Programování | Pojďme programovat elektroniku | Arduino

Pojďme programovat elektroniku: EEPROM, micro SD, OpenLog, SPIFFS, aneb jak uložit vlastní data na čip

  • Jak trvale uložit nějaká data za běhu programu?
  • Dnes si vyzkoušíme primitivní EEPROM
  • Ale také práci s SD kartou a SPIFFS

Po delší přestávce způsobené poměrně citelným zpomalením doručování žlutých obálek z Číny je tu další díl našeho seriálu o programování elektroniky. Tentokrát se vrátíme k základům a ukážeme si některé způsoby, jak trvale ukládat vlastní data.

Doposud jsme totiž pracovali jen s těmi daty, která byla natvrdo vypálená ve flashové paměti programu. Co když ale budeme potřebovat na čip až za běhu programu uložit nějakou trvalejší proměnnou, která má přežít i odpojení od zdroje napájení – nabízí se třeba nějaká konfigurační proměnná?

EEPROM

V takovém případě nám pomůže speciální a většinou poměrně malá paměť, která bývá součástí hlavního čipu. Jmenuje se EEPROM, tedy Electrically Erasable Programmable Read-Only Memory.

To „Read-Only“ je určitý názvoslovný relikt minulosti, do EEPROM totiž samozřejmě zapisovat můžeme, ačkoliv garantovaná životnost se pohybuje okolo milionu zápisů/smazání. Pokud byste na EEPROM potřebovali zapisovat ve větší míře opravdu často (třeba každou sekundu) a báli byste se o hlavní čip, můžete použít externí EEPROM ve formě modulu nebo holého švábu ideálně s jednoduchým rozhraním I2C. Když pak tato paměť selže, vyměníte pouze ji samotnou.

K těm nejpopulárnějším a ve světě Arduina nejlépe zdokumentovaným patří řada pamětí 24C (třeba AT24C256, 24C08 aj.), které jsou k dispozici jako moduly s vlastní destičkou nebo jako zmíněné šváby v konstrukci DIP, jenž snadno zacvaknete do nepájivého pole. Na eBayi obě podoby seženete doslova za pár korun a v českých e-shopech jsou ceny podobné.

4fe581f4-4407-4c27-b8f6-004c7387d143a858bdd7-78ff-4dd0-b666-f4a74ebab50ffea3e940-ce6c-42c1-bc91-433ae9317f3b
Externí EEPROM ve formě modulu a holý šváb 24C08WP s 1kB pamětí

Číslo na konci zpravidla udává velikost paměti v kilobitech (přesněji v kibibitech: 1 kb = 1 024 b), jednoduchý šváb C2408WP tedy pojme 8 kb (8 192 b), což odpovídá 1 kB (1 024 B). A právě tento drobný čip jsem našel ve své pokladnici součástek. Jak s ním komunikovat? Buď přímo skrze univerzální knihovnu Wire, která se v Arduinu stará o komunikaci na sběrnici I2C, anebo o něco komfortněji pomocí některé z dostupných specializovaných knihoven. Poslouží třeba EEPROM24C04_16 z GitHubu.

Zapojení maličkého švábu C2408 třeba na nepájivém poli je poměrně jednoduché. Pro základní experimentování stačí spojit s 5V Arduinem komunikaci (SDA a SCL), napájení (5V, GND) a pin WP (Write Protect). Když na něm nastavíte logickou 1, paměť bude pouze ke čtení. A když nastavíte logickou 0, paměť povolí zápis. Pin jsem připojil k zemi (trvalá logická 0). Další piny mohu ignorovat a čip bude dostupný na I2C adrese 0x50.

76f6d867-2225-4e53-9630-67dad70719e8642b0620-00db-4e07-bc5e-1b7a09f2b2f4
Nejjednodušší připojení skrze I2C. Čip bude dostupný na I2C adrese 0x50.

Pro trvalejší a stabilnější instalaci je doporučeno mezi napájecí pin a zem připojit ještě 100nF kondenzátor, který pohltí případné napěťové pulzy (spikes), které by mohly dělat v dalším obvodu nejrůznější neplechu.

Práce s EEPROM je ve své podstatě naprosto primitivní – zejména pokud použijeme specializovanou knihovnu. Bajt (nebo řadu bajtů) jednoduše uložíme na libovolnou adresu (pozici) v paměti a chvíli počkáme, než se vše zpracuje. Opačně si pak vždy z konkrétní adresy vyžádáme buď jeden, anebo více bajtů.

Při práci s EEPROM tedy musíme vždy vědět, na jakou adresu jsme svá data uložili. Když uložíme třeba deset bajtů na adresu 13, zaberou tato data adresy 13, 14, 15, 16, 17, 18, 19, 20, 21 a 22.

Ukázka uložení a přečtení bajtu z externí EEPROM:

Program nejprve uloží na poslední adresu 1023 bajt s hodnotou 0xAB (dekadické číslo 171). Poté skrze sériovou linku vykresli mapu celé EEPROM ve formě matice 32x32 bajtů. Náš uložený bajt by měl být až na konci.

6af45b1f-80e3-4895-b3f5-7eddea6f23bc
Výstup našeho programu s kontrolou, že se bajt skutečně uložil na poslední adresu 1kB externí paměti EEPROM

Pro zápis a čtení jsme použili již zmíněnou knihovnu EEPROM24C04_16, která vedle zápisu a čtení jednotlivých bajtů zvládne i hromadné operace s vícero bajty, což se hodí, pokud potřebujeme zapsat složitější proměnnou, strukturu apod. Převedeme si ji na pole bajtů a ty uložíme do EEPROM v jednom kroku.

// Knihovna pro praci s EEPROM C2408
// pripojenou na sbernici i2C
// https://github.com/yazug/EEPROM24C04_16
#include <Eeprom24C04_16.h>

// Objekt pro praci s „24C“ EEPROM na I2C adrese 0x50
Eeprom24C04_16 eeprom(0x50);

// Funkce pro vytisteni cele pameti
// jako matice 32x32 bajtu v sestnactkove soustave;
void vypisEEPROM() {
  for (int i = 0; i < 1024; i++) {
    uint8_t bajt = eeprom.readByte(i);
    if(bajt < 0x10) Serial.print(0);
    Serial.print(bajt, HEX);
    if ((i + 1) % 32 == 0) Serial.println("");
    else Serial.print(" ");
  }
}

// Hlavni funkce programu
void setup() {
  // Nastartovani seriove linky a EEPROM
  Serial.begin(115200);
  eeprom.initialize();

  // Uloz bajt s hodnotou 0xAB na adresu 1023
  // Bajt se tedy ulozi na posledni misto v EEPROM
  Serial.print("Ukladam bajt 0xAB na pozici 1023 ... ");
  eeprom.writeByte(1023, 0xAB);
  // Pockej 10 ms, aby EEPROM stihala
  delay(10);
  Serial.println("OK");

  // Vypis pro kontrolu 32x32 matici cele EEPROM
  // Na konci by mel byt patrny nas ulzoeny bajt 0xAB
  Serial.println("Kontrolni vypis cele EEPROM C2408:");
  vypisEEPROM();
}

// Funkci nekonecne smycky nepouzijeme,
// v prostredi Arduino je ale i tak povinna
void loop() {}

V následující kapitole se podíváme na to, jak se na deskách Arduino pracuje s vestavěnou EEPROM v jejich řídících čipech ATmega.

Témata článku: , , , , , , , , , , , , , , , , , , , , , , , , ,