A fine vita della memoria EEPROM

Vorrei capire cosa succede ai comandi di Read e Write a fine vita ( di 100'000 volte) della EEPROM interna a Atmega328.
C'è modo di capire se la memoria è danneggiata o genera un qualche errore?

A parte questa curiosità, ho necessita di salvare circa 3'000 volte al giorno una variabile, ed evitare perdite d'informazioni durante un riavvio o perdita di alimentazione.

Per aumentare la durabilità della memoria posso alternare il salvataggio della variabile in diverse pagine della EEPROM (che dovrebbe ricadere ogni 16 o 32 byte) ?

Prendi con le pinze perchè non sono ferratissimo...

  • il problema ce l'hai solo in scrittura, la read puoi farla finchè vuoi
  • non ti conviene salvare solo quando perdi l'alimentazione? L'ho fatto in un mio progetto (grazie all'aiuto del forum)... Con un condensatore e un interrupt potresti risolvere
  • puoi collegare una memoria esterna tipo fram o roba simile
  • puoi salvare su tutta la eeprom in modo circolare, così riduci il numero di scritture per singola cella

Edit: qui qualcuno con un problema simile al tuo

La ditta garantische un minimo di x scritture alle condizioni descritte:

  • All interno di tutto il range di temperatura ammesso
  • Ritenzione dei dai per X anni ( normalmente 10 o 100 anni).
  • durane la scrittura con una certa tensione sdi alimentazione.

La corruzione avviene solo in una determinata direzione ( che adesso non ho in mente).

Comunque se hai pochi Byte usa un RTC con Memoria come il DS1307 o DS3232; se hai piú dati da memorizzare usa un Fram I2C o SPI e sei a posto. I Fram seiali sono normalmente intercambiabili con i EEPROM seriali.

Ciao Uwe

Succede semplicemente che scrivi una cosa e ne leggi un’altra.

Se ti bastano 2 KB ci sono anche le Serial EERAM di Microchip. Sostanzialmente sono RAM esterne da collegare in i2c che puoi scrivere tutte le volte che ti pare (in quanto RAM) e che, se manca alimentazione, salvano al volo tutto il contenuto in una EEPROM interna e lo ricaricano alla riaccensione in maniera totalmente trasparente. Sì, una figata!

SukkoPera:
Succede semplicemente che scrivi una cosa e ne leggi un'altra.

No, la cosa non é cosí semplice. Il problema non puó capitare subito ma anche dopo del tempo. lo scrivi oggi e lo leggi giusto. Dopo del tempo si presenta l' errore e leggi qualcos altro.
Se lo facesse subito sarebbe facile identificare la cella guasta e usare un altra cella di memoria.
Ciao Uwe

E mica ho detto che succede subito ;).

fratt:
Edit: qui qualcuno con un problema simile al tuo
Tanti dati che cambiano spesso - Hardware - Arduino Forum

beh io ho una differenza fondamentale, non ho alcun problema in caso di spegnimento, anche accidentale
A me serviva ram. Anche non tamponata
Perdere i dati per me è un non rischio

ilmandorlone:
C’è modo di capire se la memoria è danneggiata o genera un qualche errore?

Bisognerebbe scrivere anche un qualche byte di controllo (CRC et similia) assieme alla variabile.

L’uso a rotazione delle celle ovviamente aumenta il numero di scritture utili, ma va usata anche una cella o più per registrare quale blocco è attualmente in uso.

Piuttosto a me non è chiaro se il limite 100k scritture si applica ad ogni singola cella o a pagine di n byte (con n sconosciuto :confused:) Se si parla di pagine di 32 byte la “durata” si ridurrebbe a un trentaduesimo (cioè soli 3.2 milioni di salvataggi contro 102 miliardi).

Un documento ed un codice d’esempio … in allegato … :wink:

Guglielmo

AVR101 - High Endurance EEPROM Storage.pdf (47.3 KB)

Atmel - High Endurance EEPROM Storage.c (4.31 KB)

Ma si riesce ad implementare anche con i "comandi" standard dell'ide?

speedyant:
Ma si riesce ad implementare anche con i "comandi" standard dell'ide?

Cosa ? Quel codice ? :o

... guarda che l'IDE richiama semplicemente GCC e NON esistono "comandi standard" del IDE, esiste il C/C++ come linguaggio ed il framework "Wiring" (ovvero una collezione di funzoni già pronte che fanno cose a basso livello nascondendole all'utente), quindi ... :wink:

Ovvio, è fondamentale conoscere il datasheet della MCU su cui si va ad implementralo visto che utilizza comandi a basso livello con accesso ai registri e, purtroppo, Atmel a volte, per registri con uguale funzionalità, da MCU a MCU ha ... utilizzato nomi diversi ... ::slight_smile:

Guglielmo

Claudio_FF:
Piuttosto a me non è chiaro se il limite 100k scritture si applica ad ogni singola cella o a pagine di n byte (con n sconosciuto :confused:) Se si parla di pagine di 32 byte la "durata" si ridurrebbe a un trentaduesimo (cioè soli 3.2 milioni di salvataggi contro 102 miliardi).

