Go Down

Topic: EEPROM.h su architettura ESP8266 (Read 1 time) previous topic - next topic

Standardoil

Sono a cena, quindi non provo ma non è questione di cosa fa la write
Lei 'riceve' un byte
È il cast implicito da int a byte che casomai taglia via informazioni
Per togliersi il dubbio basta stampare una variabile byte dopo aver fatto un cast esplicito da una int
Se il dopocena non evolve nel senso giusta magari provo....
Prima legge di Nelson (che sono io): Non scambiare il fine con il mezzo: ricorda "cosa" devi fare, non "come" devi farlo

Non bado a studenti, che copino altrove

Tu hai problema-Io ti domando-Tu non mi rispondi: vuol dire che non ti serve più

droidprova

#16
Dec 06, 2018, 09:47 am Last Edit: Dec 06, 2018, 09:53 am by droidprova
Buondì, sto gestendo più di 100 posizioni di memoria, tutte poggiate su variabili byte usando questo sistema, e non ho problemi.
Code: [Select]

int addr = 0;
byte LU1ORAON;
byte LU2ORAON;
byte LU3ORAON;
byte LU4ORAON;

void setup(){
EEPROM.begin(512);
}

void loop(){

EEPROM.write(addr, LU1ORAON);
....
EEPROM.write(addr+3, LU4ORAON);

EEPROM.commit();
}


adesso siccome qualche variabile deve diventare del tipo float, immagino che le cose cambino e di molto. Da quel che ho capito, la eeprom.h scrive e legge un byte alla volta e difatti io nel mio programma non ho problemi proprio perchè tutte le mie variabili sono del tipo byte e anche volendo, non superano mai il valore di 255.
Ora siccome una variabile float occupa 4 byte, come la si scrive e come la si legge?
Grazie

Patrick_M

