EEPROM in Arduino and ESP (ESP8266 and ESP32)

This article will explain what an EEPROM is and provide a brief overview of the other memories available in a microcontroller. You”ll also learn how to use EEPROM in Arduino and ESP microcontrollers (ESP8266 and ESP32).

Using the EEPROM put and EEPROM get functions, the software below illustrates how to read and write to EEPROM.

MEMORY USED IN MICROCONTROLLER

There are various types of memories, including Flash memory, cache memory, RAM, and EEPROM.

Flash memory

Flash memory is a type of memory that is used to store data that does not alter over time. Flash memory is known as Non Volatile memory. Permanent memory is another name for it.

In simple terms, the program you upload to the microcontroller as a hex file is saved in Flash memory. This is identical to the BIOS on a general-purpose computer.

You’re probably aware that the ATMEGA328 microcontroller used in the Arduino Uno has 32 KB of flash memory. In Arduino UNO (ATMEGA328), the number of write/erase cycles for flash memory is limited to an average of 10,000 cycles.

RAM

RAM stands for or you can say full form of RAM is Read Access Memory. SRAM (Static RAM) and DRAM (Distributed RAM) are the two types of RAM (Dynamic RAM).

All variables you use, such as int, float, and/or string, are open over RAM for calculation at the time of program execution.

char dataVar[17] = "This is some data";

17 bytes of SRAM will be allocated, and the text “This is some data” will be physically placed in FLASH memory. When device turned-on this FLASH-resident data is copied to SRAM, and the software accesses dataVar from SRAM whenever possible.

Many times, the scope of variables is limited to a single block, such as an if block or a for loop block. That is, when that particular block is executed, the variable will open in RAM and utilize some memory, but as the block is executed, the RAM memory will be freed up.

EEPROM

EEPROM stands for or you can say full form of EEPROM is Electronically Erasable Programmable Read Only Memory. EEPROM is also known as Non Volatile memory, which ensures the data is preserved even when the microcontroller is turned off.

In simple terms, EEPROM helps in to save the state of the outputs of an Arduino after a power outage or you can say, to save data after power off in Arduino.

It is, however, semi-permanent in the sense that data can be modified using software.

You’re probably aware that the ATMEGA328 microcontroller used in the Arduino Uno has 1024 Bytes (1 KB) of EEPROM memory. In Arduino UNO (ATMEGA328), the number of write/erase cycles for EEPROM is limited to an average of 100,000 cycles.

Using the EEPROM put and EEPROM get functions, you can read and write to EEPROM shown in the program below. In the following example, we’ll write int and string data to EEPROM and read them via serial input from the user.

ARDUINO EEPROM READ WRITE EXAMPLE CODE

/* This program is for EEPROM in Arduino,
   EEPROM concept in ESP (ESP8266 or nodeMCU and ESP32) is different
   https://pijaeducation.com/eeprom-in-arduino-and-esp/
*/

// include EEPROM Library
#include<EEPROM.h>

/* Defining addresses for data to store
   We know size of int is 2 Bytes in Arduino,
   If we store int at index 0 then the next EEPROM address can be anything (2,3..10 etc.) after 2 byte address i.e. (0-1)
  You can use this statement to find size of int type data Serial.println(sizeof(int)) 
*/
int eepromAddr1 = 0, eepromAddr2 = 10;

// int and string data which we store in EEPROM of Arduino Uno or Arduino Nano etc.
int intData = 1024, getInt;
String stringData = "My String", getStr;

// put means writing to EEPROM and get means reading from EEPROM
void setup() {
  Serial.begin(9600);
  // Message for user
  Serial.println("To put int Send → 'int' \nTo put String Send → 'string' \nTo get data Send → 'read'");
}

