Fino ad ora abbiamo realizzato programmi che lavorano esclusivamente in memoria volatile SRAM, che non trattiene i dati in mancanza di alimentazione, ma non tutti sanno che Arduino dispone anche di una memoria non volatile: la EEPROM

L’acronimo EEPROM sta per Electrically Erasable Programmable Read-Only Memory (in pratica uno scioglilingua) ed indica un tipo di memoria non volatile integrata proprio nel processore ATmega: al contrario di quanto accade per le SRAM, se, per caso o per volontà, si dovesse staccare l’alimentazione del nostro Arduino, i dati salvati in EEPROM non andrebbero persi. Avrete capito che questa nuova memoria può salvarci la vita in moltissime occasioni: se ad esempio abbiamo intenzione di lasciare Arduino in un determinato luogo a svolgere delle operazioni per molto tempo, allora potremmo programmarlo per fargli salvare in EEPROM i dati sensibili da recuperare poi all’accensione. Adesso però vi chiederete per quale motivo non abbiamo mai lavorato su questa memoria. Ebbene i motivi sono principalmente due:

  • La EEPROM ha una capacità di storage estremamente limitata. Ecco una piccola tabella che illustra lo spazio dedicato per ogni processore.

""""

  • Ha un ciclo di vita piuttosto breve: può essere sottoposta fino ad un massimo di 100.000 cicli di scrittura! Per questo motivo bisogna stare molto attenti nell’uso di questa memoria, se non si vuole bruciarla in poco tempo: sarebbe opportuno ridurre al minimo il numero di scritture e soprattutto evitare quelle inutili, come nel caso in cui ad esempio si vada a sovrascrivere valori già presenti in memoria.

 

Per utilizzare la EEPROM è necessario includere la libreria nativa 
<EEPROM.h> che dispone di varie funzioni, ma noi vedremo quelle principali: 

  • EEPROM.read(indirizzo) → Questa funzione legge un dato della EEPROM ad un determinato indirizzo. Tale memoria si compone di 1024 celle di 1 byte (8 bit) ciascuna, quindi la funzione richiede come parametro la cella su cui si vuole effettuare la lettura: si parte dal byte 0 e si arriva a 1023. Ad esempio l’istruzione EEPROM.read(0) andrà a leggere il contenuto della cella numero 0.

 

  • EEPROM.write(indirizzo, valore) → Questa funzione scrive un determinato valore ad un determinato indirizzo. Richiede due parametri: il numero della cella e il valore da scrivere.

 

  • EEPROM.update(indirizzo, valore) → Questa funzione svolge lo stesso compito di quella precedente, ma funziona in modo più intelligente, infatti scrive il valore all’indirizzo indicato solo se questo è diverso dal valore già presente nella stessa cella. Ad esempio il seguente programma scrive il valore 12 nella cella 3 solo una volta nonostante si abbia un ciclo for:
     

Considerando che ogni operazione di scrittura avviene in circa 3.3 ms, vi rendete conto che questa funzione è indispensabile se si vuole preservare il ciclo di vita della EEPROM… 
A tal proposito notate anche che abbiamo lavorato esclusivamente nel setup() e questa è una buona pratica quando si comincia a familiarizzare con la EEPROM: se avessimo inserito questo codice nel loop(), comunque non avremmo avuto problemi perchè la funzione update() scarta le scritture inutili, ma se ad esempio avessimo usato la semplice istruzione EEPROM.write(), probabilmente avremmo bruciato la scheda Arduino in pochi minuti. Altra scelta saggia sarebbe quella di fare il backup in EEPROM di una o più variabili ad intervalli di tempo sostenuti o ancora dopo un certo numero di letture (facendone magari anche una media): questi sono solo semplici esempi per farvi capire che bisogna stare un po’ più attenti a come si programma l’uso di una EEPROM.


Un’altra funzione che ci aiuta parecchio nella gestione delle celle è EEPROM.lenght() che restituisce in output la lunghezza della EEPROM
Se ad esempio volessimo pulire tutta la memoria, quindi resettare tutte le celle, potremmo combinare un ciclo for con la suddetta funzione:

 for (int i = 0 ; i < EEPROM.length() ; i++) {
    EEPROM.write(i, 0);
 }

 


Ricapitolando, la EEPROM

  1. E’ una memoria non volatile.
  2. Ha un ciclo di 100.000 scritture, quindi bisogna fare molta attenzione a evitare scritture inutili.
  3. Ha una capacità di storage limitata e variabile a seconda del modello di Arduino.
  4. Richiede la libreria <EEPROM.h>.
  5. La funzione di lettura è EEPROM.read(indirizzo).
  6. La funzione di scrittura è EEPROM.write(indirizzo,valore), anche se conviene usare la EEPROM.update(indirizzo,valore).
  7. La funzione EEPROM.lenght() restituisce la lunghezza della memoria.