1

I am struggling through a program. I am trying to store my uploaded string into an array then write that array to EEPROM. I run the program, upload the new array and store it in the EEPROM. all values display correctly until I reset or power off the device. I am sure I am overwriting or something obvious, but i am breaking down and asking for help.

The read and write EEPROM subroutines are at the bottom of the code. I call the EEPROM_Write() in server.on after parsing the http get.

EDIT: per feedback, removed all but the function, with the EEPROM.commit(); suggestion included... still not working

void EEPROM_Write(){
Serial.begin(115200);
EEPROM.begin(280);
  // store values in EEPROM
  for (int i = 0; i < pwmarray1Size; i++)
  {
    Serial.println(pwmarray1[i]);
    EEPROM.put( EEPROMStartAdress + (i * sizeof pwmarray1[0]), pwmarray1[i]);
  }
  Serial.println();
  EEPROM.commit();
 // EEPROM.end();
}
1
  • what is EEPROMStartAdress? you can put the whole array in EEPROM with one 'put'
    – Juraj
    Jun 17, 2020 at 9:13

1 Answer 1

1

The ESP has no real EEPROM. Instead the EEPROM class for ESPs uses the flash memory. There is a difference in the implementations of this class between Arduinos and ESPs:

On an ESP every data, that you write, will first be placed in a buffer in RAM. You need to call EEPROM.commit() to actually write that data to the underlying flash memory.

So you need to add

EEPROM.commit();

to the end of your EEPROM_Write() function, or the data will stay in RAM and thus be lost on power cycle or reset.


I think your problem (besides the commit) lies not in your EEPROM_Write() function, but in the EEPROM_Read() function. If it doesn't work correctly, you are just not able to see, if the data gets written correctly. In your code (which can be seen in the edit history), you have this function:

void EEPROM_Read(){
   //load array pwmarray1 with stored values in EPROM
  for (int x = 0; x < pwmarray1Size; x++){
    EEPROM.get(EEPROMStartAdress + (x * sizeof pwmarray1[0]), pwmarray1[x]);
        Serial.print("loading program from EPROM: "); 
    Serial.println(pwmarray1[x]);
    }
}

While in EEPROM_Write() you are calling EEPROM.begin(280) every time, you don't EEPROM.end() it there and you are also not begin the EEPROM in the EEPROM_Read() function. I'm not sure about the underlying implementation, but it started to work for me, when I began and ended the EEPROM object in both functions.

I've written a test code, that I composed party of your code and that for me correctly saves and reads an array via the EEPROM object into the flash memory. It keeps the data over resets and power cycles just correctly. You can control it via Serial Monitor. Just type c (for clearing the array to zero), r (for reading the array from EEPROM/flash) or i (for incrementing all array elements and save them to EEPROM/flash).

#include <EEPROM.h>

#define EEPROM_SIZE 280

int array[60] = {0};
const unsigned arraySize = sizeof array / sizeof array[0];

#define EEPROMStartAdress 0

void setup(){
  Serial.begin(115200);
  Serial.println("///////////////////////////////////////");
  delay(2000);
}

void loop(){
  if(Serial.available()){
    char c = Serial.read();
    switch(c){
      case 'c':
        for(uint8_t i=0;i<arraySize;i++) array[i] = 0;
        EEPROM_Write();
        Serial.println("EEPROM RESET");
        break;
      case 'r':
        EEPROM_Read();
        break;
      case 'i':
        for(uint8_t i=0;i<arraySize;i++) array[i] += 1;
        EEPROM_Write();
        break;
    }
  }
}

void EEPROM_Write(){
  EEPROM.begin(EEPROM_SIZE);
  // store values in EEPROM
  for (int i = 0; i < arraySize; i++)
  {
    EEPROM.put( EEPROMStartAdress + (i * sizeof array[0]), array[i]);
  }
  EEPROM.commit();
  EEPROM.end();
}

void EEPROM_Read(){
  EEPROM.begin(EEPROM_SIZE);
  for (int x = 0; x < arraySize; x++){
    EEPROM.get(EEPROMStartAdress + (x * sizeof array[0]), array[x]);
    Serial.print(" ");
    Serial.print(array[x]);
    }
  Serial.println();
  EEPROM.end();
}

Removing begin() and end() from EEPROM_Read() and also end() from EEPROM_Write() gives me the same results, that you described as your problem.

8
  • the labels are misleading. I am using "put" and "get". can i use EEPROM.commit() after a put? Jun 15, 2020 at 10:59
  • 1
    put and get are just wrappers around write and read, that help you to write more complex data than single bytes. In the background the exact same is happening. So yes, you can use EEPROM.commit() after EEPROM.put().
    – chrisl
    Jun 15, 2020 at 11:04
  • I have added the EEPROM.commit() and still am not getting values stored in the EEPROM. Do you know if the "EEPROMStartAdress" location has any effect? Jun 15, 2020 at 13:02
  • ok, I have spent 30 hours staring and trying to make this work to no avail. i parsed down a test to a single number. posted the new question here: stackoverflow.com/questions/62415395/… Jun 16, 2020 at 18:49
  • I'm currently working on a test sketch, but as of now, my your function works with my ESP32. I will make complete a minimal functioning test sketch, that you can test with your board. Maybe I'm able to do this tomorrow evening. The EEPROMStartAdress just tells the function, where to start writing in the provisioned EEPROM. Should not make a problem.
    – chrisl
    Jun 16, 2020 at 20:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.