void loop() {
  if (Serial.available()) {
    String x = Serial.readString();
    delay(10);
    Serial.print("\nInput → ");
    Serial.println(x);

    /* if user send 'read' (can be any string of your choice) as input
        then we will read from EEPROM using 'EEPROM get' function
    */
    if (x == "read") {
      EEPROM.get(eepromAddr1, getInt);
      EEPROM.get(eepromAddr2, getStr);
      Serial.print("getInt:");
      Serial.println(getInt);
      Serial.print("getStr:");
      Serial.println(getStr);
    }
    /* if user send 'int' (can be any string of your choice) as input
        then we will write to EEPROM using 'EEPROM put' function
    */    
    else if (x == "int") {
      EEPROM.put(eepromAddr1, intData);
      Serial.println("intData write in EEPROM is Successful");
    }
    /* if user send 'string' (can be any string of your choice) as input
        then we will write to EEPROM using 'EEPROM put' function
    */    
    else if (x == "string") {
      EEPROM.put(eepromAddr2, stringData);
      Serial.println("stringData write in EEPROM is Successful");
    }
    /* if user send 'clear' (can be any string of your choice) as input
        then we will clear data from EEPROM
       This will take some time
    */
    else if (x == "clear") {
      for (int i = 0 ; i < EEPROM.length() ; i++) {
        EEPROM.write(i, 0);
      }
      Serial.println("EEPROM Clear Done!");
    }
    /* if user send any other string as input
        then display a message to user
    */
    else {
      Serial.println("Wrong Input");
    }
  }
}

EEPROM ARDUINO CODE EXPLANATION

EEPROM PUT

EEPROM.put() (Arduino EEPROM write anything) requires two parameters, one is the address, where you want to put the data, and other is the data, which can be int or string etc.

EEPROM.put(eepromAddr1, intData);

EEPROM GET 

EEPROM.get() (EEPROM read Arduino) also requires two parameters one is the address from which you want to get data and other parameter is the variable in which you want to store data. Variable must be of the same data type (int , String etc.).

EEPROM.get(eepromAddr1, getInt);

EEPROM WRITE TO CLEAR EEPROM

You can clear the entire EEPROM or only a portion of it whenever you want it to return to its original state. To clear the entire EEPROM, you must first calculate its length, after which you can use the EEPROM.write() function to clear all of the EEPROM’s indexes.

for (int i = 0 ; i < EEPROM.length() ; i++) {
  EEPROM.write(i, 0);
}

OUTPUT

EEPROM Arduino
EEPROM Arduino Output

ESP8266 EEPROM CODE

/*  This code is for the EEPROM in the ESP8266;
     the EEPROM definition in ESP32, Arduino Uno, Mega differs from that of the ESP8266.
    https://pijaeducation.com/eeprom-in-arduino-and-esp/
*/

// include EEPROM Library
#include<EEPROM.h>

/* Defining data storage addresses
   As we know size of int is 4 Bytes,
    If we store int at index 0 then the next EEPROM address can be anything (4,5..10 etc.) after 4 byte address i.e. (0-3)
 You can use this statement to find size of int type data Serial.println(sizeof(int))
*/
int eepromAddr1 = 0, eepromAddr2 = 256;

// We store int and String data in the ESP8266's EEPROM.
int intData = 1044;
String stringData = "My String";

// put is used to write to EEPROM, while read is used to read from it.
void setup() {
  Serial.begin(115200);
  /* Begin with EEPROM by deciding how much EEPROM memory you want to use.
     The ESP8266's maximum EEPROM size is 4096 bytes (4 KB), but we're just using 512 bytes here.
  */
  EEPROM.begin(512);
  delay(500);

  // User's message
  Serial.println("To put int Send → 'int' ");
  Serial.println("To put String Send → 'string' ");
  Serial.println("To get data Send → 'read' ");
  Serial.println("To clear EEPROM Send → 'clear' ");
}

