Arduino I2C EEPROM paměť AT24C256

EEPROM paměť AT24C256 je Arduino modul, který umožňuje ukládat různé údaje z Arduina na externí paměť. Tento druh paměti je elektricky mazatelná a programovatelná paměť a pro komunikaci využívá protokol I2C. Díky tomu můžeme do EEPROM zapsat libovolné údaje, které ale zůstanou uložené i po odpojení napájení. EEPROM AT24C256 má kapacitu 256 kbit neboli 32 kbyte, díky které můžeme uložit až 32 768 bajtů (bajt = byte = znak z ASCII, 8 bitů). Pro napájení tohoto modulu lze použít stejnosměrné napětí v rozmezí 2,7 až 5,5 Voltů. Proudový odběr v klidu se pohybuje okolo 18 mikroAmpér, při čtení se můžeme dostat na hodnotu 1 miliAmpér a při zápise na 3 miliAmpéry. U této paměti AT24C256 si také můžeme pomocí propojek na modulu nastavit adresu pomocí pinů A0-A2 a také zablokovat zápis do paměti pomocí propojky WP.

Pro úspěšné propojení EEPROM paměti AT24C256 s Arduinem stačí zapojit celkem čtyři vodiče. Propojíme VCC s 5 V Arduina, SCL s pinem A5, SDA s pinem A4 a GND se zemí Arduina. Vzhledem k tomu, že komunikace mezi Arduinem a EEPROM probíhá po sběrnici I2C, tak je nutné využít pro datové piny SCL a SDA odpovídající I2C piny na Arduinu.

Ukázkový kód obsahuje na svém začátku připojení knihovny Wire pro práci se sběrnicí I2C, po kterém následuje definování adresy EEPROM paměti. Jak již bylo zmíněno, můžeme tuto adresu měnit pomocí tří adresných propojek, kdy tyto propojky odpovídají posledním třem bitům (viz komentář v programu). Po adrese následuje vytvoření proměnné, která slouží pro práci s ukládanými zprávami, kdy je doporučeno vytvářet najednou maximálně zprávy o 30 znacích kvůli omezení knihovny Wire. V podprogramu setup jako první zahájíme komunikaci po sériové lince spolu s komunikací po sběrnici I2C. Následně zapíšeme do EEPROM znak vykřičníku na maximální adresu 32 767 (adresy začínají od nuly). Po krátké pauze ze zmíněné adresy zkusíme zpětně vyčíst zapsaný bajt a následně ho vypsat po sériové lince ve tvaru znaku, abychom si ověřili úspěšný zápis. V dalším kroku si vytvoříme ukázkovou zprávu a pomocí dané funkce ji zapíšeme od adresy 100. A jako v předchozím případě využijeme opět načtení uložené informace z paměti od adresy 100 a po úspěšném načtení si zprávu vytiskneme po sériové lince. V nekonečné smyčce loop si nejprve načteme do vytvořené proměnné aktuální čas od zapnutí od Arduina s převedením na vteřiny. Následně si vytvoříme proměnnou typu String pro uložení celé zprávy a postupně do ní zapíšeme text a přidáme obsah proměnné cas. Po dokončení zprávy si ji převedeme pomocí funkce toCharArray na pole znaků a toto pole zapíšeme do EEPROM od adresy 0. Po úspěšném zápisu si vyzkoušíme načtení zprávy pomocí načítání jednotlivých bajtů. Pro tento postup si tedy vytvoříme proměnnou pro počítadlo čtených adres a načteme první znak z paměti. Poté provedeme kontrolu, jestli znak není rovný nule, která označuje prázdné místo v paměti. V případě existujících dat vytiskneme načtený znak po sériové lince a pokračujeme zvýšením ukazatele na adresu společně s načtením dalšího znaku. V této while smyčce zůstáváme do té doby, dokud nenačteme zmíněný prázdný znak, přičemž v tomto okamžiku přesuneme tisknutí po sériové lince na nový řádek a po pauze dvou vteřin opakujeme smyčku loop. V programu se dále nachází ještě pomocné podprogramy, které slouží pro práci s EEPROM. Je zde podprogram pro zápis jednoho znaku či celé zprávy a také pro čtení jednoho znaku či celé zprávy.

// Arduino I2C EEPROM AT24C256

// připojení potřebné knihovny
#include <Wire.h>
// definování adresy EEPROM paměti,
// adresa má tvar 1010-A2-A1-A0
#define eeprom B1010000
// vytvoření proměnné pro uložení zprávy do pole znaků
char zpravaChar[30];

void setup() {
  // zahájení komunikace po sériové lince rychlostí 9600 baud
  Serial.begin(9600);
  // zahájení komunikace po sběrnici I2C
  Wire.begin();
  // zápsání jednoho znaku na zařízení eeprom, na adresu 32767 (maximum)
  eeprom_zapis_znak(eeprom, 32767, '!');
  // krátká pauza po zápise
  delay(10);
  // vytvoření proměnné typu znak a načtení jednoho znaku
  // na zařízení eeprom, od adresy 0
  byte znak = eeprom_precti_znak(eeprom, 32767);
  // vytištění obsahu proměnné s posledním načteným znakem
  Serial.print("Nacteni jednoho znaku z EEPROM: ");
  Serial.println((char)znak);
  // vytvoření ukázkové zprávy
  char zprava[30] = "Arduino navody";
  // zapsání vytvořené zprávy na zařízení eeprom, od adresy 100,
  // data z proměnné "zprava" o velikosti proměnné "zprava"
  eeprom_zapis_zpravu(eeprom, 100, (byte *)zprava, sizeof(zprava));
  // krátká pauza po zápise
  delay(10);
  // čtení z vyšší adresy
  Serial.print("Cteni od adresy 100: ");
  // načtení zprávy ze zařízení eeprom, od adresy 100,
  // data uložíme do proměnné "zpravaChar" o velikosti proměnné "zpravaChar"
  eeprom_precti_zpravu(eeprom, 100, zpravaChar, sizeof(zpravaChar));
  // vytištění celé zprávy po sériové lince
  Serial.print(zpravaChar);
  Serial.println(" ");
}