Dipende dalla logica del EEProm.
Prima di scrivere un dato la cella deve essere cancellata. La cancellazione é la cosa che limita la vita della cella del EEprom. Dopo la cancellazione che porta la cella a 1 vengono scritte i 0.

Il ATmega328 ha pagine da 4 Byte. Non ho trovato informazioni affidabili se viene programmato il singolo Byte o la pagina intera. Ho trovate entrambe le versioni e non so quale é giusta. Il datasheet del ATmega328 non chiarisce questo punto.

Ciao Uwe

Se si leggono bene le AN di Atmel risulta evidente che si riferisce sempre alla vita della singola cella. Esempio:

Writing the parameters to a circular buffer in EEPROM where each of the elements in the buffer can endure 100 k erase/write cycles can circumvent this.

ed anche:

If the buffer has two levels the number of times that the parameter can be stored is twice the endurance of one single EEPROM cell

E' importante notare che conta, hai fini della "vita" di una cella NON il numero di sole scritture, ma il numero di cancellazioni/scritture (ovvero il ciclo erase/write).

Una tecnica per prolungare la vita è quella che è descritta nella AN che ho allegato al post #8 che usa un buffer circolare.

Un'altra possibile tecnica (ovviamente solo ove applicabile), per aumentare la vita, è quella di cancellare (0xFF) e poi scrivere un bit 0 alla volta ... ovvero, immaginiamo di avere un contatore ch può assumere 8 +1 valori (limite massimo) ... sarebbe possibile scrivere questi 8 +1 valori (codificandoli) utilizzando UNA sola vita della cella :

11111111 - cancellazione e primo valore del contatore
11111110 - secondo valore del contatore
11111100 - terzo
11111000 - quarto
11110000 - quinto
11100000 - sesto
11000000 - settimo
10000000 - ottavo
00000000 - nono
11111111 - cancellazione e di nuovo primo valore

Quindi ... con un po' di trucchetti è possibile aumntare notevolmente la vita di ogni singola cella.

Guglielmo

Claudio_FF:
L’uso a rotazione delle celle ovviamente aumenta il numero di scritture utili, ma va usata anche una cella o più per registrare quale blocco è attualmente in uso.

NON è detto … guarda appunto l’AN che ho allegato e vedrai che trucco usano per sapere a che punto è il buffer circolare :wink:

Guglielmo

ilmandorlone:
Vorrei capire cosa succede ai comandi di Read e Write a fine vita ( di 100'000 volte) della EEPROM interna a Atmega328.
C'è modo di capire se la memoria è danneggiata o genera un qualche errore?

A parte questa curiosità, ho necessita di salvare circa 3'000 volte al giorno una variabile, ed evitare perdite d'informazioni durante un riavvio o perdita di alimentazione.

Per aumentare la durabilità della memoria posso alternare il salvataggio della variabile in diverse pagine della EEPROM (che dovrebbe ricadere ogni 16 o 32 byte) ?

:o mah sembra inverosimile memorizzare qualcosa cosi spesso,
va sistemato il tutto in modo che la mancanza di tensione non sia un problema (batteria tampone/ condensatore) e comunque adoperare sempre il comando update invece di write

gpb01:
l’AN che ho allegato e vedrai che trucco usano per sapere a che punto è il buffer circolare :wink:

Si, con “qualche byte” intendevo qualsiasi sistema, compreso il buffer circolare.

Comunque stress test in corso sull’ultima cella, appena da errore controllo se la penultima funziona correttamente e aggiorno i risultati… per ora siamo a 16 milioni di scritture sulla stessa cella senza errori :o

#include <EEPROM.h>
//-----------------------------------------------------------------------
void stress(){
    uint32_t count = 0;
    while(true){
        byte d = count & 0xFF;
        EEPROM.write(1023, d);
        delay(5);
        if(EEPROM.read(1023) != d){
            Serial.print(count);
            Serial.println("  ERROR");
            return;
        }
        count++;
        if(count%1000 == 0) Serial.println(count);
    }
}
//-----------------------------------------------------------------------
void setup(){
    Serial.begin(9600);
    delay(4000);
    Serial.println("----START----");
    stress();
    Serial.println("----STOP----");
}
//-----------------------------------------------------------------------
void loop(){}
//-----------------------------------------------------------------------

http://tronixstuff.com/2011/05/11/discovering-arduinos-internal-eeprom-lifespan/

Claudio_FF:
Comunque stress test in corso sull'ultima cella, appena da errore controllo se la penultima funziona correttamente e aggiorno i risultati...

E siamo al dunque, a circa 17 milioni di scritture l'ultima cella ha cominciato a scantinare.

La penultima invece dopo 11 milioni di scritture va ancora bene.

Quindi ci possiamo fidare di 100mila scritture su ogni singola cella :slight_smile:

Buona Pasqua.