Come utilizzare la EEPROM interna di Arduino
Tutte le board Arduino sono dotate di una EEPROM, ossia una porzione di memoria che non si cancella quando spegnamo la nostra scheda.
Leggendo le caratteristiche della nostra scheda Arduino potremo verificare quanta memoria possiamo utilizzare per memorizzare i dati da conservare.
Sul sito ufficiale Arduino per ogni modello di board si può trovare una sezione dedicata alla memoria, in cui è possibile individuare:
The ATmega328 has 32 KB (with 0.5 KB used for the bootloader).
It also has 2 KB of SRAM and 1 KB of EEPROM (which can be read and written
with the EEPROM library).
La frase riportata si riferisce al modello Arduino Uno Rev.3, il significato è che l’ATmega328, di cui è dotata la versione Uno di Arduino, ha:
- 32KB (di cui 0,5 KB destinati a contenere il bootloader, il sistema base che rende Arduino utilizzabile e le permette di ricevere ed eseguire i tuoi sketch);
- 2 KB di SRAM;
- 1KB di EEPROM ossia 1024 celle in cui è possibile memorizzare e ritrovare i nostri dati, anche dopo un’ interruzione di corrente.
Alcune schede Arduino dispongono solamente di 512KB (ad esempio quelle equipaggiate con l’ATmega 168), ed altre, invece, come la Mega ( dotata di microcontroller ATmega 1280 o 2560) ne possiedono 4KB.
Tuttavia se non fossero sufficenti si può optare per una EEPROM esterna, gestendola dalla nostra scheda Arduino oppure è possibile utilizzare una SD shield con 2GB di archiviazione e scrivere i nostri valori in semplici file, da far ri-leggere ad ogni boot.
All’interno di ciascuna cella è possibile memorizzare un valore che va da 0 a 255, è un dato di tipo integer ossia un numero intero.
Per utilizzare questa memoria è a nostra disposizione una libreria: EEPROM.h già presente nell’IDE Arduino e che puoi richiamarla facilmente con la linea: #include <EEPROM.h>.
La libreria EEPROM.h mette a disposizione tre metodi (funzioni), ed è quindi semplicissima da utilizzare:
read(address): con questa funzione è possibile leggere un valore memorizzato nella cella indicata come address;
write(address,value): con questa funzione è possibile scrivere in una delle 512,1024,4069 celle (address) il valore (value) da memorizzare.
update(address,value): con quest’ultima funzione, invece, è possibile scrivere in una delle 512,1024,4069 celle (address) il valore (value) da memorizzare, ma questo verrà scritto solo se il nuovo valore è differente rispetto al valore attualmente memorizzato in quella specifica cella di memoria.
Qui di seguito riporto uno sketch di esempio che non farà altro che stampare sul monitor seriale ciò che viene trovato all’interno di ciascuna cella della nostra EEPROM
#include <EEPROM.h> int value; void setup() { Serial.begin(115200); } void loop() { for (int indice_cella=0; indice_cella < 512; indice_cella++) { value = EEPROM.read(indice_cella); Serial.print(indice_cella); Serial.print("\t"); Serial.print(value); Serial.println(); delay(500); } }
Leggendo lo sketch:
alla righa numero 1 includi la libreria EEPROM.h con il comando #include;
alla riga numero 2 imposta una variabile value che memorizzerà i valori letti dalla EEPROM;
Nella funzione setup() inizializza la comunicazione seriale a 115200 baud, utilizzeremo la comunicazione seriale per far scrivere sul monitor seriale i valori letti, è utile soprattutto la prima volta per verificare i valori che memorizzi in una data cella;
Nella funzione loop() ho utilizzato un ciclo for per scorrere le varie celle della EEPROM partendo dalla cella con numero 0 fino alla cella 511 compresa. All’interno di questo ciclo for la nostra scheda Arduino andrà a leggere cella per cella e a stamparne il relativo valore sul nostro monitor seriale.
Nell’ultima riga del ciclo for ho definito un tempo di attesa di 500 millisecondi tra una lettura e la successiva.
Eseguendo lo sketch sulla mia Arduino Uno la EEPROM riporta:
Leggere dalla EEPROM è solo l’inizio, se vuoi utilizzarla in un tuo progetto dovrai scriverci prima il valore che vuoi ritrovarci, ecco lo sketch ufficiale consigliato sul sito Arduino:
#include <EEPROM.h> void setup() { for (int i = 0; i < 512; i++) EEPROM.write(i, i); } void loop(){}
In questo caso gli autori non hanno voluto utilizzare la funzione loop per scrivere nella EEPROM, ma hanno utilizzato un ciclo for da 0 a 512 in cui per ogni cella hanno scritto il numero della cella stessa.
Apportando una piccola modifica a questo sketch possiamo scrivere e legger nello stesso sketch i valori della nostra EEPROM
#include <EEPROM.h> int value; void setup() { Serial.begin(9600); for (int i = 0; i < 512; i++) EEPROM.write(i, i); } void loop() { for (int indice_cella=0; indice_cella < 512; indice_cella++) { value = EEPROM.read(indice_cella); Serial.print(indice_cella); Serial.print("\t"); Serial.print(value); Serial.println(); delay(500); } }
Avrai notato un piccolo errore, anche nello sketch originale, i valori memorizzabili in ciascuna cella vanno da 0 a 255 mentre con il ciclo for si tenta di scrivere valori superiori per le celle da 256 a 511, ovviamente il risultato sarà che in queste celle il valore sarà 255, il massimo valore possibile.
Ecco il risultato dello sketch eseguito sulla mia arduino:
Avvertenze:
1.Per poter scrivere in ogni cella occorrono 3.3 millisecondi per cui teniamone conto quando andremmo a memorizzare i nostri dati nella EEPROM;
2. le EEPROM possono essere scritte per un massimo di 100.000 volte, per scrittura si intende ogni volta che cambi il valore in una cella, considerando che solitamente utilizzi la EEPROM solo per memorizzare dei dati di configurazione, questo valore è decisamente elevato;
Buon divertimento!