Trucchetto EEPROM e stabilità ethernet

Buona sera a tutti!

Dopo un po di impegni ho riapprocciato al mondo di arduino, e per prima cosa ho completato un progettino che avevo in sospeso: un piccolo impianto di comando luci sia tramite relè che tramite web.

Sono in chiusura, e sto "limando" il codice, chiedendo l'aiuto di persone più esperte per alcuni "trucchetti".

In pratica ho utilizzato un arduino uno ed una ethernet shiled con sd integrata, ed ho collegato 4 input e 4 "bottoni digitali" a 4 led affinchè potessi comandarli sia "manualmente" che tramite rete.
Ho utilizzato per l'interfaccia web la libreria Tiny web server, avendo trovato in rete un bel po di materiale.

Detto questo, avendo intenzione di installare l'impianto nello studio di casa, mi preme (anche se può sembrare non necessario) fare in modo che, nel caso ci fosse un "black out" o un reset della scheda, l'arduino tenga conservato l'ultimo stato. Per fare ciò ho quindi inserito la scrittura dello stato del led sulla EEPROM in un ciclo di if in questo modo:

//dichiarazione variabili

[...]

byte val1;
byte valold1;
int addr1 = 0;

[...]

void loop() {

 if (val1 == HIGH && (valold1 == LOW)) {
    statoLed1 = 1 - statoLed1;
    EEPROM.write(addr1, statoLed1);
    delay(30);
  }
[...]

e così via.

Così facendo, quando spengo e riaccendo l'arduino, quest'ultimo ricorda lo stato della luce.

Tuttavia sono convinto di aver commesso un (parecchi in tutto il codice XD) errore. Così facendo, infatti, sto salvando lo stato della luce in una sola delle 1024 celle disponibili all'interno dell'arduino uno.
Avendo io 4 luci da comandare, esiste un modo affinchè, invece di utilizzare solo 4 celle della eeprom, la memoria dell'arduino venga divisa in 4 partizioni ed io posso utilizzare per la conservazione dell'informazione invece che una sola cella in 256 celle?

Questo perchè non ho la più pallida idea di quante sovrascritture possano avvenire in una sola cella e non vorrei, nel caso in cui venisse "saturata" la capacità di riscrittura delle singole celle, dovere ogni tanto ricaricare lo sketch cambiando manualmente il numero della cella da dover utilizzare!

Inoltre, ho fatto girare il programma per un po, e mi è capitato dopo un certo lasso di tempo, che dal cell non riuscivo più ad entrare nella pagina dedicata al controllo dei led. Mi chiedevo quindi se potesse essere un problema semplicemente di connessione / router, oppure se effettivamente queste schede possono essere "poco stabili" a lungo andare.

Ringrazio tutti per la disponibilità,
e buona programmazione a tutti =) !

Ferdinando

Certo che puoi, invece di lasciare addr1 sempre con lo stesso valore, puoi cambiare indirizzo ogni volta che scrivi.

Potresti anche usare una sola locazione per tutti i LED, infatti in una locazione metti un byte quindi otto bit.
Ma dovresti riscrivere ogni volta che cambia uno qualsiasi dei LED quindi ai fini della "usura della EEPROM" le cose rimangono come prima o peggiorano se usi sempre lo stesso addr1.

Ovviamente adesso ci chiediamo come fare a recuperare l'ultimo addr1 quando riaccendiamo.

Puoi usare tre metodi.
Ne esisteranno altri ma questi tre sono quelli che in questo momento riesco a concepire.

1 - Azzeri tutta la EEPROM con un apposito programma mettendo 0 in tutte le locazioni, poi carichi il tuo ed usi 1 per LED spento, 2 per LED acceso. All'accensione ti basta recuperare l'ultimo valore che è diverso da zero.

2 - Usi una locazione per indicare la locazione dove hai messo l'ultimo valore, quando arrivi a 32 metti 33 e passi alla successiva locazione-indice così eviti di scrivere sempre sulla stessa locazione-indice, all'accensione scorri le locazioni-indice fino alla prima che è diversa da 33 leggi l'indirizzo della locazione che contiene il valore dello stato LED. Così rispetto al metodo 1 eviti di leggere ogni volta tutte le locazioni.

3 - Cerchi su Goggle e trovi tanti sistemi per ruotare le locazioni

Grazie mille per la risposta Paulus.
C'è qualcosa che ancora mi lascia perplesso.

Ad esempio, seguendo il ragionamento io creo un addr1 che va da 0 a 255, un addr2 che va da 256 a 511, e così anche con gli add3 e addr4 (non ho idea di come scriverlo nel codice, me ne curo in un secondo momento, ora mi interessa il processo logico.)

Allo stato attuale, per come ho concepito io il codice, io vado a memorizzare i valori 0 e 1 per il led, che sia spento oppure che sia acceso.