void loop() {
  // vytvoření proměnné s načtením času od zapnutí Arduina
  long cas = millis()/1000;
  // vytvoření zprávy v proměnné String
  String zpravaString = "Cas: ";
  zpravaString += cas;
  // převod zprávy z proměnné String na pole znaků
  zpravaString.toCharArray(zpravaChar, sizeof(zpravaChar));
  // zapsání vytvořené zprávy na zařízení eeprom, od adresy 100,
  // data z proměnné "zprava" o velikosti proměnné "zprava"
  eeprom_zapis_zpravu(eeprom, 0, (byte *)zpravaChar, sizeof(zpravaChar));
  // krátká pauza po zápise
  delay(10);
  // vytvoření proměnné pro práci s čtecí adresou
  int addr = 0;
  // vytvoření proměnné typu znak a načtení jednoho znaku
  // na zařízení eeprom, od adresy 0
  byte znak = eeprom_precti_znak(eeprom, 0);
  // dokud nenarazíme na načtení nulového znaku,
  // budeme v této while smyčce
  while (znak != 0) {
    // vytištění obsahu proměnné s posledním načteným znakem
    Serial.print((char)znak);
    // inkrementace adresy pro načtení dalšího znaku
    addr++;
    // načtení jednoho znaku na zařízení eeprom, od adresy, která je v proměnné addr
    znak = eeprom_precti_znak(eeprom, addr);
  }
  // pokračování výpisu na novém řádku
  Serial.println();
  // pauza po dobu 2 vteřin
  delay(2000);
}
// podprogram pro zapsání jednoho znaku
void eeprom_zapis_znak( int adresaZarizeni, unsigned int adresaCteni, byte data ) {
  int rdata = data;
  Wire.beginTransmission(adresaZarizeni);
  Wire.write((int)(adresaCteni >> 8)); // MSB
  Wire.write((int)(adresaCteni & 0xFF)); // LSB
  Wire.write(rdata);
  Wire.endTransmission();
}
// podprogram pro zapsání zprávy o velikosti max. 30 znaků
void eeprom_zapis_zpravu( int adresaZarizeni, unsigned int adresaCteniZpravy, byte* data, byte delkaDat ) {
  Wire.beginTransmission(adresaZarizeni);
  Wire.write((int)(adresaCteniZpravy >> 8)); // MSB
  Wire.write((int)(adresaCteniZpravy & 0xFF)); // LSB
  byte c;
  for ( c = 0; c < delkaDat; c++)
    Wire.write(data[c]);
  Wire.endTransmission();
}
// podprogram pro přečtení jednoho znaku
byte eeprom_precti_znak( int adresaZarizeni, unsigned int adresaCteni ) {
  byte rdata = 0xFF;
  Wire.beginTransmission(adresaZarizeni);
  Wire.write((int)(adresaCteni >> 8)); // MSB
  Wire.write((int)(adresaCteni & 0xFF)); // LSB
  Wire.endTransmission();
  Wire.requestFrom(adresaZarizeni,1);
  if (Wire.available()) rdata = Wire.read();
  return rdata;
}

// podprogram pro přečtení zprávy o velikosti max. 30 znaků
void eeprom_precti_zpravu( int adresaZarizeni, unsigned int adresaCteni, byte *buffer, int delkaDat ) {
  Wire.beginTransmission(adresaZarizeni);
  Wire.write((int)(adresaCteni >> 8)); // MSB
  Wire.write((int)(adresaCteni & 0xFF)); // LSB
  Wire.endTransmission();
  Wire.requestFrom(adresaZarizeni,delkaDat);
  int c = 0;
  for ( c = 0; c < delkaDat; c++ )
    if (Wire.available()) buffer[c] = Wire.read();
}

Po nahrání ukázkového kódu do Arduino desky s EEPROM pamětí AT24C256 dostaneme například tento výsledek:

Nacteni jednoho znaku z EEPROM: !
Cteni od adresy 100: Arduino navody 
Cas: 0
Cas: 2
Cas: 4
Cas: 6
Cas: 8
Cas: 10

EEPROM paměť AT24C256 nám umožňuje přidat externí uložiště pro Arduino s kapacitou zápisu 32 768 bajtů neboli znaků. Můžeme ji tedy použít například pro uložení různých konfigurací či jako zálohu ukládaných dat v případě výpadku bezdrátového spojení s hlavním systémem. Velkou výhodou je také možnost nastavit adresu pomocí tří adresních propojek a tím připojit až 8 pamětí na jedno Arduino anebo také možnost po zápisu potřebných dat zablokovat další zápis dat.

Seznam použitých komponent:

http://dratek.cz/arduino/1511-original-arduino-uno-rev3-1485165418.html

http://dratek.cz/arduino/1359-i2c-eeprom-at24c256-pro-ukladani-dat-pro-arduino-pic-1467272598.html

Další podobné články