Corruzione EEPROM.

Salve a tutti, sono nuovo del forum e spero di fare tutto nel modo più corretto e nel rispetto di tutti. Il mio problema come da oggetto è la corruzione della memoria EEPROM. Mi spiego meglio; Ho sviluppato un software che fa uso di dati salvati in EEPROM, dati che vengono letti all'accensione di arduino e assegnati a delle variabili; premetto che ho realizzato un apposito PCB che permette di interfacciare arduino con un complesso circuito elettronico. Fin qui tutto bene, il dispositivo funziona correttamente. Il guaio si presenta in maniera del tutto casuale. Succede infatti i dati in EEPROM vengono in qualche modo corrotti e quindi interpretati in modo errato dal software.

Allora ho scaricato il datasheet dell'atmega2560 (utilizzo un arduino mega) e ho scoperto che esiste un paragrafo dedicato alla corruzione della EEPROM ("Preventing EEPROM Corruption" a pagina 25). Ho capito che ci sono due motivi per il quale la EEPROM si può corrompere:

1) la tensione di alimentazione è troppo bassa e allora in fase di scrittura arduino scrive dati errati 2) la tensione di alimentazione è troppo bassa e allora arduino interpreta male le istruzioni del software andando addirittura a scrivere in EEPROM quando in realtà non dovrebbe farlo.

Il datasheet suggerisce a tal proposito di attivare il Brown-out Detector ma io non saprei come fare. Cercando in internet inoltre ho scoperto che arduino ha già il Brown-out Detector attivo e allora forse bisogna regolarlo meglio?

A qualcun'altro succede il mio stesso problema? Perchè con i microcontrollori PIC non ho mai avuto di questi problemi?

Qualche anima gentile può aiutarmi??

Grazie mille.

Che libreria stai usando?

Che libreria stai usando?

Anche io vorrei saperlo e magari qualche info in più non guasterebbe.

Mai successo, anche quando ne sapevo poco o niente.
Poi per precauzione prima della scrittura in eeprom disabilito gli interrupt e poi li riabilito alla fine.

Puoi provare così:

#include <util/atomic.h>

void eepromUpdate() {

ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
     // Il codice qui dentro non può essere interrotto da IRQ
     // scrivi qui le istruzione per aggiornare la eeprom

}

Ciao.

stefano84: 1) la tensione di alimentazione è troppo bassa e allora in fase di scrittura arduino scrive dati errati

No, se la tensione di alimentazione è sotto il minimo consentito è la EEPROM che non lavora correttamente e può memorizzare i dati in modo errato.

2) la tensione di alimentazione è troppo bassa e allora arduino interpreta male le istruzioni del software andando addirittura a scrivere in EEPROM quando in realtà non dovrebbe farlo.

Altro no, il software non può scrivere per sbaglio in eeprom, il problema è che se la tensione è troppo bassa il micro può eseguire in modo anomalo le istruzioni e se questo avviene durante la scrittura della eeprom è sicuro che i dati risultano alterati.

Il brown out è attivo di default su Arduino pertanto non è possibile che incorri nei problemi sopra citati, al massimo puoi trovare l'ultimo byte che stavi scrivendo alterato se si verifica un calo di tensione e relativo reset forzato dal brown out.

Se trovi tutti i dati sulla eeprom corrotti è altamente probabile che sia il tuo software a farlo, ovvero va a scrivere in eeprom quando non deve, sopratutto se non rilevi nessun reset occasionale del micro dovuto al brown out.

Grazie per le vostre risposte.

La libreria che uso è EEPROM.h.

Per scrivere uso il comando EEPROM.write, mentre per leggere uso EEPROM.read. Prima di leggere o scrivere in EEPROM disabilito gli interrupt con il comando noInterrupts() e poi riabilito con interrupts().