#17
Dec 06, 2018, 09:55 am Last Edit: Dec 06, 2018, 09:56 am by Patrick_M
leggendo 4 posizioni di memoria e combinandole assieme per formare il numero (sapendo qual'è la parte intera e quale la decimale) oppure moltiplicando ad esempio per 1000 il valore iniziale prima di memorizzarlo e dividerlo dopo il recupero....

p.s.

elimina il risolto dal titolo se andiamo avanti :D
per inserire (lo sketch) il programma, dall'IDE clicca modifica, clicca copia per il forum poi vieni qui e incolla nel tuo post (ctrl+v) ;)

gpb01

#18
Dec 06, 2018, 09:58 am Last Edit: Dec 06, 2018, 09:59 am by gpb01
Ora siccome una variabile float occupa 4 byte, come la si scrive e come la si legge?
... Ma impegnarsi un po' e studiare la libreria EEPROM proprio no ? ? ?  :smiley-evil:

Guarda la EEPROM.put() e la  EEPROM.get()  e troverai quello che ti serve!

Guglielmo

Search is Your friend ... or I am Your enemy !

droidprova

#19
Dec 06, 2018, 10:10 am Last Edit: Dec 06, 2018, 10:20 am by droidprova
Guglielmo, stavo leggendo gli esempi su gitub x quel che riguarda l'esp. E il metodo put e get non gli ho visti...

Adesso approfondisco e poi provo e intanto grazie x i link. Ho però un dubbio, essendo su piattaforma esp. dopo il put deve seguire sempre il commit?

E ancora: dall'esempio put:

Code: [Select]
float f = 123.456f;  //Variable to store in EEPROM.
  int eeAddress = 0;   //Location we want the data to be put.


  //One simple call, with the address first and the object second.
  EEPROM.put(eeAddress, f);


ma se float occupa 4 byte significa che la mia memoria sarà occupata in automatico su eeAddress 0,1,2,3 . Quindi per un eventuale float f2 successivo devo scrivere:

Code: [Select]
EEPROM.put(eeAddress +4, f2);

SukkoPera

La commit() va fatta quando vuoi effettivamente scrivere i dati su EEPROM. Immagina che la EEPROM.put() (e .write()) di fatto scrivano in un buffer in RAM che viene scaricato su EEPROM solo quando fai commit(). Quindi se devi fare tante write/put, le fai e ci metti una unica commit in fondo.

Per la seconda domanda la risposta è sì. Forse fai meglio a mettere tutti i tuoi dati in una struct e a scrivere/leggere quella.
"Code is read much more often than it is written, so plan accordingly. Design for readability."

Guida rapida a ESP8266: https://goo.gl/kzh62E

docdoc

Guglielmo, stavo leggendo gli esempi su gitub x quel che riguarda l'esp. E il metodo put e get non gli ho visti...
Beh nella libreria (EEPROM.h per ESP ovviamente) leggo questo:

Code: [Select]
template<typename T>
 T &get(int const address, T &t) {
   if (address < 0 || address + sizeof(T) > _size)
     return t;

   memcpy((uint8_t*) &t, _data + address, sizeof(T));
   return t;
 }

 template<typename T>
 const T &put(int const address, const T &t) {
   if (address < 0 || address + sizeof(T) > _size)
     return t;
   if (memcmp(_data + address, (const uint8_t*)&t, sizeof(T)) != 0) {
     _dirty = true;
     memcpy(_data + address, (const uint8_t*)&t, sizeof(T));
   }

quindi  direi che ci sono, se non erro sono implementate come template C++.

Quote
ma se float occupa 4 byte significa che la mia memoria sarà occupata in automatico su eeAddress 0,1,2,3 . Quindi per un eventuale float f2 successivo devo scrivere:
EEPROM.put(eeAddress +4, f2);
Eh certo. Ma come ha detto SukkoPera, fai prima a farti una tua struct e scrivere e leggere quella senza starti a dannare con questi calcoli.

Immagina che la EEPROM.put() (e .write()) di fatto scrivano in un buffer in RAM che viene scaricato su EEPROM solo quando fai commit().
Esattamente, ma senza condizionale, altrimenti lo confondi... :)
Di fatto nel begin() dici quanta RAM allocare per il buffer, quindi le varie write() e put() scrivono in questa RAM, e col commit() si scrive nella flash (non c'è fisicamente una EEPROM su ESP).
Alex "docdoc" - ** se ti sono stato d'aiuto, un punto karma sarà gradito, clicca su "add" qui a sinistra, vicino al mio nome ;) **

droidprova

qualcosa non va. Dunque invio questa stringa:

Gi11930-2030-23.5

e devo ottenere da codice che incollo 5 valori separati:

19, 30, 20, 30, 23.5

Code: [Select]

byte GI1ORAON;
byte GI1MINON;
byte GI1ORAOFF;
byte GI1MINOFF;
float t_set_gi1;

.....

else if (strncmp(stringa, "GI1", 3) == 0) { // GIOVEDI'

   

      strncpy(tmp, stringa + 3, 2); // Passo il puntatore al 2 carattere di stringa, e prelevo i caratteri necessari al confronto RTC nella funzione accensioni()
      tmp[2] = '\0';
      GI1ORAON = atoi(tmp);
      EEPROM.write(addr + 19, GI1ORAON);

      strncpy(tmp, stringa + 5, 2);
      tmp[2] = '\0';
      GI1MINON = atoi(tmp);
      EEPROM.write(addr + 20, GI1MINON);

      strncpy(tmp, stringa + 8, 2);
      tmp[2] = '\0';
      GI1ORAOFF = atoi(tmp);
      EEPROM.write(addr + 21, GI1ORAOFF);

      strncpy(tmp, stringa + 10, 2);
      tmp[2] = '\0';
      GI1MINOFF = atoi(tmp);
      EEPROM.write(addr + 22, GI1MINOFF);

      strncpy(tmp, stringa + 13, 4); // preleva valore temperatura
      //tmp[4] = '\0';
      t_set_gi1 = atof(tmp);//  e lo passa alla variabile
      EEPROM.put(addr + 23, t_set_gi1);

      EEPROM.commit();
      reply = "fascia oraria giovedì/1 memorizzata";
    }


con EEPROM.put(addr + 23, t_set_gi1); se stampo da seriale t_set_gi1 è zero, ovviamente con EEPROM.write(addr + 23, t_set_gi1); è 23.

Cosa sbaglio?

Patrick_M

Code: [Select]

GI1MINOFF = atoi(tmp);
      EEPROM.write(addr + 22, GI1MINOFF);


quanti byte è lungo un int?


e quindi dove devi scrivere il prossimo dato?

Code: [Select]
t_set_gi1 = atof(tmp);//  e lo passa alla variabile
      EEPROM.put(addr + 23, t_set_gi1);


per inserire (lo sketch) il programma, dall'IDE clicca modifica, clicca copia per il forum poi vieni qui e incolla nel tuo post (ctrl+v) ;)

droidprova

un int occupa 2 byte, ma tutti gli atoi generano sempre valori minori di 255, per questo penso che il tutto prima dell'inserimento dell'atof e dell'eeprom.put() abbia funzionato correttamente. Puoi spiegarti meglio?

Patrick_M

se il risultato è sempre un byte allora ok altrimenti essendo appunto un int 2 byte e scrivendo in posizione 22 la prossima posizione deve essere la 24 e non 23
soprattutto quando poi vai a leggerlo, se leggi un intero recupererai la posizione 22 e 23,
per inserire (lo sketch) il programma, dall'IDE clicca modifica, clicca copia per il forum poi vieni qui e incolla nel tuo post (ctrl+v) ;)

gpb01

>Patrick_M: basta che guardi il pezzo di codice al post #22 per vedere che:

Code: [Select]
byte GI1MINOFF;
... quindi UN solo byte, indipendentemente da quello che ci mette dentro ! ;)

Guglielmo
Search is Your friend ... or I am Your enemy !

gpb01

#27
Dec 07, 2018, 09:42 am Last Edit: Dec 07, 2018, 09:44 am by gpb01
>droidprova: ... perché non metti una Serial.println() dopo la conversione e prima della scrittura in EEPROM?

Code: [Select]
t_set_gi1 = atof(tmp); //  e lo passa alla variabile
Serial.println(t_set_gi1); // stampa il valore così puoi verificarlo
EEPROM.put(addr + 23, t_set_gi1);


Inoltre, perché qui non inserisci il terminatore ? ? ?

Code: [Select]
strncpy(tmp, stringa + 13, 4); // preleva valore temperatura
//tmp[4] = '\0';  // perchè è commentato?

Guglielmo

Search is Your friend ... or I am Your enemy !

Patrick_M

si hai ragione Guglielmo.... ma non sono andato a rileggere i precedenti :)
per inserire (lo sketch) il programma, dall'IDE clicca modifica, clicca copia per il forum poi vieni qui e incolla nel tuo post (ctrl+v) ;)

SukkoPera

#29
Dec 07, 2018, 10:21 am Last Edit: Dec 07, 2018, 10:21 am by SukkoPera
Ripeto:
Code: [Select]
struct Parametri {
  byte LU1ORAON;
  byte LU2ORAON;
  byte LU3ORAON;
  byte LU4ORAON;
  // ...
};

Parametri param;

void save() {
  EEPROM.put (0, param);
}


Ecc...
"Code is read much more often than it is written, so plan accordingly. Design for readability."

Guida rapida a ESP8266: https://goo.gl/kzh62E

Go Up