Go Down

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

gpb01

#30
Dec 07, 2018, 10:37 am Last Edit: Dec 07, 2018, 10:37 am by gpb01
Ripeto ...
... quella è sicuramnete la soluzione più pulita e semplice :)

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

droidprova

Grazie a tutti, forse ci sono, ho seguito il consiglio di Guglielmo di stampare la variabile prima della put.

Dopo aver sistemato il giusto numero di spazi qui:

Code: [Select]
strncpy(tmp, stringa + 13, 6); // preleva valore temperatura

e qui:

Code: [Select]

tmp[5] = '\0';


Ora ottengo il valore con virgola e lo vedo.

Poi per verifica ho stampato questo:

Code: [Select]
EEPROM.get(addr +23, t_set_gi1);
  Serial.println(t_set_gi1, 2);


E tutto combacia. Grazie mille!!!!

X Sukko, appena capisco bene questo passaggio e poi switcho sulle struct . Grazie mille


zoomx

L'ESP8266 può riservare un pezzo della flash per creare una sorta di memoria di massa, con un file system SPIFFS.
Puoi creare file e scriverci come fosse una SD.
Le EEPROM mi sembra una cosa da Ufficio Complicazione Affari Semplici, in questo caso.

droidprova

Grazie zoomx, che vantaggi ha praticamente lo SPIFFS rispetto alla gestione con EEPROM? E a tal proposito quale libreria consigli?

Grazie

zoomx

Che puoi creare file come ti pare, come se fosse un PC, l'unico limite è la dimensione.
La libreria è già inclusa nel core ESP9266 e la documentazione è qui
http://esp8266.github.io/Arduino/versions/2.0.0/doc/filesystem.html
ma ci sono diversi esempi in rete.
E' molto usata per gestire file da restituire via web.
Puoi anche usarlo per un log.

droidprova

#35
Dec 17, 2018, 08:27 am Last Edit: Dec 17, 2018, 08:28 am by droidprova
Buondì,

nel programma che sto finendo, faccio uso della #include <EEPROM.h>, e finchè non utilizzo il ciclo for per fare un canc della eeprom e sovrascrivere tutti i byte a zero va tutto bene. Appena faccio il canc poi non riesco più a gestire la memoria, è come se non memorizzasse più . A quel punto per far rifunzionare tutto devo riflashare il programma cancellando tutto. Perchè?


Code: [Select]


int addr = 0;
.....

for (addr = 0; addr < 512; addr++) {
        EEPROM.write(addr, 0);
      }
      delay(50);
      EEPROM.commit();



droidprova

Ragazzi ho bisogno di qualche spunto/input. Dunque sto costruendo un cronotermostato che dialoga con un bot di telegram per inviare e ricevere comandi e risposte.
Vorrei attraverso il comando PROG chiedere al bot il riepilogo della programmazione fatta in precedenza.

Esempio del codice che uso per comunicare con il bot:
Code: [Select]

String message = bot.message[i][5];
    message.toUpperCase();                         // rendo maiuscola tutta la stringa per evitare errori di sintassi
    message.toCharArray(stringa, 18);              // converto la stringa message nell'array stringa
    String reply;

.......
 
else if (strncmp(stringa, "PROG", 4) == 0) {     // chiede riepilogo programmazione
     
      reply = "Riepilogo programmazione";
    }




Tutti i dati inviati che compongono la programmazione settimanale, sono storati nella eeprom e all'occorrenza vengono letti e resi disponibili sotto rete locale cliccando sul link dell'indirizzo IP della schedina. A questo punto la schedina risponde con una pagina web. La pagina web è composta sostanzialmente da righe che leggono la eeprom:


Code: [Select]

.......

