Search code examples
arduinoesp32arduino-esp8266arduino-esp32

EEPROM with ESP32-WROOM-32


I bought an ESP32-WROOM-32 and I realize that there are some things which are not the same compared to Arduino Nano, Arduino Uno or Arduino Mega 2560.

One of the things that I realized which is different is how to store and read data from the controller. 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 my small projects with Arduino boards. The code consists of creating an OLED menu where I can navigate true pages and change integer values and these 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 integer values. The problem is that after switching OFF/ON the board, the values are not persisted.

I was already looking at some tutorials in the Internet about EEPROM and ESP32 and tried to implement it, but unfortunately without a 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 in 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();
  }
}

Solution

  • There is a file system that is very easy to use, called SPIFFS.

    If you are using the Arduino IDE you will find an example program named SPIFFS_test. It is pretty straightforward, showing how to open files, list directories and such.

    Menu FileExamplesExamples for ESP32SPIFFSSPIFFS_test

    The functions and how they are used are very similar, maybe even identical, to the standard C file system functions.