HELP Nodemcu EEPROM value after reboot lost

Hi, this is the first time I try to use the EEPROM, I was able to read the values ​​on port A0 by pressing the D6 button, but as soon as I restart I lose the value stored in the variable "valoremin ".

Can someone help me ?
Thanks.

BlynkTimer timer;
#include <EEPROM.h>

int val0 = 1;
int Livello = 0; // variabile di memorizzazione
int valoremin ; // valore minimo rilevabile
int valoremax = 200 ; // valore massimo rilevabile

void setup(){
Serial.begin(115200);
 EEPROM.begin(512);
 valoremin = EEPROM.read (0);
pinMode (D6,INPUT_PULLUP); //Pulsante
timer.setInterval(2000L, myTimerEvent);

}

void myTimerEvent(){

val0 = digitalRead(D6); // legge il valore dell'input
if (val0 == LOW) {
Serial.println("SCRITTURA EEPROM VALOREMIN");
valoremin = analogRead (A0);// acquisisce il segnale dal sensore A0
 EEPROM.write(0,valoremin );
delay (3000);
Serial.println("SCRITTURA EEPROM COMPLETATA");
delay (3000);}

Livello = analogRead (A0);// acquisisce il segnale dal sensore 
valoremin = EEPROM.read (0);
Serial.print ("Livello: = ");
Serial.print (Livello); // espone il livello sulla seriale

Livello = map(Livello, valoremin, valoremax, 0, 100);
Serial.print(Livello);

How frequently are you calling myTimerEvent ?

Posting snippets of code isn’t usually that helpful.

Pete.

You’re calling the timer every two seconds, but the function will take at least 6 seconds to complete because of the delays. Delays shouldn’t be used with Blynk, because they will cause disconnections.

Each EEPROM memory location has an average life of 100,000 read/write operations, so you could kill the EEPROM in a couple of days if you aren’t careful.

To solve this, SPIFFS was introduced, which treats the entire NVRAM memory as a disk, and does wear levelling and error checking to eliminate this issue.
SPIFFS has now been deprecated and replaced with LittleFS.

I’d suggest that you use LittleFS rather than EEPROM, and remove your delays.
When it comes to debugging your issue then you should add some serial prints so that you can monitor the values that you are reading and writing from/to the NVRAM.

Pete.

Pete.

@PeteKnight have you got any link or code that does this ?
Because i have searched a whole lot when i wanted to store few data like last state of relay and more. But i couldn’t find much code that can do that.

Whereas writing to EEPROM is much easy. Just mention the address and use read and write function. So easy.

But littleFs is like open dir, write, close. Open, read, close… i found this very confusing. So ended up with EEPROM AGAIN. EEPROM.UPDATE will help a bit when the data is same from previous.

I would request you to explain with a snippet
How to write a simple state of an LED to SPIFFS and read the same later.

Thank you in advance.

EDIT:

I know this is not blynk related :stuck_out_tongue_winking_eye:
But wanna learn from you .

To be honest, I have virtually no need for storing local variables because of the way that I use MQTT QOS and Node-Red.
I have used SPIFFS on one project, but it’s a project with lots of tabs and so not easy to share - and I never completed the project because I took a different approach in the end.

The file operations with SPIFFS (and the syntax for LittleFS is almost identical) makes sense to me, because its very similar to what I used to do in BASIC many many years ago.

The simplest approach is to write a couple of functions that accept parameters and return the results. One for reading data, and the other for writing. Pass the values that you want to write as a parameter and return the result, and with the read function simply specify the file and the variable you want to read.
Once you’ve created these functions you can re-use them in any sketch in future just by including the code.

Pete.

This sounds really interesting. I would really like to see the snippet code from your project.
I request you too share the SPIFF part of the code if you still have that in your folder. It would really help people like me who are using EEPROM right now.

Its a request, please post it when you are free.

I found what I think was my latest file on my cloud backup, so here are the raw snippets…

void start_spiffs()
{
  if (!SPIFFS.begin(true))
  {
    Serial.println("SPIFFS Mount Failed");
    // We ought to report the error to user !
    return;
  }
  
  listDir(SPIFFS, "/", 0);

  data_log = read_SPIFFS_file_into_variable("/Log_File.txt");
  //  Serial.println("data_log:");
  //  Serial.println(data_log);  

  available_version_number = read_SPIFFS_file_into_variable("/Last_Version_Number.txt").toInt();
  Serial.print("available_version_number = ");
  Serial.println(available_version_number);  

  next_table_row = read_SPIFFS_file_into_variable("/Next_Row_Number.txt").toInt();
  Serial.print("next_table_row = ");
  Serial.println(next_table_row);  
  write_to_SPIFFS_data_log_file(" ");
  write_to_SPIFFS_data_log_file("SPIFFS data read at startup complete");  
  write_to_SPIFFS_data_log_file(" ");
}


String read_SPIFFS_file_into_variable(String SPIFFS_filename) // Reads the data out of the specified SPIFFS file and returns it as a String
{
  int i;
  String temp_string ="";
  String value_to_return;
  
  //Read File data
  File f = SPIFFS.open(SPIFFS_filename, "r");

  if (!f)
  {
    Serial.println("file open failed - " + SPIFFS_filename);
    write_to_SPIFFS_data_log_file("file open failed - " + SPIFFS_filename);
  }
  else
  {
    // Read data from file
    for(i=0;i<f.size();i++) //Read upto complete file size
    {
      temp_string += (char)f.read();
    }
    f.close();  //Close file
    temp_string.trim();
    value_to_return=temp_string;
   }
  return value_to_return;  
}


void write_to_SPIFFS_data_log_file(String log_message) // Appends the specified message to the log file, with a new line
{
  File log_file = SPIFFS.open("/Log_File.txt", FILE_APPEND);
  if (!log_file)
  {
    Serial.println("Failed to open log_file for appending");
    return;
  }
  else
  {
    log_file.println(log_message);
    log_file.close();
  }
}


void clear_SPIFFS_data_log_file() // clears the log file
{
  if (!SPIFFS.remove("/Log_File.txt"))
  {
    Serial.println("Failed to delete log_file");
    return;
  }
  else
  {
    Serial.println("Log File cleared");
  }
}




void spiffs_first_time() // Formats the SPIFFS and writes desired values into each file
{
    if (!SPIFFS.begin(true))
    {
        Serial.println("SPIFFS Mount Failed");
        return;
    }
   SPIFFS.format();

  // File to store the last firmware vesion number that was read from the HTTP server
  File last_v_number = SPIFFS.open("/Last_Version_Number.txt", "w");
  if (!last_v_number)
  {
    Serial.println("File 'Last_Version_Number.txt' open failed.");
    return;
  }
  else
  {
    last_v_number.println("12344");
    last_v_number.close();
  }

  // File to store the next row number that will ne used for the Blynk action summary table
  File next_row_number = SPIFFS.open("/Next_Row_Number.txt", "w");
  if (!next_row_number)
  {
    Serial.println("File 'Next_Row_Number.txt' open failed.");
    return;
  }
  else
  {
    next_row_number.println("0");
    next_row_number.close();
  }


  // File to downloaded firmware image used for OTA update
  File ota_bin_file = SPIFFS.open("/OTA_Update_File.bin", "w");
  if (!ota_bin_file)
  {
    Serial.println("File 'OTA_Update_File.txt' open failed.");
    return;
  }
  else
  {
    ota_bin_file.println("");
    ota_bin_file.close();
  }

  // File to store the log file from the last wake cycle
  File log_file = SPIFFS.open("/Log_File.txt", "w");
  if (!log_file)
  {
    Serial.println("File 'Log_File.txt' open failed.");
    return;
  }
  else
  {
    log_file.println("");
    log_file.close();
  }
}

The code was designed to maintain a log file when doing deep sleep and HTTP OTA updates (which requires a disconnection from Blynk/MQTT), the log file data needed to be stored then reported next time, then it can be cleared. The read_SPIFFS_file_into_variable and write_to_SPIFFS_data_log_file functions were designed to do the reads and write functions like this…

data_log = read_SPIFFS_file_into_variable("/Log_File.txt");

write_to_SPIFFS_data_log_file("Your log file message here");

Void setup contains this…

    //spiffs_first_time(); // Only run to clear/populate the SPIFFS files
    start_spiffs();

Enjoy!

Pete.

1 Like

Thank you so much for giving time for searching and posting it here. I will definitely give this a try.
Thank you once again.

I solved
void myTimerEvent(){

valoremin = EEPROM.read (0);
it had to be added EEPROM.end() ;

Thanks.

EEPROM.write does not write to flash immediately, instead you must call EEPROM.commit() whenever you wish to save changes to flash. EEPROM.end() will also commit, and will release the RAM copy of EEPROM contents.

EEPROM library uses one sector of flash located just after the embedded filesystem.

Use to save:
EEPROM. put(0, variable);
EEPROM. commit();

and to read
EEPROM. get(0, varable);

1 Like

How can I avoid that the stored value is slightly different from the one read by the sensor?
example if the value stored in EEPROM is 149 and the reading detects 148 or 150 how do I correct to always detect 149?
I was thinking of something like this but I think it is not correct.

if ((valoremin <1 && valoremin >1)){valoremin = valoremin ;}

You wouldn’t adjust the value that is detected, you’d compare that to your stored value and if it was within your tolerance range you’d ignore the difference.

You can do this with a series of nested if statements.

Pete.

i’m trying like this but i can’t solve

if ((valoremin <2 && valoremin >2)){valoremin = EEPROM.get (0,valoremin);}

Livello = map(Livello, valoremin, valoremax, 0, 100);

If you want a tolerance of +/- one unit of measurement then something like this…

If (new_reading < (old_reading -1))
  {
   If (new_reading > (old_reading +1))
     {
       \\ write new reading to NVRAM
     }
  }

Pete.