void loop() {
  if (Serial.available()) {
    String x = Serial.readString();
    delay(10);
    Serial.println("");
    Serial.print("Input → ");
    Serial.println(x);

    /* If the user enters 'read' as input,
        we will read from the EEPROM using the 'EEPROM get' function.
    */
    if (x == "read") {
      /* We build a function eeprom_read_string(int),
          where we simply transfer an address to read from and it returns a string
      */
      String si = eeprom_read_string(eepromAddr1);
      /* After reading from EEPROM, convert String to int,
          - 4 is only to see whether it converted or not
      */
      int data = si.toInt();
      Serial.print("Readed Integer: ");
      Serial.println(data - 4);

      String ss = eeprom_read_string(eepromAddr2);
      Serial.print("Readed String: ");
      Serial.println(ss);

      delay(50);
    }
    /* if user send 'string' as input
        then we will write to EEPROM using 'EEPROM put' function
    */
    else if (x == "string") {
      EEPROM.put(eepromAddr2, stringData);
      eeprom_commit();
    }
    /* If the user enters 'int' as input, 
        we convert int to string since we created a function to read string from EEPROM 
        and then use the 'EEPROM put' function to write to EEPROM.
    */
    else if (x == "int") {
      String s = String(intData);
      EEPROM.put(eepromAddr1, s);
      // It's important to use EEPROM.commit() while writing to EEPROM.
      eeprom_commit();
    }
    /* if user send 'clear' as input
        then we will clear data from EEPROM
    */
    else if (x == "clear") {
      for (int i = 0 ; i < 512 ; i++) {
        EEPROM.write(i, 0);
      }
      // Don't forget EEPROM.end();
      EEPROM.end();
      Serial.println("EEPROM Clear Done!");
    }
    /* if user send any other string as input
        then display a message to user
    */
    else {
      Serial.println("Wrong Input");
    }
  }
}

/* Create a type String function that reads from EEPROM byte by byte,
   stores it in a char array, converts it to a string, and returns a String.
*/
String eeprom_read_string(int address) {
  char x[255], c;
  int i = 0;
  while (c != NULL) {
    x[i] = EEPROM.read(address);
    c = x[i];
    address++;
    i++;
  }

  String sr = String(x);
  return sr;
}

// Check whether write to EEPROM was successful or not with the EEPROM.commit() function.
void eeprom_commit() {
  if (EEPROM.commit()) {
    Serial.println("EEPROM successfully committed!");
  } else {
    Serial.println("ERROR! EEPROM commit failed!");
  }
}

EEPROM ESP8266 CODE EXPLANATION

EEPROM PUT

EEPROM.put() requires two parameters, one is the address, where you want to put the data, and other is the data, which can be int or string etc.

However, in ESP, we use String because we create a read function that returns a string and it will be more convenient for us. Once you write/put data you need to commit it (check next).

EEPROM.put(eepromAddr2, stringData);

EEPROM COMMIT

The EEPROM.commit() function is used to determine whether or not a write to EEPROM was successful.

EEPROM.commit()

EEPROM WRITE TO CLEAR EEPROM

You can clear the entire EEPROM or only a portion of it whenever you want it to return to its original state. To clear the entire EEPROM, you must find its length, after which you can use the EEPROM.write() function to clear all of the EEPROM’s indexes. Do not forget to end it (check next).

EEPROM.write(i, 0);

EEPROM END

When writing to EEPROM, use the EEPROM.end() function at the end to commit EPPROM. If you don’t use it, it won’t clear your EEPROM, so try reading with and without the EEPROM end() function.

 EEPROM.end();

EEPROM READ

The address from which you want to read data is the only parameter needed for EEPROM.read(). Since the EEPROM.read() function only returns single byte data, we use a for-loop to read data (character) until it is null and then store it in a char array. Then we converted it into a String and returns back.

EEPROM.read(address);

OUTPUT

EEPROM ESP
EEPROM ESP OUTPUT

ESP32 EEPROM CODE

/* This program is for EEPROM in ESP32,
   EEPROM concept in ESP8266 or nodeMCU and Arduino is different
   https://pijaeducation.com/eeprom-in-arduino-and-esp/
*/

// include EEPROM Library
#include<EEPROM.h>

/* Defining data storage addresses
   As we know size of int is 4 Bytes,
    If we store int at index 0 then the next EEPROM address can be anything (4,5..10 etc.) after 4 byte address i.e. (0-3)
  You can use this statement to find size of int type data Serial.println(sizeof(int))
*/
int eepromAddr1 = 0, eepromAddr2 = 10;

// int and string data which we store in EEPROM of Arduino Uno or Arduino Nano etc.
int intData = 1024;
String stringData = "My String";

// put means writing to EEPROM and get means reading from EEPROM
void setup() {
  Serial.begin(115200);
  /* Begin with EEPROM by deciding how much EEPROM memory you want to use.
    The ESP32's maximum EEPROM size is 4096 bytes (4 KB), but we're just using 512 bytes here.
  */
  EEPROM.begin(512);
  delay(500);

  // User's message
  Serial.println("To put int Send → 'int' ");
  Serial.println("To put String Send → 'string' ");
  Serial.println("To get data Send → 'read' ");
  Serial.println("To clear EEPROM Send → 'clear' ");
}

