Consigli Gestione eeprom

Ciao a tutti,
mi potete dare qualche consiglio per ottimizzare il più possibile l'utilizzo della eeprom?

devo gestire la memorizzazione di cinque situazioni nel caso in cui va via la corrente e arduino dopo un po si riavvii...:

1 Tenda aperta
2 tenda in chiusura
3 tenda chiusa
4 Tenda chiusa con pioggia
5 Tenda in apertura

In generale la tenda(in realtà sono 3, ma credo che la logica dietro una la possiamo estendere a tutte e tre), si movimenta in base al tempo fuori, solitamente non più di due cicli(da 1 a 5) al giorno in base alla stagione e condizioni meteo...

ho studiato la libreria eeprom e non ho problemi ad utilizzarla, ma sono preoccupato di giocarmi la eeprom nel breve(facendomi due conti e mettedomi nella peggiore condizione... 2 cicli(da 1 a 5) per 365 giorni(nella bella stagione non si chiudono mai le tende...) sono 27 anni di scritture....ma non vorrei che sto omettendo qualcosa nel mio ragionamento...

uso arduino mega

I conti sono giusti se riferiti all'uso garantito della stessa cella nelle condizioni peggiori di funzionamento/temperature.

È probabile che in realtà si superino abbondantemente i 100 anni :wink:

Nello stress test che ho realizzato tempo fa, le celle della EEPROM hanno cominciato a scantinare verso i 10 milioni di riscritture, cioè cento volte il limite garantito.

L'alternativa, per restare con decine di milioni di riscritture entro i limiti garantiti è quella di usare le celle di tutta la EEPROM a rotazione.

Grazie Claudio!!! ah quindi quello delle 100.000 scritture è un limite non certo... almeno si arriva a 100.000.... ottimo...

ok per la ruotazione non ci avevo pensato...

come mi accorgo se la eeprom comincia a sfarfallare?

simosere:
ok per la rotazione non ci avevo pensato...

C'è sia un application note di Atmel che un esempio in 'c' per questa cosa ...
... se ti va di studiare, io te li allego. :wink:

Guglielmo

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

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

simosere:
come mi accorgo se la eeprom comincia a sfarfallare?

Ci si accorge perché quello che si legge non è quello che si è scritto.

Già con una rotazione tra 10 celle i 27 anni diventano 270.

Con 100 celle duriamo 2700 anni (garantiti :stuck_out_tongue:), bastano?

void writeTenda(uint8_t tenda, uint8_t value)
{
    uint16_t baseAddr = 202 * (tenda - 1);  // tenda = 1 2 3
    uint16_t blockAddr = EEPROM.read(baseAddr) + 256*EEPROM.read(baseAddr+1);
    uint8_t counter = EEPROM.read(blockAddr);
    counter++;
    if (0 == counter)
    {
        blockAddr += 2;
        if (blockAddr > baseAddr+200) { blockAddr = baseAddr + 2; }
        EEPROM.write(baseAddr, lowByte(blockAddr));
        EEPROM.update(baseAddr+1, highByte(blockAddr));
    }
    EEPROM.write(blockAddr, counter);
    EEPROM.write(blockAddr+1, value);
}


uint8_t readTenda(uint8_t tenda)
{
    uint16_t baseAddr = 202 * (tenda - 1);  // tenda = 1 2 3
    uint16_t blockAddr = EEPROM.read(baseAddr) + 256*EEPROM.read(baseAddr+1);
    return EEPROM.read(blockAddr+1);
}

Cacchio... incomprensibile per me Claudio... grazie per il tempo che mi hai dedicato... me lo commenteresti? Diciamo a prova di scemo!?

Al momento nel progetto da banco che ho concluso in ogni fase che cambia lo stato della tenda(in chiusura, chiusa ecc) incremento una variabile byte di 1 e la salvo nella stessa cella... tutto funziona... ma il fatto della rotazione satebbe tanta roba....

Devi salvare solo se viene spento o se va via la corrente... :slight_smile:
P.s.: no, non serve la macchina del tempo.

Datman:
Devi salvare solo se viene spento o se va via la corrente... :slight_smile:

E come fa arduino a capire che sta andando via la corrente? O cpme glielo dico... questa mi è nuova...

Ovviamente non puoi prevederlo, ma puoi mantenere l'elettronica accesa per il tempo necessario a scrivere sulla eeprom mediante un supercondensatore. Considera che basta un secondo.
Se ne è già parlato.

Quindi però serve che arduino verifichi la tensione in ingresso e in caso di calo salvi il parametro.... che intendi per super condensatore? Tipo e valore?

https://forum.arduino.cc/?topic=651223#msg4395346

Letto tutto il topic... ma mi fermo però qui... non ci ho capito una mazza si come procedere e cosa fare...
Sulla linea che alimentata arduino ho un condensatore eletteolitico da 10000uf che potrebbe aiutare.... ma non ho capito poi il passo successivo...

ho trovato questo e questo tutorial...

@Datman possono andare?

teoricamente allo scendere dei volt misurati dovrei poter avere il tempo di salvare... corretto?

grazie mille per lo spunto

Quel modulo è solo un partitore di tensione fatto con due resistenze. Tu devi, invece, alimentare Arduino a 9-12V attraverso un diodo da 1A (1N4001...7) e un condensatore da almeno 0,1F 15V. Metti 10 Ohm in serie al condensatore per non bruciare il diodo. Prima del diodo prelevi la tensione con un partitore 10k/4k7 per non superare i 5V e la mandi a un analog in. Quando la lettura scende al di sotto di circa 500 (9V) o 650 (12V) salvi su eeprom.

Grazie Datman, mi sto organizzando per fare delle prove....

nel frattempo sto sperimentando lato software e come ho detto:

Al momento nel progetto da banco che ho concluso in ogni fase che cambia lo stato della tenda(in chiusura, chiusa ecc) incremento una variabile byte di 1 e la salvo nella stessa cella... tutto funziona...

sto approntando il discorso ruotazione cella di salvataggio... purtoppo quello scritto da Claudio non lo capisco... e non capire significa non imparare... e quindi smanetto da solo.... :slight_smile:

al momento faccio cosi per salvare lo stato della tenda:

 count_eepromSX = 1;  // 1 tende in chiusura,  2 tende chiuse, 3  tende chiuse con pioggia , 4 in apertura , 5 tende aperte, 6 in chiusura con pioggia
EEPROM.write(addr_eepromSX, count_eepromSX);

per leggere invece:

value_eepromSX = EEPROM.read(addr_eepromSX);

quindi secondo me basterebbe ad ogni cambio di count_eepromSX andare a incrementare value_eepromSX di un valore e quindi assegnare count_eepromSX tot celle in base agli stati che ha la cella...quindi 6 celle invece di una...

stessa cosa per leggere al riavvio....

mi sfugge qualcosa?

simosere:
me lo commenteresti?

La faccio molto più semplice, una sola tenda, tre blocchi per 300mila scritture garantite (82 anni nello use case descritto).

Uso delle prime sette celle della EEPROM:

ADDR   UTILIZZO
----   ---------------------------------
 0     indirizzo blocco attivo (1, 3, 5)

 1     contatore
 2     valore

 3     contatore
 4     valore

 5     contatore
 6     valore

Lettura del valore dal blocco attivo:

byte blockAddr = EEPROM.read(0);
byte value = EEPROM.read(blockAddr + 1);

Scrittura del valore, con incremento counter ed eventuale avanzamento blocco se necessario:

byte blockAddr = EEPROM.read(0);
byte counter = EEPROM.read(blockAddr);
counter++;
if (0 == counter)
{
   blockAddr += 2;
   if (blockAddr > 5) blockAddr = 1;
   EEPROM.write(0, blockAddr);
}
EEPROM.write(blockAddr, counter);
EEPROM.write(blockAddr+1, value);

grazie mille Claudio, nel WE lo provo!!! :slight_smile:

blockAddr += 2;

questo però non lo capisco...
sarebbe:
blockAddr = blockAddr + 2; perchè?

inoltre l'unica cosa che dovrei cambiare per le altre due tende,se ho capito bene, è il range di blockAddr e la cella zero EEPROM.read(0);

simosere:
sarebbe:
blockAddr = blockAddr + 2; perchè?

Perché gli indirizzi di inizio dei blocchi sono 1 3 e 5, poi si ritorna a 1.

inoltre l'unica cosa che dovrei cambiare per le altre due tende,se ho capito bene, è il range di blockAddr e la cella zero EEPROM.read(0);

Ogni tenda avrà le sue sette celle, di cui la prima contiene l'indirizzo del blocco attivo della corrispondente tenda.

Nota, per funzionare nella EEPROM vanno prima scritti i valori di partenza sensati, cioè gli indirizzi dei primi blocchi attivi e gli stati (value) iniziali delle tende, altrimenti le celle contengono tutte 255. L'operazione è da fare una sola volta.

Nota, per funzionare nella EEPROM vanno prima scritti i valori di partenza sensati, cioè gli indirizzi dei primi blocchi attivi e gli stati (value) iniziali delle tende, altrimenti le celle contengono tutte 255. L'operazione è da fare una sola volta.

non ho mica capito... :confused:

cmq per mancanza di tempo ho momentaneamente sospeso il tutto, ma intanto vi chiedo un'altra cosa... a tende aperte e chiuse problemi non ne ho a livello di gestione software, ma quando le tende si stanno movimentando mi sorge un problema dato che controllo la posizione della tenda in chiusure e in apertura... in pratica per evitare(in apertura) effetto veladelle tende scalo 38 secondi(il tempo per completare la movimentazione) e all'arrivare allo zero sospendo il controllo che mi ferma le tende in caso di effetto vela(monitorando la velocità del vento) e le fa ripartire quando la velocità del vento è diminuita...

avevo sottovalutato questo aspetto e mi occorre memorizzare anche questo punto quando vado a salvare in eeprom... il conteggio come detto va da 38 a zero. so che per salvare dati in eeprom maggiori di un byte posso usare le funzione put e get... ma come gestire il salvataggio di questi parametri? ad ogni scalare di un secondo devo salvare?

se non applico il discorso di lasciare arduino leggermente in carica con un condensatore(come diceva datman) il tempo necessario il problema si pone....

invece pensavo, ma mi servirebbe qualche dritta se ci sono schede già pronte e come interfacciarle con arduino, di inserire proprio delle batterie ricaricabili sempre in carica che al momento che la 220 va giù subentra per alimentare il tutto per fare le cose con calma... anche im base alla lunghezza del loop ed essere certo che mi salvi sempre in eeprom...

grazie in antcipo

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.