«

»

Mar 19

Stampa Articolo

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.


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

69 comments

2 pings

Vai al modulo dei commenti

  1. Lorenzo

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

    1. Mauro Alfieri

      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

  2. Angelo

    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. Mauro Alfieri

      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

  3. Paolo

    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. Mauro Alfieri

      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

      1. Paolo

        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. Mauro Alfieri

          Ciao Paolo,
          certo che ti aiuto 🙂

          Mauro

  4. Elia

    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. Mauro Alfieri

      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

      1. teo

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

        1. Mauro Alfieri

          Ciao Teo è una domanda?

  5. Ivan

    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. Mauro Alfieri

      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

  6. Mondin Marco

    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. Mauro Alfieri

      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

      1. Mondin Marco

        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. Mauro Alfieri

          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

          1. Mondin Marco

            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);”

    2. Domenico Alfano

      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. Mauro Alfieri

        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

  7. Mondin Marco

    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. Mauro Alfieri

      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

      1. Mondin Marco

        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.

  8. Ivan

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

  9. Giordano Settimo

    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. Mauro Alfieri

      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

  10. David

    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. Mauro Alfieri

      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

  11. Marco

    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. Mauro Alfieri

      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.

  12. Marco

    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. Mauro Alfieri

      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

      1. Marco

        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. Mauro Alfieri

          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.

  13. Matteo

    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. Mauro Alfieri

      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.

  14. Steve Zoff

    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. Mauro Alfieri

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

  15. Alessandro

    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. Mauro Alfieri

      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.

  16. Marta

    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. Mauro Alfieri

      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.

  17. GordTheRogue

    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. Mauro Alfieri

      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.

  18. Juri

    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. Mauro Alfieri

      Ciao Juri,
      non ho compreso la tua esigenza.

      1. Juri

        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. Mauro Alfieri

          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.

          1. Juri

            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.

          2. Mauro Alfieri

            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.

          3. Juri

            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

          4. Mauro Alfieri

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

  19. Agostino

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

    1. Mauro Alfieri

      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.

  20. Gianluca Giangreco

    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. Mauro Alfieri

      Grande Gianluca.

  21. Claudio

    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. Mauro Alfieri

      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.

      1. Claudio

        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. Mauro Alfieri

          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.

  22. vincenzo

    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. Mauro Alfieri

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

  23. manuel

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

    1. Mauro Alfieri

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

  24. mattia

    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. Mauro Alfieri

      Si certo Mattia.

    2. Maurizio

      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. Mauro Alfieri

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

  1. Arduino: ottimizzare la EEPROM - Mauro Alfieri Elettronica Informatica

    […] 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. Un semplice antifurto: memorizzare i codici sensori nella EEPROM | Arduino: i miei progetti

    […] 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. I campi obbligatori sono contrassegnati *

Puoi usare i seguenti tag ed attributi HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>