void loop() {
  if (Serial.available()) {
    String str = Serial.readString();
    delay(10);
    Serial.println("");
    Serial.print("Input → ");
    Serial.println(str);

    /* If the user enters 'read' as input,
        we will read from the EEPROM using 'readInt and readString' function.
    */
    if (str == "read") {
      int rInt = EEPROM.readInt(eepromAddr1);
      String rString = EEPROM.readString(eepromAddr2);
      Serial.println("Read from EEPROM");
      Serial.print("Int:");
      Serial.println(rInt);
      Serial.print("Str:");
      Serial.println(rString);
    }
    /* if user send 'int' as input
        then we will write to EEPROM using 'EEPROM.writeInt' function
    */
    else if (str == "int") {
      EEPROM.writeInt(eepromAddr1, intData);
      EEPROM.commit();
      Serial.println("intData write in EEPROM is Successful");
    }
    /* if user send 'string' as input
        then we will write to EEPROM using 'EEPROM.writeString' function
    */
    else if (str == "string") {
      EEPROM.writeString(eepromAddr2, stringData);
      EEPROM.commit();
      Serial.println("stringData write in EEPROM is Successful");
    }
    /* if user send 'clear' as input
        then we will clear data from EEPROM
    */
    else if (str == "clear") {
      for (int i = 0 ; i < 512  ; i++) {
        EEPROM.write(i, 0);
      }
      // Don't forget EEPROM.end();
      EEPROM.end();
      Serial.println("EEPROM Clear Done!");
    }
    // Provide a reply if the input does not match.
    else {
      Serial.println("Invalid Input");
    }
  }
}

EEPROM ESP32 CODE EXPLANATION

EEPROM BEGIN

Start with EEPROM by determining how much memory you’ll need.
The maximum EEPROM size on the ESP32 is 4096 bytes (4 KB), but we’ll only use 512 Bytes here. You can choose the size of according to your needs.

 EEPROM.begin(512);

EEPROM writeInt, writeString

The ESP32 EEPROM write function is somewhat different from the Arduino and ESP8266. EEPROM write functions in this allows us to write data in a variety of data types.

As their name implies, these functions make our work simpler. writeInt to save Integer type data and writeString to save string type data in EEPROM.

EEPROM.writeInt(eepromAddr1, intData);

EEPROM write() takes two parameters: the index or address and data (int, float, long, string, etc.).

EEPROM.writeString(eepromAddr2, stringData);

EEPROM COMMIT

The EEPROM.commit() function is used to determine whether or not a write to EEPROM was successful.

EEPROM.commit();

EEPROM WRITE TO CLEAR EEPROM

When you want to restore the EEPROM to its original state, you can clear the entire EEPROM or only a portion of it. To clear all of the EEPROM’s indexes, use the EEPROM.write() feature.

EEPROM.write() contains two parameters, the first of which is the index or address, and the second of which is 0. The use of a loop assists in the clearing of all indexes.

Remember to bring it to an end (check next step)

EEPROM.write(i, 0);

EEPROM END

When writing to EEPROM, use the EEPROM.end() function at the end to commit EPPROM. If you don’t use it, it won’t clear your EEPROM, so try reading with and without the EEPROM end() function.

EEPROM.end();

EEPROM READ

The only parameter for EEPROM.read() is the address from which you want to read data.

However, instead of read, you must choose the appropriate function based on the data saved.

For example, to read integer data, write

EEPROM.readInt(eepromAddr1);

and to read string data, write

EEPROM.readString(eepromAddr2);

OUTPUT

EEPROM ESP32
EEPROM ESP32 OUTPUT
5 1 vote
Article Rating
Subscribe
Notify of
guest
3 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
ahmet
ahmet
2 years ago

not working for esp8266
arduino ide 1.8.15

Waiter
Waiter
2 years ago

The Serial Monitor defauts to sending a New Line when the return key is clicked on the keyboard. To get this to work, I had to set my Serial Monitor to No Line Ending.

In the code, could probably strip out any linefeed carriage return characters in the “str” returned string.

3
0
Would love your thoughts, please comment.x
()
x