Può essere dovuto a disturbi di natura elettrica? In sostanza arduino pilota una pompa in cc a spazzole (4 ampere), celle di peltier (per un totale di 10 ampere) e un carico resistivo in modo impulsivo (treni di impulsi a 50 Ampere). Può un disturbo elettrico non influire sulla corretta esecuzione del software ma corrompere la EEPROM?

La "tecnica" che uso per scrivere in EEPROM è la stessa che uso per i PIC. MAI AVUTO PROBLEMI.

Nella normale esecuzione del software non vado mai a scrivere in EEPROM. Scrivo in eprom solamente quando entro in un apposito menù di setup è ciò avviene una sola volta subito dopo aver scaricato il software in arduino.

Per MauroTec: puoi spiegarmi a cosa serve quel codice?

GRAZIE MILLE A TUTTI

Potrebbe anche essere una copia della scheda Arduino a bassisimo prezzo dove sono stati usati dei componenti di scarto recuperati per essere venduti a basso prezzo.

Dove e che Arduino hai comprato?

Ciao Uwe

Un eventuale disturbo potrebbe essere provocato dal motore, ma hai detto che leggi la EEPROM durante il setup iniziale, quindi il motore è spento.

Invece potrebbe corrompere le variabili su cui hai scaricato i valori quando il motore entra in funzione.

Se così fosse la EEPROM è a posto e la conferma puoi averla leggendo i suoi valori con un altro sketch.

Un altro motivo potrebbe essere una esaurimento della RAM: succede, ad esempio, usando l’oggetto String.

Cosa hai messo come filtro/riduttore di disturbi?

cyberhs: Un eventuale disturbo potrebbe essere provocato dal motore, ma hai detto che leggi la EEPROM durante il setup iniziale, quindi il motore è spento.

La lettura della EEPROM non può alterarla in nessun modo, al limite ottieni dati errati, però basta rileggerli per risolvere se è causato da un problema di alimentazione. La EEPROM può essere alterata solo da problemi durante la fase di scrittura, p.e. uno spike sulla alimentazione, oppure dal codice stesso se va a scriverci sopra quando non deve farlo, ovvero errore di programmazione :)

Suggerirei, per poterti dare indicazioni:

  • dicci se stai usando una MEGA originale o qualcosa di cinese
  • mostraci il programma
  • mostraci lo schema elettrico

Per MauroTec: puoi spiegarmi a cosa serve quel codice?

Trovi qualcosa qui:http://www.nongnu.org/avr-libc/user-manual/group__util__atomic.html#ga362c18b15a09703e42e1c246c47420ef

Se usi noInterrupts() ecc ottieni all'incirca stesso risultato del codice sopra. In generale quel codice serve a rendere una porzione di codice non interrompibile. Un richiesta di interrupt infatti può verificarsi ed interrompere l'esecuzione di una funzione, cosa che avviene ad esempio quando arriva un carattere sulla seriale. Tuttavia se gli interrupt sono già disabilitati li lascia disabilitati a differenza di noInterrupt() e interrupt();

Comunque non è questo il problema, prendi in considerazione un problema di memoria RAM, scrivi un programmino di test e fallo girare accendendo e spegnendo le varie utenze. Se la eeprom non si corrompe ci sono buone probabilità che ci sia un problema di RAM (es. scrivi fuori da un array, eccessivo uso della classe String.)

Ciao.

Disabilitare gli interrupt per scrivere la EEPROM mi sembra paranoico. Visto che per farlo usiamo una libreria, sarà sua cura farlo, se necessario. E in effetti è proprio così:

   __asm__ __volatile__ (
        "/* START EEPROM WRITE CRITICAL SECTION */\n\t"
        "in r0, %[__sreg]           \n\t"
        "cli                        \n\t"                              // <-- Disabilita interrupt
        "sbi      %[__eecr], %[__eemwe]   \n\t"
        "sbi      %[__eecr], %[__eewe]    \n\t"
        "out      %[__sreg], r0           \n\t"
        "/* END EEPROM WRITE CRITICAL SECTION */"
        :
        : [__eecr]  "i" (_SFR_IO_ADDR(EECR)),
          [__sreg]  "i" (_SFR_IO_ADDR(SREG)),
          [__eemwe] "i" (EEMWE),
          [__eewe]  "i" (EEWE)
        : "r0"
    );

