Arduino: gestione memorie interne
Tutorial alla gestione delle memore EEPROM integrate nel microcontrollore ATmega328PU
I microcontrollori possiedono al loro intero una memoria EEPROM che può essere tranquillamente utilizzata e fruttata nei nostri sketch. La memoria EEPROM permette la memorizzazione di una informazione in modalità non volatile, ovvero se il microcontrollore viene resettato o disalimentato l’informazione viene mantenuta. Ogni microcontrollore ha una ben definita memoria utilizzabile: ad esempio le schede ArduinoUNO (ATmega328PU) possiedono 1 Kbyte (1024 byte) di memoria mentre le schede ArduinoMEGA2560 (ATmega2560) possiedono 4 Kbyte (4096 byte).
Le singole memorie dei microcontrollori sopra riportati sono tutte da 1 byte (ovvero 8 bit) e, a livello di gestione software, necessitano di sole due informazioni:
- indirizzo: ovvero in quale memoria si trova il dato di mio interesse
- valore: valore dell’informazione presente nella memoria.
L’informazione indirizzo verrà gestita come variabile di tipo integer, invece il valore verrà gestito come variabile unsigned char. Per la gestione di tali memorie negli sketch è necessario includere nel programma la libreria EEPROM.h presente di default nelle librerie ufficiali Arduino. I comandi utilizzati per la gestione delle memorie sono:
EEPROM.read(indirizzo); // permette di leggere il valore memorizzato in una determinata memoria EEPROM.write(indirizzo, valore); // scrive un valore in una determinata memoria EEPROM.update(indirizzo, valore); // scrive il valore in una determinata memoria solo se è diverso da quello già presente EEPROM.length(); // restituisce l'informazione della dimensione totale delle memorie
NB. Le memorie EEPROM hanno un numero massimo di scritture, quindi utilizzare in modo inappropriato tali comandi comporta la saturazione e il non corretto funzionamento delle memorie stesse.
Esempio
Si vuole realizzare un sistema basato su quattro pulsanti (ingressi digitali) e la comunicazione seriale. La funzione di ogni singolo pulsante è la seguente:
PULSANTE 1 (pin 10) = stampa sulla seriale la dimensione massima della memoria
PULSANTE 2 (pin 11) = stampa sulla seriale il valore memorizzato
PULSANTE 3 (pin 12) = incrementa il valore di +1
PULSANTE 4 (pin 13) = decrementa il valore di -1
Si andranno a sfruttare gli ingressi in modalità pull-up, come spiegato nell’articolo Arduino: input digitali, in modo da evitare l’utilizzo di quattro resistori fisici sulla breadboard. Lo schema è riportato di seguito.
#include <EEPROM.h> int pulsante1 = 10; // dimensione memoria int pulsante2 = 11; // valore memorizzato int pulsante3 = 12; // incrementa valore +1 int pulsante4 = 13; // decrementa valore -1 int indirizzo_memoria = 0; // si vuole utilizzare solo la memoria dell'indirizzo 0 unsigned char valore; // creo la variabile che contiene l'informazione valore void setup() { pinMode(pulsante1, INPUT); pinMode(pulsante2, INPUT); pinMode(pulsante3, INPUT); pinMode(pulsante4, INPUT); Serial.begin(9600); valore = EEPROM.read(indirizzo_memoria); //leggo e memorizzo in valore il contenuto della memoria } void loop() { // lettura memoria massima disponibile if (digitalRead(pulsante1) == LOW) { Serial.print("Memoria disponibile "); Serial.print(EEPROM.length()); Serial.println(" byte"); delay(500); } // stampa del valore attuale (già memorizzato di seguito) if (digitalRead(pulsante2) == LOW) { Serial.print("Il valore attuale è "); Serial.println(valore); delay(500); } // incremento il valore di +1 e salvo il dato nella memoria if (digitalRead(pulsante3) == LOW) { valore = valore + 1; EEPROM.update(indirizzo_memoria, valore); Serial.print("Dato memorizzato: "); Serial.println(valore); delay(500); } // decremento il valore di -1 e salvo il dato nella memoria if (digitalRead(pulsante4) == LOW) { valore = valore - 1; EEPROM.update(indirizzo_memoria, valore); Serial.print("Dato memorizzato: "); Serial.println(valore); delay(500); } }