Se utilizzo il primo metodo che mi hai proposto, accade che (correggimi se sbaglio) nel momento in cui io accendo / spengo il led dopo la 256esima volta, nel momento in cui riaccendo l'arduino accade che, non esistendo più il valore "0" che mi hai suggerito tu (nel mio caso potrebbe essere "2" tanto per intenderci), l'arduino mi leggerà sempre il valore che ha usato nella prima scrittura poichè una volta finito il ciclo, tutti i valori sovrascritti saranno diversi da 0.

Il secondo non mi è chiarissimo, credo che tu abbia usato 32 celle invece di 256 come avevo ipotizzato io, ma non mi è chiarissimo il funzionamento.

La terza invece è quella che ho provato per prima, chiaramente :stuck_out_tongue: .
Probabilmente non ho spulciato bene, anche se ormai tutti i titoli della prima pagina di google nella ricerca sono diventati viola :wink:
Non essendo riuscito a trovare nulla di concreto (come ad esempio un pezzo di codice) e facendo della mia arma vincente il copia/incolla :sunglasses: mi domandavo dove era possibile trovare un banalissimo esempio, da poter sviluppare poi io in maniera completa e dettagliata nelle varie esigenze!!!!

Ringrazio ancora per la disponibilità e per quello che voi esperti fate (superando spesso i limiti della pazienza XD) per noi neofiti! =)!

fikkiovarrikkio:
Se utilizzo il primo metodo che mi hai proposto, accade che (correggimi se sbaglio) nel momento in cui io accendo / spengo il led dopo la 256esima volta, nel momento in cui riaccendo l'arduino accade che, non esistendo più il valore "0" che mi hai suggerito tu (nel mio caso potrebbe essere "2" tanto per intenderci), l'arduino mi leggerà sempre il valore che ha usato nella prima scrittura poichè una volta finito il ciclo, tutti i valori sovrascritti saranno diversi da 0.

Quando vedi che addr1==255 vai ad azzerare tutte le prime 255 locazioni e ricominci dalla prima.

Nel codice, ti basta all'accensione (quindi nel setup) recuperare il valore di addr1 che sarà quello corrispondente all'ultima cella dove c'è un valore !=0 e poi quando devi andare a scrivere fai un addr1++ seguito da un
if (addr1==255) .... eccetera per rimediare.

Potresti anche seguire una strategia diversa, in modo da giungere il più tardi possibile alla locazione 255. Alla locazione addr1 scrivi un valore dispari = led acceso, pari = led spento e vai ad incrementare, appena arrivi a 255 incrementi addr1 e passi alla cella successiva. Quindi 1 = acceso, 2 = spento, 3 = acceso.... e così via.

Oppure, se fai tantissime variazioni e vuoi evitare di usurare la EEPROM, metti un FRAM I2C esterna.

Mi piace! Mi è tutto molto più chiaro con questo esempio!

Proverò a fare nel modo in cui mi hai suggerito e ti farò sapere se sono riuscito, magari postandoti un pezzo del codice!!!!

Grazie mille =) !

Buon pomeriggio!

Come promesso vi aggiorno nel merito:

ho provato la strategia propostami da Paulus.
Quando creo l'array, se quest'ultimo è abbastanza "piccolo" (ho fatto una prova con una dimensione di 20 celle per testarne la bontà), tutto funziona alla perfezione.
Quando invece creo l'array più grande, ed in particolare di 255 celle, capita che lo sketch viene caricato su arduino, il quale xo non risponde ai miei segnali!

La scheda non si dovrebbe mai resettare da sola... :slight_smile:
Per il blackout: se metti un condensatore di capacità sufficiente sull'alimentazione (attraverso un diodo) dell'atmega328, tale da mantenerlo funzionante per 1 secondo (ma anche molto meno), rilevando la mancanza di alimentazione hai ancora il tempo di salvare su EEPROM.
In un apparecchio a batteria che ho costruito ho messo l'interruttore di alimentazione che comanda un mosfet: quando spengo l'interruttore, lo spegnimento viene rilevato immediatamente dal microcontrollore, che salva lo stato sulla EEPROM; il condensatore sul gate del mosfet ritarda lo spegnimento dell'apparecchio per permettere lo svolgimento dell'operazione.

fikkiovarrikkio:
Buona sera a tutti!

Dopo un........

Ringrazio tutti per la disponibilità,
e buona programmazione a tutti =) !

Ferdinando

tutto dipende da quanto hai intenzione di campare :smiling_imp: quindi ...
metti che riscrivi la stessa memoria una volta al giorno tutti i santi giorni ti restano 273 anni
metti che riscrivi la stessa memoria tre volte al giorno tutti i santi giorni ti restano 91 anni