Tutorial: usare la EEPROM di arduino

Tutte le schede Arduino sono dotate di una EEPROM, ossia una parte di memoria che non si cancella con la mancanza di alimentazione.

eeprom arduino uno

Leggendo le caratteristiche della tua scheda Arduino potrai verificare quanta memoria puoi utilizzare per memorizzare i dati da conservare.

Sul sito ufficiale arduino per ogni modello trovi una sezione dedicata alla memoria, solitamente “Memory” in cui puoi leggere qualcosa di simile:

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, se non hai familiarità con l’inglese, il significato è che l’ATmega328, di cui è dotata la versione Uno di Arduino, ha:

  • 32KB (Kilo Byte) di cui 0,5 KB (512) 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 spazi o celle (gli addetti ai lavori mi concedano il termine) in cui puoi memorizzare e ritrovare i tuoi dati, anche dopo l’interruzione di corrente.

Alcune schede Arduino ne hanno solo 512KB (ad esempio quelle equipaggiate con l’ATmega 168), ed altre come la Mega ( equipaggiata con il miscrocontrollore ATmega 1280 o 256o) ne possiedono 4KB (4096 Byte).

Tuttavia se non ti fossero sufficenti per il tuo progetto puoi optare per un chip EEPROM esterno, pilotandolo da arduino oppure puoi utilizzare una SD shield con 2GB di memoria dati e scrivere i tuoi valori in file, rileggendo ad ogni boot i file momeorizzati.

In ciascuna cella puoi memorizzare un valore che va da 0 a 255, è un dato di tipo integer ossia un numero intero.

Per utilizzare questa memoria è a tua disposizione una libreria: EEPROM.h già presente nell’IDE Arduino e che puoi richiamarla facilmente con la linea: #include <EEPROM.h>.

La EEPROM.h ti mette a disposizione due metodi, è quindi semplicissima da utilizzare:

read( address ): con questo metodo puoi leggere il valore memorizzato nella cella indicata come address;

write( address,value ): con questo metodo puoi scrivere in una delle 512,1024,4069 celle ( address ) il valore ( value ) da memorizzare.

Semplice no ?

Ed ecco un primo sketch che ti permette di leggere da ciascuna delle celle il valore che in questo momento è impostato:

#include <EEPROM.h>

int a = 0;
int value;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  value = EEPROM.read(a);

  Serial.print(a);
  Serial.print("\t");
  Serial.print(value);
  Serial.println();

  a = a + 1;

  if (a == 1024)
    a = 0;

  delay(500);
}

Lo sketch è quello presentato sul sito ufficiale, avrei potuto scriverne uno io ma avrebbe fatto le stesse cose, mi sono limitato a citare quello ufficiale e modificare solo il valore delle celle da controllare, da 512 a 1024 per utilizzare tutte le celle della mia arduino.

Leggendo lo sketch:

linea 01: includi la libreria EEPROM.h con il comando #include;

linee 03-04: imposta due variabili a e value la prima utile come indice per scorrere le celle, la seconda memorizzerà i valori letti dalla EEPROM;

Nella funzione setup() inizializza la comunicazione seriale a 9600 baud, utilizzerai la comunicazione seriale per farti scrivere sul monitor seriale i valori letti, è utile soprattutto la prima volta per verificare i valori che memorizzi in una data cella;

Alla linea 13 leggi il valore della cella passata come parametro alla funzione read, nello sketch è a che alla linea 03 hai definito e impostato a 0;
linee 15-18: scrivi sul monitor seriale i valori letti, la colonna di sinistra mostra il valore dell’indice della cella, la colonna di sinistra il valore letto;
linea 20: incremente il valore di a di un punto, al prossimo ciclo loop() la linea 13 a varrà 1, al giro successivo 2, ecc… permettendoti di leggere tutte le celle della tua EEPROM;
linee 22-23: definiscono un limite di cella, per evitare errori dello sketch cercando di leggere valori di cella superiori a quelle disponibili, nell’esempio originale è impostato a 512, io ho fatto una piccola correzione per consentirti la lettura di tutte e 1024 le celle;
ricorda: se possiedi una Arduino Mega potrai impostare questo valore a 4096, inoltre le celle sono 1024 ma si parte da 0 per cui il valore di a va da 0 a 1023;
linea 25: definisce un tempo di attesa di 500 millisecondi tra una lettura e la successiva.
Eseguendo lo sketch sulla mia Arduino Uno la EEPROM riporta:
serial monitor eeprom read
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 < 1024; 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 ( da me modidicato in un range da 0 a 1024 ) in cui per ogni cella hanno scritto il numero della cella stessa.
Apportando una ulteriore piccola modifica a questo sketch puoi scrivere e leggere nello stesso sketch i valori della tua EEPROM:
#include <EEPROM.h>

int a = 0;
int value;

void setup()
{
  Serial.begin(9600);
  for (int i = 0; i < 1024; i++)
    EEPROM.write(i, i);
}

