Save and Read Data from EEPROM with ESP32-WROOM-32

Beginner in Arduino and ESP-32 needs help.

I bought an ESP32-WROOM-32 and i realize that there are some things who are not the same comparing to Arduino Nano,UNO or Mega. One of the things that i realized who are diferent is how to store and read data from the controler. I want to save some data to EEPROM, to retain that value even when the device is switched OFF.

I have the following code that i use all the time in mine little projekts whit Arduino Boards. The code consist in creating a Oled Menu where i can navigate true pages and change Int values and this values are stored in the EEprom.

The same code i uploaded to the esp32 without any problem and the Menu works fine. I can change the Int values. The problem is that after switching OFF/ON the board the values are not persistence.

I Googled already for some tutorials in the Internet about EEprom with ESP32 and Preferences Library with ESP32 and tried to implement it , but unfortnally without result.

#include <EEPROM.h>
#include <OneButton.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 
#define SCREEN_HEIGHT 64 
#define DISP_RESET -1


const char*Vartext[] {"Data_0", "Data_1", "Data_2"};

const byte maxAnz = sizeof(Vartext) / sizeof(Vartext[0]);

const int mindata[maxAnz] {0, 0, 0};
const int maxdata[maxAnz] {10000, 200, 300};
uint32_t longstart;
byte Varindex;
byte Page = 0;
bool input;     
bool changed;     
bool datachanged ;

// data in struct to save on EEprom
struct mydaten {
  int VarData[maxAnz];
} mydata;

const byte pinsel = 16;    // select Button
const byte pinplus = 4;   // Plus Button
const byte pinminus = 5;  // Minus Button

OneButton Btnsel(pinsel, true);
OneButton Btnplus(pinplus, true);
OneButton Btnminus(pinminus, true);
Adafruit_SSD1306 DISP(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, DISP_RESET);

void setup() {
  Serial.begin(115200);

  EEPROM.get(0, mydata); // Read Data from EEPROM
  for (byte i = 0; i < maxAnz; i++) {
    checkminmax();
  }
  changed = true;

  Btnsel.attachClick(selClick);
  Btnsel.attachDoubleClick(selDblClick);
  Btnplus.attachClick(plusClick);
  Btnplus.attachDuringLongPress(plusDurPress);
  Btnplus.attachLongPressStart(LongStart);
  Btnminus.attachClick(minusClick);
  Btnminus.attachDuringLongPress(minusDurPress);
  Btnminus.attachLongPressStart(LongStart);

  DISP.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  DISP.clearDisplay();  
  DISP.setTextWrap(false);
  DISP.setTextSize(2);
  DISP.setTextColor(WHITE);
  DISP.setCursor(20, 30); DISP.print(F("Menu"));
  DISP.setTextSize(2);
  DISP.display();
  delay(2000);
}
//--------------------------------------
void loop() {
  Btnsel.tick();
  Btnplus.tick();
  Btnminus.tick();
  if (input)Displayinput();
  else Display(Page);
}
//--------------------------------------
void saveEEprom() {
  if (datachanged) {
    datachanged = false;
#ifdef debug
    Serial.println("Save in EEprom");
#endif
    EEPROM.put(0, mydata);
  }
}
//--------------------------------------
void selClick() {
  changed = true;
  if (input) {  
    Varindex++;
    if (Varindex >= maxAnz) Varindex = 0;
  }
  else { 
    Page++;
    if (Page >= 3) Page = 0;
  }
}
//--------------------------------------
void selDblClick() {
  if (input) saveEEprom(); 
  input = !input; 
  changed = true;
}

void plusClick() {
  click(1);
}
void minusClick() {
  click(-1);
}
void plusDurPress() {
  longclick(1);
}
void minusDurPress() {
  longclick(-1);
}
void LongStart() {
  longstart = millis();
}
void click(int inc) {
  if (input) {
    changed = true;
    datachanged = true;
    mydata.VarData[Varindex] += inc;
    checkminmax();
  }
}
void longclick(int direction) {
  static uint32_t oldtime;
  int inc = 10;
  if (millis() - longstart > 5000) inc = 100;
  if (millis() - oldtime >= 100 && input) {
    oldtime = millis();
    changed = true;
    datachanged = true;
    mydata.VarData[Varindex] += inc * direction;
    checkminmax();
  }
}

void checkminmax() {
  if (mydata.VarData[Varindex] < mindata[Varindex]) {
    mydata.VarData[Varindex] = mindata[Varindex];
  }
  if (mydata.VarData[Varindex] > maxdata[Varindex]) {
    mydata.VarData[Varindex] = maxdata[Varindex];
  }
}

void Displayinput() { // Display bei input
  if (changed ) {
    changed = false;
    DISP.clearDisplay();
    DISP.setTextSize(2);
    DISP.setCursor(0, 0); DISP.print("input");
    DISP.setCursor(0, 20); DISP.print(Vartext[Varindex]);
    DISP.setCursor(10, 40); DISP.print(mydata.VarData[Varindex]);
    DISP.display();
  }
}