(Da eeprom_write_byte() di avr-libc)

In ogni caso, qualcosa del genere succede anche a me, ma credo sia colpa della MCU, temo sia danneggiata. Hai provato su un’altra scheda? Se leggere dati “corrotti” è un grosso problema per te, puoi introdurre un checksum per verificare che quel che hai letto sia corretto.

Ma, ho avuto l'ardupower acceso per due anni consecutivi, e non ho avuto problemi con la eeprom. I parametri del tcp e altre menate erano salvate in eeprom, le leggeva all'avvio e le scriveva quando accendevo o spegnevo le prese. Effettivamente uso una uno non una mega e le letture e scritture erano poche, ma mi sembra strano. Non è che nel codice ci sono problemi con gli indirizzi e in qualche caso particolare scrive i dati nel posto sbagliato e corrompe la memoria.

Alberto

Buongiorno a tutti,
chiedo scusa per la mia assenza.
Effettivamente, lavorando con un display touch, devo gestire un bel pò di stringhe che definisco così:

#undef PROGMEM
#define PROGMEM __attribute__((section(".progmem.data")))

const char *string_array[] = {

"stringa1",
"stringa2",
..............,
..............,
}

inoltre per aggiornare le variabili in eeprom mi affido ad un array; Mi spiego meglio:

all’accensione leggo la eeprom e inizializzo le variabili

variabile1=EEPROM.read(indirizzo1);
variabile2=EEPROM.read(indirizzo2);
variabile3=EEPROM.read(indirizzo3);
........

definisco un array

uint8_t aggiorna[2];

quando devo aggiornare un valore in eeprom non lo vado a scrivere subito ma assegno il valore alla variabile (per esempio variabile1) e poi scrivi l’istruzione bitSet(aggiorna[0],0);

ad un certo punto del software (all’interno del while(true)) interrogo la variabile aggiorna in questo modo:

if(bitRead(aggiorna[0],0)){

EEPROM.write(indirizzo1,variabile1);

}

if(bitRead(aggiorna[0],1)){

EEPROM.write(indirizzo2,variabile2);

}

...

if(bitRead(aggiorna[1],0)){

EEPROM.write(indirizzo9,variabile9);

}
....

In altre parole uso la variabile aggiorna per “segnare” quale variabile devo aggiornare in eeprom e poi interrogando sempre tale variabile aggiorno la eeprom in una botta sola.

A questo punto ripeto che io non modifico mai la eeprom a meno che non entro nel menù di setup.
Cio avviene una volta sola dopo aver scaricato il software.

Quindi rimane la possibilità che usando tante stringhe in qualche modo vado a scrivere in locazioni sbagliate di memoria. Ho ancora qualche dubbio ma cerchero di controllare meglio le istruzioni che vanno a scrivere in eeprom.

GRAZIE a tutti.

P.S.: Compro l’arduino mega dal sito ufficiale quindi sono sicuro che sono originali

stefano84: P.S.: Compro l'arduino mega dal sito ufficiale quindi sono sicuro che sono originali

Se non ci dai lo sketch intero non sappiamo darti nessuna risposta solo supposizioni.

Spero proprio di sí. Se il produttore non vende Arduini originale chi altro?ß

Ciao Uwe

uwefed: Spero proprio di sí. Se il produttore non vende Arduini originale chi altro?ß

Adesso Seeedstudio vende Genuino originali made in china :) Disponibili da EXP.

Mi spiace ma non posso postare tutto il codice....è troppo grande. Sono circa 12.000 righe di codice distribuito su più file

Potresti inviarlo, il modo ci sarebbe.

Ma tanto nessuno lo leggerebbe se è lungo quanto dici :)

allora ho il sospetto che fai da qualche parte un index overflow di un array. Ciao Uwe