void loop()
{
  value = EEPROM.read(a);

  Serial.print(a);
  Serial.print("\t");
  Serial.print(value);
  Serial.println();

  a = a + 1;

  if (a == 1024)
    a = 0;

  delay(500);
}
Ti racconto come è fatto solo quest’ultimo in quanto è la fusione del primo e del secondo sketch proposto:
linea 01: non è cambiata, includi sempre la libreria EEPROM.h;
linee 03-04: non sono cambiate;
linea 08: non è cambiata, inizializza la comunicazione con il monitor seriale, che utilizzerai per leggere i valori memorizzate nelle celle;
linee 09-10: imposta un ciclo da 0 a 1024 all’interno del quale utilizzando il metodo write per ogni cella memorizza un valore pari al numero della cella stessa, vedrai nella fase di lettura cosa intendo;
linee 13-28: sono invariate, servono a leggere i valori memorizzati nelle celle da 0 a 1023.
Avrai notato un piccolo errore, anche nell sketch originale, i valori memorizzabili in ciascuna cella vanno da 0 a 255 mentre con il ciclo for alla linea 09 si tenta di scrivere valori superiori per le celle da 256 a 1023, 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:
serial monitor eeprom write e read
Alcune avvertenze:
1. per poter scrivere in ogni cella occorrono 3,3 millisecondi, per cui tienine conto quando memorizzerai i tuoi 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;
Prima di lasciarti ai tuoi esperimenti ti lascio un quesito da approfondire:
Come puoi memorizzare un valore superiore a 255? ad esempio se hai da memorizzare il valore rilevato da un potenziometro attraverso un ingresso analogico?
Esistono molti metodi tuttavia ti invito a cercare il tuo e suggerirlo a tutti noi, ovviamente utilizzando il minor numero di celle possibili.
Buon divertimento.
  • Questo sito ed i suoi contenuti è fornito "così com'è" e Mauro Alfieri non rilascia alcuna dichiarazione o garanzia di alcun tipo, esplicita o implicita, riguardo alla completezza, accuratezza, affidabilità, idoneità o disponibilità del sito o delle informazioni, prodotti, servizi o grafiche correlate contenute sul sito per qualsiasi scopo.
  • Ti chiedo di leggere e rispettare il regolamento del sito prima di utilizzarlo
  • Ti chiedo di leggere i Termini e Condizioni d'uso del sito prima di utilizzarlo
  • In qualità di Affiliato Amazon io ricevo un guadagno dagli acquisti idonei qualora siano presenti link al suddetto sito.

Permalink link a questo articolo: https://www.mauroalfieri.it/elettronica/tutorial-usare-la-eeprom-di-arduino.html

84 commenti

2 ping