void Display(byte Page) { 
  if (changed) { 
    changed = false;
    DISP.clearDisplay();
    if (Page == 0) { 
      DISP.setTextSize(1);
      DISP.setCursor(0, 0);
      DISP.print("variable Value");
      for (byte i = 0; i < maxAnz; i++) {
        byte row = i * 10 + 10;
        DISP.setCursor(0, row);
        DISP.print(Vartext[i]);
        DISP.setCursor(80, row );
        DISP.print(mydata.VarData[i]);
      }
    }
    else if (Page == 1) { 
      DISP.setTextSize(2);
      DISP.setCursor(0, 0); DISP.print("Page 1");
    }
    else if (Page == 2) { 
      DISP.setTextSize(2);
      DISP.setCursor(0, 0); DISP.print("Page 2");
    }
    DISP.display();
  }
}

Thanks in advance for some help

The ESP32 does not have an EEPROM use littleFS ( little File System) to store persistent data between boots.

1 Like

I could right now persist the valus with EEPROM.

I was missing one line of code.

EEPROM.commit();

I maked following changes on mine Code and it maintains the value after turning ON/OFF.

void setup() {
  Serial.begin(115200);

  EEPROM.begin(512);

  EEPROM.get(0, mydata); // Read Data from EE


void saveEEprom() {
  if (datachanged) {
    datachanged = false;
#ifdef debug
    Serial.println("Save in EEprom");
#endif
    EEPROM.put(0, mydata);
  }
  EEPROM.commit();
}

I read that the EEPROM library for the ESP32 is deprecated. New code should use the Preferences library or persist data using the filesystem.

Could somebody help with this using my code?
Thanks

1 Like

Thanks for your help and reply . Could you show me using my code how i would need to use littleFS?
Thanks

Words like "arduino esp32 little file system" in an internet search engine do not help?

1 Like
#include <Preferences.h>
Preferences prefs;

int dataStore[3] = {123, 456, 789};
int dataRetrieve[3];

void setup() {
  Serial.begin(115200);
  prefs.begin("IntegerArray"); //namespace
  prefs.putBytes("IntegerArray", (byte*)(dataStore), sizeof(dataStore));
  prefs.getBytes("IntegerArray", &dataRetrieve, sizeof(dataRetrieve));
  Serial.println(dataRetrieve[0]);
  Serial.println(dataRetrieve[1]);
  Serial.println(dataRetrieve[2]);
}

void loop() {}
3 Likes

I will take a look. Thanks for the help

Thanks for the example. I will try it out

I took your advice and googled "unhelpful response", but the only result was your screen name... :kissing_smiling_eyes:

2 Likes

That's cool.

I have been trying to do something similar. My device sleeps and wakes up with special keys, does operations like configurations and memory storage, and I was recently testing EEPROM read function to read and store variable data previously saved with the help of the EEPROM put function. It would always show an error, been looking for answers for two days.

So, that means, it is not even going to remember the values I asked it to store? That totally sucks. I now have to look to Preferences and LittleFS libraries like you had previously suggested me to.

Although with Preferences and LittleFS again comes the point about how much and in what way I can get control of what data I can store and utilise that. Specified storage about 215 bytes for configuration and rest for other. Sigh, I was almost finished with the device as well, and now it's like back to the drawing board. Espressif should say something in the lines like, "Hey, EEPROM is not going to retain the data you are so hopefully trying to read after you reboot the ESP32." Sigh * infinity.

No, both EEPROM.h and Preferences.h will store values which are retained through a shutdown/restart of an ESP32.

Please post some example code which demonstrates your problem.

It's not that, when I tried testing it before using 8192 as the epitome of storage for EEPROM, before it worked fine and I could read it without any problems.

Fairly recently, doing the same thing with EEPROM storage of 8192 was reading absolutely nothing and inverted questions marks would be returned upon what was read converted to char. It wasn't until I changed the size to 512 that it managed to give me correct read values. It didn't show any kind of error and over the course of reboots, worked normally, absolutely normally. Hence, I consider now 512 Bytes storage as epitome of EEPROM size that I can read and reach.

These 512 Bytes are very short for me, so I am looking forward to using Preferences and from what I can tell, there doesn't seem to be any info on its storage, whether it's more than 8 kB or not, except maybe one or two claiming one can save about 20 kB data on it, there is also issue with Preferences is that it is problematic in the case that the opened namespaces cannot be destroyed or there may not be a way to destroy that without erasing entirety of NVS partition. I could use LittleFS, but that requires a file system and that would just be an added problem, and also not sure how much it can store. Datasheet mentions the NVS storage is 20 kB and assumes and leaves the rest of these libraries storage for the users to figure out.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.