client.println("· Luned&igrave;:");                    // LUNED1'
    client.println("</br>");
    client.println("Fascia_1: ");
    if (EEPROM.read(addr + 15) < 10)  client.print('0');
    client.print(EEPROM.read(addr + 15), DEC);
    client.print(':');
    if (EEPROM.read(addr + 16) < 10) client.print('0');
    client.print(EEPROM.read(addr + 16), DEC);
    client.print(" / ");
    if (EEPROM.read(addr + 17) < 10)  client.print('0');
    client.print(EEPROM.read(addr + 17), DEC);
    client.print(':');
    if (EEPROM.read(addr + 18) < 10) client.print('0');
    client.print(EEPROM.read(addr + 18), DEC);
    client.print(" - ");
    client.print("T: ");
    client.print(EEPROM.get(addr + 19, t_set_lu1), 1);
    client.println("&deg;C");
    client.println("</br>");
    client.print("Fascia_2: ");
    if (EEPROM.read(addr + 23) < 10)  client.print('0');
    client.print(EEPROM.read(addr + 23), DEC);
    client.print(':');
    if (EEPROM.read(addr + 24) < 10) client.print('0');
    client.print(EEPROM.read(addr + 24), DEC);
    client.print(" / ");
    if (EEPROM.read(addr + 25) < 10)  client.print('0');
    client.print(EEPROM.read(addr + 25), DEC);
    client.print(':');
    if (EEPROM.read(addr + 26) < 10) client.print('0');
    client.print(EEPROM.read(addr + 26), DEC);
    client.print(" - ");
    client.print("T: ");
    client.print(EEPROM.get(addr + 27, t_set_lu2), 1);
    client.println("&deg;C");
    client.println("</br>");
    client.print("Fascia_3: ");
    if (EEPROM.read(addr + 31) < 10)  client.print('0');
    client.print(EEPROM.read(addr + 31), DEC);
    client.print(':');
    if (EEPROM.read(addr + 32) < 10) client.print('0');
    client.print(EEPROM.read(addr + 32), DEC);
    client.print(" / ");
    if (EEPROM.read(addr + 33) < 10)  client.print('0');
    client.print(EEPROM.read(addr + 33), DEC);
    client.print(':');
    if (EEPROM.read(addr + 34) < 10) client.print('0');
    client.print(EEPROM.read(addr + 34), DEC);
    client.print(" - ");
    client.print("T: ");
    client.print(EEPROM.get(addr + 35, t_set_lu3), 1);
    client.println("&deg;C");
    client.println("</br>");
    client.print("Fascia_4: ");
    if (EEPROM.read(addr + 39) < 10)  client.print('0');
    client.print(EEPROM.read(addr + 39), DEC);
    client.print(':');
    if (EEPROM.read(addr + 40) < 10) client.print('0');
    client.print(EEPROM.read(addr + 40), DEC);
    client.print(" / ");
    if (EEPROM.read(addr + 41) < 10)  client.print('0');
    client.print(EEPROM.read(addr + 41), DEC);
    client.print(':');
    if (EEPROM.read(addr + 42) < 10) client.print('0');
    client.print(EEPROM.read(addr + 42), DEC);
    client.print(" - ");
    client.print("T: ");
    client.print(EEPROM.get(addr + 43, t_set_lu4), 1);
    client.println("&deg;C");

.......


come posso accedere a tale marea di dati per consentire al reply di spedirmeli via bot così da abbattere il limite fisico della rete locale?

Grazie mille

docdoc

come posso accedere a tale marea di dati per consentire al reply di spedirmeli via bot così da abbattere il limite fisico della rete locale?
Come farei io? Lascerei perdere le scritture a livello di byte ed userei la struct, come consigliato all'inizio.
Alex "docdoc" - ** se ti sono stato d'aiuto, un punto karma sarà gradito, clicca su "add" qui a sinistra, vicino al mio nome ;) **

droidprova

Riprendo l'argomento, devo gestire una struct:

Code: [Select]
// struct dati
struct prog {
  int a = EEPROM.read(addr + 15);
  String string1 = ":";
  int b = EEPROM.read(addr + 16);
  String string2 = "-";
  int c = EEPROM.read(addr + 17);
  String string3 = ":";
  int d = EEPROM.read(addr + 18);
  String string4 = "/";
  float e = EEPROM.get(addr + 19);
  String string5 = "°C";
};
struct prog PROG;



una volta dichiarata, come si gestisce per stamparla e far si che dalla libreria di telegram la si possa inviare come risposta?

SukkoPera

#39
Feb 01, 2019, 06:09 pm Last Edit: Feb 01, 2019, 06:09 pm by SukkoPera
Erm, no, devi separare dichiarazione e utilizzo:

Code: [Select]
// struct dati - Qui definisci solo come è fatta la struct, ovvero quali campi contiene
struct prog {
  int a;
  String string1;
  int b;
  String string2;
  int c;
  String;
  int d;
  String string4;
  float e;
  String string5;
};

struct prog PROG; // Qui definisci una variabile PROG di tipo prog, che dunque contiene tutti i campi di cui sopra. Nota che "struct" è opzionale in C++

void setup() {
  // Qui (o ovunque tu voglia) riempi i singoli campi della struct
  PROG.a = EEPROM.read(addr + 15);
  PROG.string1 = ":";
  PROG.b = EEPROM.read(addr + 16);
  PROG.string2 = "-";
  PROG.c = EEPROM.read(addr + 17);
  PROG.string3 = ":";
  PROG.d = EEPROM.read(addr + 18);
  PROG.string4 = "/";
  PROG.e = EEPROM.get(addr + 19);
  PROG.string5 = "°C";



Per stamparla lo devi fare un campo alla volta, come fossero tante variabili separate. Ma la cosa bella è che ora puoi fare:

Code: [Select]
EEPROM.put(0, PROG);

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

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

droidprova

Grazie mille Sukko. Speravo in un modo veloce x stampare tutta la struct in un colpo solo. Peccato!

droidprova

#41
Feb 14, 2019, 12:07 pm Last Edit: Feb 14, 2019, 12:08 pm by droidprova
Dunque con libreria EEPROM.h su esp8266 (core 2.4.2) , se aggiorno il codice da IDE arduino (vers. 1.8_8) usando la modalità di cancellazione "dati + sketch" tutte le celle di memoria (ne uso 246) a seconda del tipo di dati si inizializzano così:

variabili int - > 255
variabili float -> nan

Ciò non è necessariamente un guaio in quanto durante il normale funzionamento del progetto, è previsto di  storare manualmente i vari valori, che ne so spedendoli via telegram. In questo caso il tutto funziona bene. Nelle celle di memoria indipendentemente se abbinate a variabili int o float, vengono salvati i giusti valori.

Il problema resta solo al primo avvio e solo su alcune variabili che in automatico fanno dei cicli di lettura e memorizzazione, in questo caso se la cella restituisce nan, il resto del codice viene eseguito male. A esempio, queste sono delle righe che fanno da contaore:

Code: [Select]

if ((digitalRead(rele) == LOW) && (onetime_2 == true)) {  // uso il flag onetime_2 per eseguire il codice una volta sola
    onetime_1 = true; // reset flag conta accensioni
    conta_ore_now = ((millis() - tempo_0) / 3600000) + EEPROM.get(addr + 243, conta_ore_mem);  // in ore
    conta_ore_mem = conta_ore_now ;
    EEPROM.put(addr + 243, conta_ore_mem);
    EEPROM.commit();
    onetime_2 = false;  // preparo il flag per una nuova lettura
  }


Vi chiedo:

1. perchè le celle vengono inizializzate così
2. e se ci fosse eventualmente un modo per aggirare il problema

Io ho provato a risolvere formattando la memoria con un clear:

Code: [Select]
for (int addr = 0; addr < 512; addr++) {

    EEPROM.write(i, 0);
  }


ecco, subito dopo questo comando, nessuna cella fa più il suo compito, devo riflashare tutto cancellando anche i dati. Why?


SukkoPera

Su ESP in realtà la EPROM non esiste, è emulata in una porzione di flash, per cui la stai cancellando, se selezioni "DATI + sketch" (Una cella vuota legge 255 - tutti i bit a 1 insomma -, non 0 come forse ti aspetti, e un float fatto di tutti 1 non è la rappresentazione valida di un numero, ovvero "Not a Number": NaN). Se c'è una modalità per cancellare solo lo sketch, è quella che ti serve.

In ogni caso sarebbe bene fare una validazione di quello che leggi dalla EPROM (tipo un CRC) e, se questa fallisce, inizializzare tutto a dei valori di default.
"Code is read much more often than it is written, so plan accordingly. Design for readability."

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

droidprova

Ah. Capisco...più o meno

ma nella fattispecie, questo esempio che fa:  https://www.arduino.cc/en/Tutorial/EEPROMCrc

SukkoPera

Qualcosa del genere, ma usando delle funzioni della AVR libc che rendono il tutto più semplice ;).
"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