V predchádzajúcom článku som vysvetlil, ako rozdeliť pamäť na rovnaké časti, tzv. bloky. Dospel som k záveru, že na plné využitie pamäte by som ju mohol rozdeliť na 256 blokov po 16 bajtov, prípadne aj 128 blokov po 32 bajtov. Plných 32 bajtov sa zdá byť priveľa a pravdepodobne by viedlo k plytvaniu cenným priestorom.

Taktiež mnohé I2C (Wire) knižnice majú pevný limit 30 bajtov na jeden zápis. Momentálne používam knižnicu makuna Rtc a to je v nej uvedené v komentári v zdrojovom kóde. To znamená, že nie je možné zapísať celých 32 bajtov naraz. Je však možné rozdeliť to na dva zápisy bez problémov. Nie je to technické obmedzenie, len pribúda kód. Z toho dôvodu sa pokúsim vojsť do 16 bajtov, čo je stále dosť.

S 16 bajtmi na blok môžem uložiť aspoň 256 záznamov, čo predstavuje 256 záznamov každých 24 hodín alebo 128 záznamov dvakrát denne. Počiatočný formát ukladaných dát, na ktorý som prišiel, vyzerá takto:

1620967937+12345

Dáta majú nasledovnú podobu:

[unix epoch][prepínací oddeľovač][hmotnosť v dekagramoch]

Tento formát sa zmestí do 16 bajtov. Prepínací oddeľovač mení svoje znamienko vždy, keď sa záznam prepíše. Je to nevyhnutné, inak by sme nevedeli, ktoré dáta sú najnovšie v kruhovej vyrovnávacej pamäti. O tejto téme som diskutoval pred pár dňami. V skutočnosti by dáta (skrátené len na 6 blokov po 16 bajtov pre ilustráciu) mohli vyzerať takto:

1620967977+10080
1620967987+10090 // najnovší záznam
1620967937-10040 // najstarší záznam
1620967947-10050
1620967957-10060
1620967967-10070

Dáta ukazujú, že záznamy vznikajú každých 10 sekúnd a hmotnosť postupne rastie o 10 dekagramov (100 gramov). Toto by fungovalo bez väčších problémov, ale dalo by sa to urobiť lepšie?

Možné optimalizácie #

  1. Knižnica používa nejaký zvláštny epochový čas, začínajúci od 1. januára 2000. To ušetrí jeden bajt, pretože takýto epochový čas je momentálne okolo 674252045. Knižnica poskytuje nástroje na manipuláciu s týmto epochom, takže s tým pre teraz ostanem.
  2. Keďže už ukladám epochový čas, mohol by som nájsť hranicu medzi najstarším a najnovším záznamom porovnaním týchto časov – čím by odpadol prepínací oddeľovač. Žiadny oddeľovač by ani nebol potrebný, keďže všetky dáta majú pevnú dĺžku a dajú sa oddeliť jednoducho posunom.
  3. Ak sa dáta ukladajú v pevných časových intervaloch, epochový čas by nebol potrebný vôbec, keďže sa dá spätne vypočítať. Stačil by len prepínací oddeľovač a hmotnosť, keďže je potrebný aspoň jeden spôsob, ako určiť, kde sa momentálne nachádza hlava kruhovej vyrovnávacej pamäte.
  4. Čo je najdôležitejšie, keďže sa snažím ukladať len celé čísla, zaberú oveľa menej miesta ako pri ukladaní po jednotlivých znakoch. Napríklad epochový čas sa zmestí do 30 bitov a dokonca celý Unix epochový čas momentálne zaberá 31 bitov, čo sú len 4 bajty – oproti 9 alebo 10 bajtom pri ukladaní ako znaky! Podobne hmotnosť by sa dala uložiť len do dvoch bajtov (maximum 65535 dekagramov, čo je trikrát viac ako dosahovaný rozsah), čím by som dosiahol požadovanú veľkosť bloku len 4 + 2 bajty a úctyhodných 682 záznamov!

Ďalšie kroky #

S 682 možnými záznamami by som sa mohol rozhodnúť buď zaznamenávať záznamy častejšie, čím by sa znížil dopad občasných chýb merania, alebo ukladať aj ďalšie dáta, napríklad teplotu. DS3132 má vnútorný teplomer na kalibráciu frekvencie oscilátora a jeho hodnota je dostupná na čítanie. Čo viac, môže byť dokonca veľmi presný, až do 0,002 °C. Celkom zaujímavé pre úľ, keďže tento projekt meria hmotnosť potenciálneho medu na diaľku.

Knižnica však predvolene umožňuje ukladať pole znakov alebo C reťazce, nie celé čísla na zadanom offsete. Budem musieť zistiť, ako pohodlne pracovať s celými číslami v tejto knižnici, ak chcem zostať lenivy – ale nemal by to byť problém.

Toto je 65. príspevok v rámci #100daystooffload.