Vai al modulo dei commenti

    • Lorenzo il 6 Giugno 2012 alle 18:56
    • Rispondi

    Ah un altra cosa… perché non crei dei pdf per queste guide, per poi distribuirli come delle “raccolte”?

    1. Secondo suggerimento ottimo.
      Non ci avevo ancora pensato, il Blog è nato per condividere on-line le mie esperienze, magari cerco un editore disposto a pubblicare i miei tutorial.

      Grazie
      Mauro

    • Angelo il 26 Febbraio 2013 alle 18:19
    • Rispondi

    ciao, articolo molto interessante e preciso, lasci anche spunti non da poco, la soluzione all’ultima domanda?
    usare la funzione map(), e convertire un qualsiasi intervallo a 0,255 e riconvertirlo all’occorrenza?

    1. Ciao Angelo,
      può essere una soluzione, certo ti perdi 1/4 di precisione …
      Ci sono altri metodi che permettono di non perdere definizione del dato.

      Lascio la sfida volutamente aperta.

      Mauro

    • Paolo il 24 Marzo 2013 alle 16:55
    • Rispondi

    Interessante…
    La prima cosa che viene in mente è usare due celle successive in modo da avere 16 bit.
    Utilizzare il minor numero di celle possibili… dipende dalle esigenze.
    Se si ha necessità di memorizzare diversi valori superiori a 255 allora la cosa migliore mi sembra quella di fissare un range di celle da usare in coppia. Ad esempio: dalla cella 900 alla cella 1024.

    Se invece la necessità di memorizzare valori superiori a 255 fosse limitata a pochi valori e non possiamo sapere a priori quanti saranno (o se ve ne saranno), allora credo sia meglio fissare una sequenza che indica che le celle successive sono da considerare insieme. Ad esempio: 255 255 255 indica di considerare le successive 2 celle insieme. Certo stiamo usando 5 celle per memorizzarne 2, ma l’uso è – come specificato – limitato ai casi in cui i valori più grandi di 255 da memorizzare siano pochi, non sappiamo a priori quanti siano ed addirittura se ve ne siano.
    Rimane da risolvere un caso limite: se i valori 255 255 255 non fossero lì ad indicare la sequenza che ci dice di considerare due celle insieme ma fossero lì come valori memorizzati. Si può risolvere in diversi modi, il più semplice che mi viene in mente è… usare due celle anche per memorizzare il valore 255. Si sprecheranno quattro celle ogni volta che bisogna memorizzare il valore 255.

    Con lo stesso metodo, si possono usare più celle invece di due ottenendo la precisione necessaria, se dovesse servire…
    Avrò risposto almeno in parte al quesito?

    1. Grande Paolo,
      ottime risposte e idee valide per risolvere il quesito.
      Vedo che sei preparato e volenteroso.
      Se ti va di scrivere qualche sketch su questo argomento e pubblicare un articolo io sono a disposizione e sono certo sarà di grande interesse.

      Mauro

        • Paolo il 25 Marzo 2013 alle 08:34
        • Rispondi

        Mi sono accorto di un errore nel secondo metodo che propongo.
        Considerando il fatto che i valori fino a 254 rappresentano valori memorizzati ed invece 255 è un valore di controllo, è inutile avere la sequenza di tre 255 255 255 per indicare che le successive due celle vanno considerate come un unico valore a 16 bit. Ne basta uno solo.
        Una cosa del genere…
        x < 255 valore
        255 le due celle successive rappresentano un unico valore a 16 bit
        255 255 le quattro celle successive rappresentano un valore a 32 bit
        255 255 255 valore in virgola mobile x.xxxx Eyy
        255 255 255 255 valore di data ed ora ……

        Per l'articolo… va bene, ma dovresti darmi una mano, sarebbe il primo sketch che scrivo per Arduino che ho preso da pochissimo.

        1. Ciao Paolo,
          certo che ti aiuto 🙂

          Mauro

    • Elia il 2 Aprile 2013 alle 21:27
    • Rispondi

    Ciao, complimenti per il blog!
    avrei solo una piccola domanda riguardo la scrittura della EEPROM: se si scrive sulla memoria dall’indirizzo 0 all’indirizzo 1024(come hai fatto nel secondo sketch) non si compromette il funzionamento del micro?
    Scrivendo così da cima a fondo non si toccano i registri delle porte, PWM, Timer, ecc,…?
    Spero che la domanda non sia banale:) ho già lavorato sulla EEPRM di altri micro e in quei casi c’erano dei registri specifici per immagazzinare dati. Forse il mio dubbio é scontato e non ti é passato per la testa di specificare la cosa:)
    Grazie mille:)

    1. Ciao Elia,
      il tuo dubbio non è affatto banale o scontato.
      Non ho trovato documentazione in merito, se la trovi mi farebbe piacere condividerla.
      Ho sempre pensato che la parte scrivibile della EEPROM sia quella che non contiene registri del micro controllore, del resto è lui stesso a decidere dove puoi o non puoi scrivere.

      Mauro

        • teo il 5 Gennaio 2016 alle 03:38
        • Rispondi

        la EEPROM è completamente separata dal resto della memoria. dovrebbe essere di natura completamente diversa anche a livello hardware

        1. Ciao Teo è una domanda?

    • Ivan il 19 Luglio 2013 alle 17:51
    • Rispondi

    Buona sera, sto lavorando ad un progettino in cui mi servirebbe leggere un numero memorizzato in precedenza dalla eprom. Esattamente questo:
    http://forum.arduino.cc/index.php?topic=177753.new;topicseen#new

    Come posso fare per leggere e memorizzare questo NUMERO?

    Grazie mille dell’aiuto, purtroppo non sono un programmatore esperto 🙂

    1. Ciao Ivan,
      per leggere e scrivere nella EEPROM di arduino esistono due semplici funzioni read() e write()

      Dipende da che numero devi memorizzare, e da dove lo vuoi leggere.

      Mauro

    • Mondin Marco il 20 Agosto 2013 alle 16:21
    • Rispondi

    Semplicemente userei due celle consecutive, gli operatori di scorrimento, somme e prodotti logici.

    #include

    int pinToStore=A0; /* il valore sul pin A0 sarà memorizzato alla pressione del pulsante 2*/
    int pushButtonStore=2; /* Il pulsante al pin 2 indica quando memorizzare lo stato del pin A0 */
    int pushButtonRead=3; /* Il pulsante al pin 3 indica quando leggere il dato memorizzato sulla EEPROM */
    int storedValueOffset=200; /* Un valore a caso di esempio che indica la posizione del dato */

    void setup() {
    pinMode(pushButtonStore, INPUT);
    Serial.begin(9600);
    }

    void loop() {
    if(digitalRead(pushButtonStore)==HIGH) {
    int value=analogRead(pinToStore); /* il valore può variare tra 0 e 1023. */
    int byte0=value&255; /* con un prodotto logico per 255 ottengo gli 8 bit meno significativi. */
    int byte1=(value>>8)&255; /* con uno spostamento a sinistra ed il prodotto logico ottengo gli 8 bit più significativi. */
    EEPROM.write(storedValueOffset, byte0);
    EEPROM.write(storedValueOffset+1, byte1);
    delay(5);
    }
    if(digitalRead(pushButtonRead)==HIGH) {
    int byte0=EEPROM.read(storedValueOffset);
    int byte1=EEPROM.read(storedValueOffset+1);
    int value=(byte1<<8)|byte0; /* somma logica del valore in byte1 spostato a sinistra di 8 bit e byte0 */
    Serial.print("Valore memorizzato : ");
    Serial.print(value,DEC);
    Serial.println();
    delay(5);
    }
    }

    1. Grazie Marco,
      soluzione davvero note restante con 2 posizioni riesci a memorizzare 1023 valori senza perdita di definizione.
      Ti chiedo se tale metodo potrebbe essere adattato ad una situazione in cui non sai a priori il valore da memorizzare, diciamo che potrebbe essere 105423 o 3467 ecc..

      Mauro

        • Mondin Marco il 22 Agosto 2013 alle 17:31
        • Rispondi

        In realtà ho indicato 0-1023 solo perché è la risoluzione del pin di ingrasso analogico.
        Il metodo usato senza modifiche può memorizzare o leggere un intero(positivo) arbitrario a 16bit, ovvero con valori che oscillano tra 0 e 65535.
        Se fosse necessario memorizzare interi a 24 o 32bit modificherei appena il tutto per spezzare il numero in 3 o 4 BYTE equivalenti a 3 o 4 celle della EEPROM. Ogni cella può contenere un massimo di 8 bit.
        Ovviamente prima di definire la dimensione dei numeri dovrei definire il dominio in cui lavorerà lo sketch in modo da poter poi scegliere un opportuno limite.

        1. Grazie Marco,
          avevo inteso il motivo della tua scelta e nella maggior parte dei progetti soddisfa il quesito di memorizzazione.
          Ti ho chiesto un approfondimento in quanto in un progetto a cui ho adorato averi dovuto memorizzare un numero arbitrariamente grande proveniente dalla lettura di un encoder molto definito: 3000 impulsi/giro

          Hai ragione senza definire un dominio di azione é dura conoscere il limite ed impostare correttamente il codice.

          Mauro

            • Mondin Marco il 23 Agosto 2013 alle 15:22

            Per definire i limiti del dominio in un caso come il tuo, conoscendo il dato che hai esposto si è già a buon punto.

            Facciamo due ipotesi:

            -Supponiamo che il componente meccanico collegato all’encoder abbia un regime massimo di 1.500 Giri/minuto.
            -Supponiamo che il lavoro massimo di tale componente meccanico sia di 2 giorni.

            2 giorni sono 2.880 minuti (60minuti x 24ore x 2giorni). Quindi se il componente meccanico lavorasse al massimo per tutti e due i giorni, avrei un massimo teorico di 12.960.000.000 impulsi (3000 impulsi x 1500 giri/minuto x 2880 minuti).

            Il massimo memorizzabile in 3 celle (24 bit) è 16.777.215 e non sarebbe sufficiente.
            Il massimo memorizzabile in 4 celle (32 bit) è 4.294.967.295 nemmeno questo è sufficiente.
            Il massimo memorizzabile in 5 celle (40 bit) è 1.099.511.627.780 sufficiente non solo a memeorizzare per i due giorni richiesti, bensì addirittura per 169 giorni consecutivi al massimo. Cosa piuttosto improbabile per quasi ogni applicazione.

            Per memorizzare 5 celle alla volta userei sempre il prodotto booleano per 255. Tale operazione equivale a applicare una maschera di filtro che restituisce solo gli ultimi 8 bit a destra. Ad operazione farei scorrere a destra di 8 bit e ripeterei il tutto.
            ——————-
            Supponendo che A sia l’intero e B un array di interi da memorizzare:

            int B[5];

            B[0] = A & 255; // Maschera che filtra solo i primi 8 bit
            A = A>>8; // Scorro a destra di 8 bit A
            B[1] = A & 255; // Va beh….
            A = A>>8; // Ok….
            B[2] = A & 255;
            A = A>>8;
            B[3] = A & 255;
            A = A>>8;
            B[4] = A & 255;

            —————-
            Se vogliamo ottimizzare:

            int B[5];

            for(int indice=0;indice>8;
            }

            —————-
            Se vogliamo anche preservare A:

            int B[5];
            int ALavoro=A;

            for(int indice=0;indice>8;
            }

            —————-
            Nello stesso ciclo invece che usare l’assegnazione all’array B potrei direttamente scrivere sulla EEPROM all’indirizzo (offset_deciso + indice). Basterebbe sostituire “B[indice] = ALavoro & 255;” con “EEPROM.write(storedValueOffset+indice, ALavoro & 255);”

      • Domenico Alfano il 7 Settembre 2013 alle 00:55
      • Rispondi

      Ciao Marco, ottimo codice complimenti.
      Volevo chiederti se per far si che il codice legga e salvi lo statto di più di un pin basta modificare int pinToStore=A0 in
      int pinToStore=(A0, A1, A2) o se vanno fatte ulteriori modifiche al codice
      Il pin da salvare può essere anche del tipo digitale ? devo salvare lo stato di alcuni led per poi richiamarli con la funzione read.
      Grazie mille !
      Domenico

      1. Ciao Domenico,k
        grazie per i complimenti.
        Se desideri salvare lo stato di altri pin ( analogici o digitali ) dovrai modificare il codice in modo da indicare ad arduino di leggere più pin e memorizzare ciascun valore in una posizione di memoria.

        Mauro

    • Mondin Marco il 23 Agosto 2013 alle 15:25
    • Rispondi

    Scusa se non ho rispettato il regolamento ed ho postato pezzi di sketch! Il Problema è nell’ultimo commento sono pure stati cannibalizzati e resi incomprensibili…

    1. Ciao Marco,
      non preoccuparti, la tua spiegazione è incredibilmente precisa e benfatta.
      Ti andrebbe di trasformarla in un articolo per il Blog?
      In pratica possiamo procedere in due modi:
      a) ti creo un account come autore e tu scrivi l’articolo, decidiamo insieme la data di pubblicazione;
      b) mi invii via email tutto il testo e lo sketch ed io ti pubblico l’articolo;

      La soluzione A ti permette di ricevere e rispondere ai commenti oltre al fatto che quando hai qualche altro articolo da scrivere puoi farlo liberamente.

      Mauro

        • Mondin Marco il 23 Agosto 2013 alle 16:58
        • Rispondi

        Grazie mille, sono molto onorato da ciò.
        Tieni comunque presente che con arduino sono ancora agli inizia, semplicemente lo trovo molto intuitivo in quanto sono ormai molti anni che programmo in c ed alcuni anni che programmo in C++.
        Il linguaggio di programmazione di arduino alla fine è un C++ con delle integrazioni dedicate che derivano da wiring.
        Le nozioni di algebra booleana derivano invece dagli studi e dal fatto che per un breve periodo ho programmato anche in assembly per 680×0 ed in quel caso era indispensabile digerirla.
        Una volta appresi i fondamenti non ho mai smesso di usarla nemmeno con il C ed il C++.

        Mi trovo a mio agio solo per questo.

        Poi anche io sono appassionato di bricolage, informatica ed elettronica.

        Facciamo così:
        Ti invio una bozza di articolo con tanto di sketch, e se lo trovi di tuo gradimento valuti se pubblicarlo e/o aprire l’account come autore.
        Mi ci vuole solo un po’ di tempo per stenderlo.
        Grazie ancora.

    • Ivan il 8 Settembre 2013 alle 14:37
    • Rispondi

    Grazie ad entrambi per l’aiuto!
    Ho ripreso a sperimentare..
    Mi farò sentire presto

    • Giordano Settimo il 24 Dicembre 2013 alle 16:06
    • Rispondi

    Ciao Mauro, ennesimo commento sul tuo fantastico blog.
    Sto creando un piccolo progetto con Arduino per cui mi piacerebbe ottenere il corretto funzionamento anche dopo una mancata alimentazione; mi spiego meglio.

    Se mentre l’algoritmo continua a funzionare improvvisamente viene a mancare l’alimentazione della scheda, una volta ripristina mi piacerebbe che l’algoritmo riprendesse da dove si era interrotto invece che ripartire dall’inizio.

    Per farlo potrei utilizzare una variabile, salvata in eeprom, però dovrei salvarla (per aggiornarne il valore) ad ogni loop e quindi le 100.000 scritture finirebbero presto… qualche idea ?

    1. Ciao Giordano,
      mi passano in mente 3 strade possibili, da sperimentare:

      1. scrivi solo i cambiamenti del valore e non tutte le volte, leggere puoi farlo infinite volte;
      2. usa più celle in modo da allungare la vita di ciascuna;
      3. Usa una SD card

      Mauro

    • David il 6 Febbraio 2014 alle 11:47
    • Rispondi

    Ciao Mauro, complimenti per questo utilissimo sito.
    Per scrivere dei valori su EEPROM superiori a 255 bisogna (almeno questo è 1 metodo) usare due celle, così come funziona il can-bus: prima cella da 0 a 3, seconda cella da 0 a 255, così hai 255×4 = 1020 valori.
    Ciao e grazie

    1. Ciao Davide,
      la tua soluzione è certamente interessante, trovi nel blog un articolo dedicato alla gestione delle celle con gli operatori binari scritto da un appassionato molto ferrato sull’argomento 🙂

      Mauro

    • Marco il 24 Luglio 2014 alle 10:03
    • Rispondi

    Salve Mauro, sto cercando di inserire dei dati da excel in un programma in modo da far muovere un motore ogni 0,05 seconmdi, grazie all’arduino motor shiled, collegato ad un motore bipolare passopasso. Posso usare la EEPROM per questo programma?
    Grazie in anticipo

    1. Ciao Marco,
      dipende da dove ti serve caricare i dati e come devono essere mantenuti.
      Se gli intervalli sono regolari non comprendo perché mettere questi dati in EEPROM e non fissarli nello sketch.

    • Marco il 24 Luglio 2014 alle 15:32
    • Rispondi

    Grazie della risposta,
    il problema è che ho moltissimi dati da inserire nel programma.
    Ogni 0,05 secondi devo dare al programma un dato che ho su excel e questo per una giornata intera.
    Il programma che uso è quello che ha messo sul suo sito; “Motori passo-passo bipolari con Arduino – prima parte”.
    Quindi la mia domanda è come faccio a portare questi migliaia di dati che ho su excel dentro il programma dell’arduino?

    grazie
    Marco

    1. Ciao Marco,
      mi vengono in mente solo due modi:
      1. come matrice ( array ) nello sketch
      2. una shield per scheda SD card su cui carichi un file csv e lo leggi ed elabori nello sketch

        • Marco il 24 Luglio 2014 alle 17:36
        • Rispondi

        ciao Mauro,
        non riesco a far entrare i dati nel programma dell’arduino , mi potresti far un esempio di come inserire dati che ho su excel o blocconote in un pogramma con una matrice(array) perfavore?

        1. Ciao Marco,
          dipende da che tipo e forma di dati vuoi catalogare e come decidi tu di utilizzarli.
          Per aiutarti posso suggerirti di consultare la guida arduino sul sito ufficiale nella sezione dedicata agli array, ci sono alcuni esempi che possono aiutarti a capire come organizzare i tuoi dati.

    • Matteo il 16 Settembre 2014 alle 14:59
    • Rispondi

    Ciao Mauro,
    sto costruendo un circuito con una cella di carico e arduino tuttavia ho un problema:
    praticamente voglio memorizzare su una sd card dei dati generati da calcoli in seguito alla misura dei carichi (e fino a qui nessun problema), ma dal momento che è possibile che arduino venga spento devo dargli la possibilità quando si riaccende di rileggere l’ultimo valore memorizzato che mi serve per riniziare o meglio continuare il processo di misura e di calcoli. Quello che voglio dire è che arduino lo deve riconoscere proprio come variabile. Inoltre c’è da tenere conto che le informazioni memorizzate aumentano con le misure fatte.
    Non so se cambia qualcosa comunque vorrei precisare che il valore da memorizzare ha 8 cifre dopo la virgola.
    Ho visto sul web che si parla spesso dell’array e di librerie specifiche, ma purtroppo non ho trovato nulla di preciso che riesca a chiarirmi il funzionamento. Ho iniziato da poco ad avere a che fare con arduino e considerando anche il fatto che l’unico codice che avevo visto finora era il pascal non sono molto pratico di linguaggi di programmazione quindi se qualcuno ha da propormi un sito su cui trovare qualcosa di utile o qualche esempio vi sarei estremamente grato.

    Grazie.
    Matteo

    1. Ciao Matteo,
      puoi sicuramente trovare numerosi esempi di sketch arduino sul blog.
      Come avrai letto in questo articolo ho decritto nel dettaglio come utilizzare la EEPROM per memorizzare i dati e rileggerli al riavvio.

    • Steve Zoff il 3 Dicembre 2014 alle 11:18
    • Rispondi

    Buon giorno Mauro, seguo le evoluzioni di Arduino da vecchio sperimentatore . Ora mi chiedevo : ma non sarebbe meglio se le righe dell’IDE venissero numerate durante la scrittura di uno sketrch? Uso IDE 1.0.6 ma non riesco a vedere se c’è l’opzione nei settaggi. Esiste la possibilità? Grazie

    1. Ciao Steve,
      penso anche io sia una bella agevolazione.
      Nell’IDE 1.0.6 c’è l’opzione nelle preferenze “display line numbers”

    • Alessandro il 3 Gennaio 2015 alle 02:41
    • Rispondi

    Vorrei aggiungere all’ottimo articolo anche un bel link per libreria EEPROMMEX
    http://thijs.elenbaas.net/2012/07/extended-eeprom-library-for-arduino
    consente di memorizzare anche float number ed altre funzioni belle e pronte…
    anche se personalmente preferisco scrivere su sdcard, la EEPROM rischia di divenire inutilizzabile ben presto, 100.000 cicli di memorizzazione non sono tanti, con scritture ogni 5ms (ad esempio in fase di test e prove varie) in poco più di 6 minuti il limite è raggiunto)

    1. Grazie Alessandro la proverò.
      Certamente la SD Card è preferibile se stai realizzando un data logger o simili, la EEPROM è utile se devi salvare una tantum le configurazioni.

    • Marta il 7 Febbraio 2015 alle 18:33
    • Rispondi

    Ciao, articolo interessante e molto chiaro, complimenti!
    Mi rimane un dubbio “a monte”… non mi è chiaro per quale motivo si dovrebbe usare l’EEPROM dato che la memoria flash è più performante. Quindi in generale perchè è prevista una EEPROM sull’arduino? Non sarebbe meglio salvare anche i dati di configurazione comunque nella memoria flash?

    Grazie!

    1. Ciao Marta,
      nella flash puoi salvare solo lo sketch, che io sappia non c’è modo di accederVi da sketch per salvare dei dati.
      Se conosci un metodo per farlo mandami il link che leggo volentieri come si fa.

  1. Salve Mauro, vorrei utilizzare la EEPROM per salvare la posizione (valore) di un potenziometro ed ho capito come si fa, è semplice.
    Ho però alcuni dubbi sul numero di scritture del valore:
    Volendo preservare il numero di scritture devo per forza di cose impostare il programma affinché il write avvenga con la pressione di un pulsante, altrimenti, poiché il cambio stato del potenziometro è monitorato all’interno a loop() per esigenze di utilizzo, continuerebbe a scrivere ad ogni ciclo e quindi “invecchiare” la EEPROM, giusto?
    Grazie, colgo l’occasione per farle i complimenti per il blog.

    1. Ciao GordTheRogue,
      si, purtroppo è corretto quello che dici.
      Se vuoi “preservare la vita della EEPROM” dovrai decidere con un evento esterno il momneto in cui salvare e non lasciare che sia il loop() a farlo in automatico.

    • Juri il 18 Maggio 2015 alle 16:35
    • Rispondi

    ciao articolo interessante, qualcuno conosce un modo per “precaricare” i dati nella eeprom cosi’ da poterli utilizzare in un secondo momento (per esempio una tabella) ogni volta che arduino viene acceso, senza tutte le volte caricare tutti i dati nella eeprom all’inizio del programma? grazie

    1. Ciao Juri,
      non ho compreso la tua esigenza.

        • Juri il 18 Maggio 2015 alle 21:06
        • Rispondi

        vorrei, nel momento in cui carico lo sketch, caricare anche i dati nella eeprom, in quanto il programma userebbe suddetti dati come “riferimento” ed in sola lettura, li vorrei nella eeprom in modo da non sprecare 1k di memoria flash. e’ possibile caricare dati nella eeprom mentre carico (prima o dopo) lo sketch in arduino?

        1. Ciao Juri,
          nella setup() puoi richiamare i dati in EEPROM ma questi passeranno direttamente nella SRAM al momento in cui li invochi per essere gestiti dallo sketch.
          La Flash serve a mantenere in memoria lo sketch stesso.

            • Juri il 19 Maggio 2015 alle 12:01

            purtroppo non riesco a spiegarmi, nella eeprom e’ memorizzata una tabella di 256 bytes, i dati vengono letti soltanto uno alla volta, tramite la stessa variabile value=EEPROM.read(tab)
            il valore di “tab” viene determinato da un sensore accelerometrico, i 4 bit meno significativi sono la Y mentre i 4 piu’ significativi sono la X, in base a questa variabile il programma va a leggere il risultato nella tabella. in memoria ci sono 4 tabelle. totale 1k, i valori nelle tabelle sono statici, cioe’ sono delle costanti e servono da riferimento, il mio problema e’ che per caricare la eeprom con le tabelle spreco memoria sketch perche’ che io sappia si possono caricare valori nella eeprom solo tramite programma. oltre Arduino io programmo altri micro, il PICAXE per esempio ha un comando che viene eseguito solamente durante la compilazione dello sketch (non occupa memoria) e carica i dati nella eeprom, “DATA” come nei vecchi computer a 8 bit 🙂 mi chiedevo se su arduino esistesse qualcosa del genere, ho letto che e’ possibile farlo, tramite linea di comando) con AVRDude, ma richiede un programmatore apposito (ICSP) che non ho.

          1. Ciao Juri,
            ora spero di aver capito la tua intenzione,
            Puoi eseguire due sketch differenti: il primo carica le 4 tabelle nella EEPROM.
            Poi sostituisci lo sketch con quello che deve solo leggerle e non necessita più delle informazioni da scrivere nella EEPROM.

            L’alternativa è l’uso del programmatore AVR ma tenterei prima l’ipotesi che ti ho scritto se risponde al tuo problema.

            • Juri il 20 Maggio 2015 alle 12:15

            l’idea e’ buona, provero’ come hai detto tu, con la speranza che quando vado a caricare il secondo sketch non venga cancellata l’eeprom 😀 grazie

          2. Ciao Juri,
            se nel secondo sketch eviti i comandi di write sulla EEPROM non rischi.
            La EEPROM in arduino è separata dalla Flash.

    • Agostino il 20 Giugno 2015 alle 10:41
    • Rispondi

    Ciao, come faccio a resettare o eliminare la memoria della eeprom?

    1. Ciao Agostino,
      puoi solo sovra scriverla, non ha senso eliminarne un dato se non sostituendolo con un altro, sprecheresti una scrittura quando puoi semplicemente ignorarla o sovra scriverla.

    • Gianluca Giangreco il 2 Dicembre 2015 alle 18:38
    • Rispondi

    Io per scrivere il valore k sulla EEPROM ho fatto semplicemente così:

    EEPROM.update(1,k/256); EEPROM.update(0,k%256)

    in 1 (High Byte) scrivo k/256 (prende evidentemente solo la parte intera), mentre
    in 0 (Low Byte) scrivo il resto della divisione stessa.

    Per leggere il valore:

    k=EEPROM.read(0)+(EEPROM.read(1)<<8)

    cioè: valore contenuto in 0 + valore contenuto in 1 moltiplicato mediante scorrimento per 2^8.
    Funziona! 🙂

    1. Grande Gianluca.

    • Claudio il 19 Dicembre 2015 alle 20:14
    • Rispondi

    Salve a tutti, ho scritto un programma, più che altro sono riuscito a fare il giusto copia e incolla mettendoci un po’ di ingegno che fa una cosa semplice. Premo un pulsante e arduino mi scrive su una SD in un file txt la data e l’ora corrente nella forma dd/mm hh:mm. Quando premo di nuovo scrive nuovamente sotto il primo. In pratica un piccolo conta eventi. Gli eventi da contare sono le mie piccole scosse di natura epilettica e dovrebbero, poi, confluire in un file excel da portare alla mia neurologa. Tutto funziona ma l’aggeggio è così composto arduino + sd shield + rtc. Problema? Troppo grande fisicamente, non posso portarmi in giro un attrezzo del genere! Volevo fare una piccola scatolina con un pulsantino e una presa usb per scaricare i dati sul pc. Arduino potrebbe essere sostituito da un arduino mini. Per l’RTC non si scappa, serve. Si potrebbe risparmiare spazio eliminando la SD e forse si arriverebbe una dimensione tale da portarsi in tasca. Ovviamente i dati dovrebbero andare in eeprom ma non saprei poi come tirarli fuori per farne un txt… insomma, l’idea c’è (potrebbe essere comodo per altre persone che, come me, soffrono di epilessia), la teoria c’è, la pratica e la competenza di programmazione manca… non si può aver tutto dalla vita!!! Avevo anche pensato di usare un’app da mettere su un telefonino, qualcosa ho trovato ma è macchinoso e quindi, magari se stai guidando (con alcuni tipi di epilessia si guida tranquillamente), può essere pericoloso perché ti obbliga ad abbassare gli occhi. Una scatoletta con un pulsante è semplice e non distrarrebbe dall’attività che si sta svolgendo.
    Alla fine… idee????
    Grazie a tutti quelli che hanno avuto la pazienza di leggere tutto il post!
    Claudio.

    1. Ciao Claudio,
      bellissimo progetto !!
      Così su due piedi mi viene in mente la Raspberry Pi Zero sia come dimensioni sia per la possibilità di utilizzare l’ntp ( network time protocol ) per la sincronizzazione dell’orario.
      Potresti poi leggere la SD estraendola oppure studiando un modo di connettere il dispositivo via wifi.

      Se verifichi che possa essere una valida soluzione possiamo approfondire il progetto.

        • Claudio il 30 Dicembre 2015 alle 10:57
        • Rispondi

        Grazie Mauro,
        E’ interessante, ho visto la PI Zero su qualche sito, è un problema trovarla ma quello si risolve con un po’ di pazienza. Non conosco il Python ma da quello che ho letto mi è sembrato di capire che è un linguaggio molto portatile. Immagino, correggimi se sbaglio, che si potrebbe sviluppare il progetto su una Raspberry normale e, una volta visto che funziona, trasferire il tutto sulla Zero. Una Rasperry “normale” ce l’ho. Per il recupero dei dati andrebbe benissimo prendere la SD e copiare i dati su un pc normale per elaborarli in excel, senza complicarsi l vita con wifi.
        Intanto ti ringrazio tanto per l’interessamento.
        Claudio.

        1. Bene Claudio,
          ho visto che in italia la trovi sul sito robotics-3d.com non so se sia già disponibile ma se provi a sentirli magari te ne procurano una in breve.

    • vincenzo il 31 Dicembre 2015 alle 12:37
    • Rispondi

    ciao senti volevo domandarti se arduino e capace di memorizzare un pachetto codici (telecomando)e poi ad una funzione trovarlo e memorizzarlo automaticamente come i telecomandi universali?

    1. Ciao Vincenzo,
      in arduino devi insegnargli tutto, potrebbe farlo, ma devi scrivere uno sketch che si preoccupi di eseguire quanto ti occorre.

    • manuel il 22 Aprile 2017 alle 15:54
    • Rispondi

    scusa la domanda ma anche la eeprom di arduino e di un teefono o di un hardisck ssd ha un limite di cicli ??

    1. Ciao Manuel,
      si tutte le EEPROM che io conosco possiedono un ciclo elevato di scritture ma finito.

    • mattia il 4 Giugno 2017 alle 07:44
    • Rispondi

    Ciao Mauro e complimenti per il blog.
    Avrei una domanda da farti, io avrei bisogno di salvare 3 valori float che rappresentano 3 temperature del tipo: 38.83
    tutte con questo formato.
    volevo sapere secondo te è possibile “spaccare” in due il numero e scrivere consecutivamente delle 6 celle della EEPROM prima la parte intera e poi quella decimale dei 3 numeri?
    ad esempio:
    38.51 39.40 40.43 salvati in memoria come
    cella 512 38
    cella 513 51
    cella 514 39
    cella 515 40
    cella 516 40
    cella 517 43
    spero di essermi spiegato e grazie in anticipo

    1. Si certo Mattia.

      • Maurizio il 13 Giugno 2017 alle 16:46
      • Rispondi

      Ciao Mauro, anch’io come Mattia dovrei memorizzare un valore di temperatura in EEPROM, valore che è una variabile float.
      Ora non so come fare per memorizzarla correttamente e poi richiamarla, puoi aiutarmi?
      Grazie

      1. Ciao Maurizio,
        il metodo suggerito da Mattia non va bene nel tuo caso?

  2. Salve mi servirebbe un mano per resettare una scheda arduino nano montata su una mana se,di un incisore laser, dopo aver eseguito un flash firmware mi si è bloccata e non riesco più a cambiare firmware mi sapreste aiutare?

    1. Ciao Luca,
      la scheda è originale?
      La scheda è smontabile?
      Riesci a vedere la porta Usb di connessione dal computer?

    • Simone il 13 Giugno 2018 alle 17:03
    • Rispondi

    Ciao Mauro,
    complimenti per il blog, davvero utilissimo. Avrei bisogno di un mano. Ti avviso che mi sono affezionato da poco in questo fantastico mondo.
    Sto lavorando ad un progetto che consiste in una tastiera musicale. Informandomi su internet qua e là sono riuscito a crearla ma vorrei andare avanti e svilupparla di più. Praticamente l’ idea è quella di creare sul momento una canzone e memorizzarla sulla EEPROM per poi rileggerla schiacciando un altro bottone, magari.
    E’ possibile una cosa del genere con la EEPROM oppure non ha abbastanza spazio per farlo e quindi dovrei usare qualcos’altro?
    Se conosci pagine in cui c’è già una soluzione simile, ti sarei grato. Io ho provato a guardare ma non ho trovato nulla che potesse soddisfare le mie esigenze.
    Grazie

    1. Ciao Simone,
      il progetto è molto carino ma non so darti dei link da seguire se non quelli che sul mio blog parlano della eeprom.
      Tuttavia considera che su Arduino Uno hai solo 1024 posizioni per numeri interi a 8 bit. Se anche tu riuscissi a memorizzare una nota in un campo ed un tempo in un altro x ogni nota avrai 2 campi quindi 512 posizioni e di conseguenza note. Mi sembra poco anche per piccoli brani.

      Prova con la SDCard: più semplice da gestire, più capiente e puoi sostituirla con una più capiente se vuoi.
      Il tuo progetto è interessante e ti invito a usare i commenti per le prossime richieste e a pubblicarlo quando pronto.

    • simone il 15 Luglio 2018 alle 16:24
    • Rispondi

    Salve a tutti e vi faccio i complimenti per le vostre capacita’ .. siete incredibili… io da 2 anni ho iniziato con arduino,tanto che ho la casa invasa di componenti,sonde,schede e chi piu ne ha ne metta… da autodidatta son riuscito a fare tanti bei lavoretti ma di semplice utilizzo come ad esempio apricancelli piscine con password tramite tastierini dividendo le password tra ospite e admin in modo che l ospite puo accedere solo nelle ore programmate da un orologio esterno a 24h… ma essendo appassionato anche di app android mi sono messo a studiare e a fare le app riuscendo a far dialogare con diversi metodi arduino e le app fatte da me’.. tramite tablet ho fatto una app che gestisce un impastatrice industriale potendo impostare tempi di ciascuna manovra oppure in manuale.. la app inviava ad arduino i comandi tramite il case.. in base alla lettera ricevuta eseguiva l azione… quindi la parte arduino e stata semplice ma la parte android molto piu complessa dovendo estrapolare molti dati dal tablet per renderla funzionale e con i giusti tempi… quindi sembra quasi che sia arrivato al mio limite perche non riesco ancora oggi a comprendere bene la logica di come iniziare le stringhe e di cosa ci vuole dopo.. ho sempre preso progetti esempio e modificati a piacere…. esistono corsi online o anche in determinate sedi dove posso comprendere meglio la programmazione vera e propria? un grande saluto Simone

    1. Ciao Simone,
      mi sembra che tu sia riuscito molto bene a destreggiarti nonostante le cose che scrivi.
      Io ho rilasciato un corso arduino on-line gratuto in questo blog, non è propriamente un corso accademico.
      In alternativa posso consigliarti di partecipare ad uno dei miei corsi in aula se vuoi apprendere le basi della programmazione.

      Mi piacerebbe pubblicare qualcuno dei tuoi progetti se ti va e lo reputi fattibile.

    • Andrea Marulla il 28 Febbraio 2019 alle 14:54
    • Rispondi

    Ciao a tutti, forse sto prendendo una cantonata, ma mi vien da dire che tutto sia molto più semplice in quanto non dobbiamo preoccuparci di spezzettare i byte a mente: il linguaggio ‘C’ fornisce già tutto. Io opterei per mettere tutti i dati da salvare in una struttura, dopo di che attraverso un sizeof() ricaverei la dimensione in byte. A questo punto con un puntatore a char ed un po’ di aritmetica dei puntatori il gioco è fatto sia in scrittura che in lettura. In questo modo non mi preoccupo del formato dei dati ma solo della loro dimensione e disposizione.

    [[ codice rimosso in automatico ]]

    A questo punto nel codice potrete usare la tipologia di struttura DATI come modello dei vostri dati da salvare, e le due funzioni sotto per scrivere e leggere i dati.

    Ol codice che ho messo come esempio l'ho improvvisato qui e non l'ho provato, ma credo dovrebbe funzionare e comunque rappresenta più che altro l'idea di massima.

    Spero di aver dato il mio contributo 😉

    1. Ciao Andrea,
      splendido contributo, tuttavia il codice viene rimosso in automatico come da regolamento.
      Se vuoi inviami via email il tuo codice esempio con il commento linea per linea, come gli articoli del blog, ed io lo inserirò in un articolo a tuo nome.

    • Giacomo Visone il 14 Aprile 2019 alle 22:07
    • Rispondi

    Bellissimo blog

    1. Grazie Giacomo.

    • TicoTico il 12 Maggio 2019 alle 11:17
    • Rispondi

    Ho letto con attenzione tutti i contributi bel blog, Interessanti tutti per vari punti di vista. Essendo interessato, per attività di modellismo ferroviario, alla scrittura e lettura da Eprom l’ultimo contributo con codice rimosso di Andrea Marulla sarebbe utilissimo anche se non testato. Sarebbe possibile averlo?
    Grazie ad entrambi

    1. Ciao TicoTico,
      purtroppo il codice rimosso non è recuperabile.
      Il regolamento non permette di incollare codice e viene rimosso da un sistema automatico.

      Posso lasciare on-line il tuo commento in modo che Andrea possa, leggendo il tuo commento, scriverti per metterVi daccordo su come passarvelo, magari potrebbe pubblicarlo su gitHub e condividerti il link.

        • TicoTico il 14 Maggio 2019 alle 08:23
        • Rispondi

        OK, Molte grazie , Spero di potermi mettere in contatto

    • Lorenzo il 27 Aprile 2022 alle 12:30
    • Rispondi

    Ciao, scusami se ti scrivo ora, ma mi potresti aiutare con arduino MEGA2560 + WIFI?
    Questo è il mio problema:
    – quando carico da PC il mio codice, funziona tutto a doc, ma se resetto o se tolgo e rimetto l’alimentazione, il codice sparisce!! E’ normale? Come posso fare in modo che il codice resti in memoria e che quando do alimentazione, venga eseguito normalmente, come fa ad esempio arduino standard?

    Ti ringrazio.
    Lorenzo

    1. Ciao Lorenzo,
      è un comportamento molto anomalo, il codice viene trasferito nella Flash del 2560 e resta li, è possibile che tu abbia qualche istruzione che cerca la porta seriale o una connessione di qualche tipo ad un pc esterno?

  1. […] al tema principale, come visto nell’articolo sulle EEPROM, ogni cella ha le dimensioni di 1 BYTE, ti serviranno quindi 2 celle per un intero a 16bit, 4 per […]

  2. […] pensato alla EEPROM presente su Arduino. Questo articolo di Mauro Alfieri spiega perfettamente il suo […]

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.