Lekce 17 - Arduino a EEPROM
03.05.2013 14:21Translate to English
Někdy se může stát, že budeme potřebovat uložit nějakou hodnotu nebo proměnou a tuto uchovat i když bude naše zařízení vypnuté, nebo když u Arduina provedeme restart. Samozřejmě, že by jsme mohli tyto data uložit např. na SD kartu, ale v případě malého objemu dat např nastavení intervalu zjištění nějaké hodnoty, kterou by si uživatel mohl nastavit v menu, by připojování SD karty bylo "plácání materiálem". Tyto data si uložíme do EEPROM v našem Arduinu. Jedná se o paměť, která si pamatuje naše data i po vypnutí napájení, a je určena pro ukládání dat. ze angl. zkr. Electrically Erasable Programmable Read-Only Memory.
tabulka velikostí pamětí v jednotlyvých typech Arduina:
Typ Arduina | Procesor | Velikost EEPROM |
UNO | ATmega328 | 1kB |
MEGA | ATmega2650 | 4kB |
NANO | ATmega328(168) | 1kB (512B) |
Micro | ATmega32u8 | 1kB |
Z výše uvedené tabulky vidíte, že velikost závisí na procesoru na Arduinu. Nepsal jsem zde různé jiné typy Arduina jako Mega ADK, Esplora a BT. Stačí se podívat na typ použitého procesoru na desce a víte jak jste na tom.
Takže pro první příklad a ukázku nebudeme potřebovat nic jiného, než samotné Arduino a jedno jaký typ a USB kablík k počítači. Samotný zápis do paměti řídí knihovna EEPROM.h, kterou si pomocí "include" zapíšeme na začátek programu. Z té knuhovny potom využijeme funkci:
EEPROM.write(adresa, hodnota); např.: EEPROM.write(49, 177); - na adresu 49 zapíšeme hodnotu 177
adresa je typu integer, a hodnota byte (0-255) a nebo pro čtení
hodnota = EEPROM.read(adresa); např. hodnota = EEPROM.read(49); - z adresy 49 přečte hodnotu a zapíše do proměné "hodnota".
Upozornění:
U pamětí EEPROM se uvádí životnost 100 000 cyklů, tudíž tuto pamět využívejte z rozvahou. :-). Opravdu se nehodí, aby jsme s ní programově pracovali nepřetržitě nekolik dní, např při ukládání nějaké hoidnoty 5x za sekundu. Hodí se výborně na ukládání uživatelských dat a různých nastavení, která si uživatel může měnit např. v nějakém menu na dipleji (např. minimílní hodnota z nějakáho čidla pro sepnutí relé, pro nastavení intervalu apod.).
Tak teď si nahrajeme náš prográmek pro práci s touto pamětí:
Timto krátkým a jednoduchým programem jsme si uložili 5 různých hodnot na adresu 0 až 5. Upozorňuji že hodoty můžou být pouze byte tzn. číslo 0 až 255. Po nahrání programu do Arduina, by se nám tento měl automaticky spustit a uložit hodnoty. Zkusíme si odpojit napájení a uvidíme, zda si naše Arduinko bude čísla pamatovat.
Připravíme si druhý program, který nám naše uložené hodnoty vypíše třeba na seriový port:
Po zapnutí napájení a nahrání programu do arduina si zapneme Serial Monitor a výsledek by měl vypadat takto:
Tak to by jsme měli, ale co když budeme chtít uložit nějaké větší číslo? Máme dvě možnosti. Pokud budeme chtít třeba například uložit číslo z Analogového pinu, které může nabývat hodnot od 0 do 1023, tak ho můžeme vydělit číslem 4 a získat tak sice nepřesnější hodnotu, ale už se nám vejde do paměti, nebo druhý způsob bude využít z paměti bajty dva. A to si teď vyzkoušíme.
V ukázce nepracujeme přímo s EEPROM pouze si demonstrujeme rozdělení 2byte čísla (Integer int) na dvě čísla byte pro možný zápis do EPROM. Jedná se o číslo 28478, výsledek spojení dvou hodnot byte se poté vypíše na serial port.
Nejprve jsme si naši hodnotu z integru převedli do prvního byte. Automaticky se hodnota čisla binárně 0110111100111110 usekne na 00111110, protože se do byte více nedostane (je to proměná o velikosti 1 byte). Tak první byte máme vyřešen. A co druhý? To vyřešíme pomocí bitového posunu. (>> bitový posun doprava, << bitový posun doleva). My použijeme bitový posun doprava a to o 8 bitů.
Výsledek:
0110111100111110 - původní číslo
0011011110011111 - bitový posun o 1 bit doprava
0001101111001111 - bitový posun o 2 bity doprava
0000110111100111 - ...
0000011011110011
0000001101111001
0000000110111100
0000000011011110 - bitový posun o 7 bitů doprava
0000000001101111 - bytový posun o 8 bitů doprava
Tak to je princiop bitového posunu. Má i více využití. Teď si můžeme uložit i druhý byte našeho čísla. Při načítání čísla s EEPROM je postup jen opačný, jak můžete v programu vidět.
Aby byl postup lépe využitelný vytvořil jsem kód, kde je již zápis celého Integeru (2 byte čísla) a jeho následné vyvolání, je implementováno do dvou funkcí.
Zde už musíme dát pozor. V kódu je nastavena hodnota adresy čísla 10, ale využitý prostor pro číslo je na adresách 10 a 11. Takže nemůžeme ukládat zase něco na adresu 11, ale využijeme až další prostor v paměti. Dají se ukládat samozřejmě i daleko větší čísla, postup bude podobný avšak zabere více bytů v paměti.
TIP - Jak uložíme číslo s desetinou čárkou?
Pro příklad máme číslo 14,742. Do paměti umíme ukládat pouze hodnoty velikosti 1 bytu, ale umíme uložit integer. Takže si číslo vynásobíme např. číslem 1000 (dostaneme pak přesnost na 3 desetiná místa, když vynásobíme číslem 100 tak 2 desetiná místa - počet nul = počet desetiných míst) Číslo 14742 uložit umíme, když ho poté přečteme z paměti číslo vydělíme opět číslem 1000. Nesmíme zapomenout, že číslo Integer může být od -32768 do 32767.
Na závěr si ukážeme jak si můžeme uložit také text pro nějaký účel. Pokud víme, že každý znak v textu reprezentuje nějaká číselná hodnota, uložení nebude složité. Zde je program:
Vidíte, že jsme si pro práci s textem a EEPROM vytvořil dvě funkce. Jedna z nich text ukládá a druhá ho zase čte. Tady si musíme uvědomit, že ve funkci si také nastavujeme počet rezervovaných znaků v paměti.
TextToEEPROM(50,10,"Ahoj..."); --> Znamená, že uloží na adresu 50 text o maximální délce 10 znaků. Uložený text je "Ahoj...". V případě, jako v tomto, že je text kratší zbytek v paměti do zbývajích znaků (celkem 10 - 7) vyplní mezerami a to proto, aby smazal zbytem naší paměti pro tento text. Delší text by měla funkce automaticky zkrátit.
TextFromEEPROM(50,10) --> Načte String (text) z adresy 50 o délce max 10 znaků. Když je text kratší, automaticky smaže mezery na konci.
Příklad jsem moc nekomentoval v kódu, ale snad je vše jasné. Stačí si celé funkce z kódu zkopírovat a použít ve Vašem programu. Ukázka pouze uloží nějaké dva texty do EEPROM a potom znovu z paměti načte a vypíše na seriový port.
———
ZpětDiskusní téma: Lekce 17 - Arduino a EEPROM
Datum | 07.09.2015 |
---|---|
Vložil | R.V. |
Titulek | ee |
A k té chybě dochází při manipulaci s EEPROM nebo i bez manipulace?
———
Datum | 17.12.2014 |
---|---|
Vložil | LuBoss |
Titulek | EEPROM a praxe |
Rád bych se zeptal, jakou máte zkušenost s použitím interní EEPROM v praxi? Můj problém konkrétně u procesoru ATmega8 je, že pokud vlivem rušení, poklesu napájecího napětí, nebo aktivaci watchdogu dojde k resetu mikroprocesoru, tak velice často dojde i k přepsání interní EEPROM náhodnými daty. Detekci poklesu napětí mám nastavenou na 4V a vyzkoušeli jsme i napájení z autobaterie, ale i tak dochází k náhodnému přepsání dat v EEPROM :-(
Řešil někdo z vás podobné problémy v praxi?