Friday, January 24, 2020

Permanent storage using EEPROM

For an index to all my stories click this line

I suppose this is something every reader of this weblog has ran into. You are making a project and you want to save some values of variables. Why ? Well every time your program restarts it starts with the initial values. But what if you want to continue where you left last time ?

An example is my Simon game. You can find that in the following blog-posts:
https://lucstechblog.blogspot.com/2018/12/simon.html
https://lucstechblog.blogspot.com/2018/12/simon-part-2.html

My girlfriend really likes this game. But it lacks something. It does not remember the high-score. So she wants me to build a new version with a display that shows the current high-score and the overall high-score.
The problem is that the Arduino, Attiny and the ESP microcontrollers erase their ram memory when they power down and restart. Therfore the overall high-score is never remembered.

The solution is to store the value of your variables in permanent memory.
When you do this, you can safely power down your project. Next time when you power it up again the project can read the values back from the permanent memory. This way your high score is stored safe.
You can use this for any kind of data you want to store permanent. Think about highest and lowest temperature readings, the last color settings of an RGB strip etc. etc.

The Arduino processors have a build-in EEPROM (Electrical Erasable Programmable Read Only Memory) and both the ESP8266 and the ESP32 have flash memory. Let's use that.

Arduino and Attiny85 EEPROM



The Arduino and Attiny processors have an internal EEPROM memory of 512 bytes. So they can store 512 values. As each of these 512 memory places is one byte they can each store a value from 0 to 255.
For the sake of this example I am going to show you how to save 10 values in EEPROM memory. Just look at this example program:



// ======================================
// test program for EEPROM write and read
// adapted by Luc Volders
// ======================================

#include <EEPROM.h>

int value = 0;
int i=0;

void setup()
{
  Serial.begin(9600);
  for (i=1; i<10; i++)
  {
    EEPROM.write(i, i+10);
    delay (100);
  } 
  
  for (i=1; i<10; i++)
  {
    value = EEPROM.read(i);
    Serial.print(i);
    Serial.print("\t");
    Serial.print(value, DEC);
    Serial.println();
  }
  
  
}

void loop()
{
}

I'll explain what is going on.

#include <EEPROM.h>

The first thing you need to do is to import the EEPROM library.

int value = 0;
int i=0;

Two helper variables are defined.

Then the real program is put in the setup. This way it runs only once.

Serial.begin(9600);

The Serial port is activated and we can check what is happening through the serial monitor.

  for (i=1; i<10; i++)
  {
    EEPROM.write(i, i+10);
    delay (100);
  }
 
This is where the magic happens.
The loop counts from 1 to 10. These are the EEPROM bytes where we are going to store our demo values. i is the location in the EEPROM memory where we are storing our values and i+10 is the value we are going to store. You can replace the i+10 value by anything you like as long as the value stays between 0 and 255.

  for (i=1; i<10; i++)
  {
    value = EEPROM.read(i);
    Serial.print(i);
    Serial.print("\t");
    Serial.print(value, DEC);
    Serial.println();
  }

After the values are stored we read them back with EEPROM.read(i). And i is again one of the memory places 1 to 10. The read value is then printed to the serial monitor to see if everything went well.

Now power down your Arduino or Attiny and upload the next program:


// ======================================
// test program for EEPROM read
// adapted by Luc Volders
// ======================================

#include <EEPROM.h>

int value = 0;
int i=0;

void setup()
{
  Serial.begin(9600);
  
  for (i=1; i<10; i++)
  {
    value = EEPROM.read(i);
    Serial.print(i);
    Serial.print("\t");
    Serial.print(value, DEC);
    Serial.println();
  }
}

void loop()
{
}

As you can see it is the same program as the previous but I omitted the writing part. So the only thing that happens is that the program reads the EEPROM memory and prints its values to the Serial monitor.



And this is the Serial Monitor output. As you can see even when the Arduino is powered down and a new program is loaded, the values stored in the EEPROM are still preserved.

ESP8266 and ESP32 EEPROM



Both the ESP8266 and the ESP32 do not have any build in EEPROM memory. But they do have flash memory. That is the same memory you are using in your photocam or phone and that does not looses its info when the power is shut down. So let's use that.

Luckily for us the Arduino EEPROM library has been adapted in such a way that it works for the ESP series controllers. We only have to make a minor adjustment in the program.


#include <EEPROM.h>

#define EEPROM_SIZE 100

int value = 0;
int i=0;

void setup() 
{
  Serial.begin(9600);
  
  EEPROM.begin(EEPROM_SIZE);

    for (i=1; i<10; i++)
  {
    EEPROM.write(i, i+10);
    EEPROM.commit();
    delay (100);
  } 


  for (i=1; i<10; i++)
  {
    value = EEPROM.read(i);
    Serial.print(i);
    Serial.print("\t");
    Serial.print(value, DEC);
    Serial.println();
  }
}

void loop() 
{
}


A short look at the differences from the Arduino program.

#define EEPROM_SIZE 100

For the ESP series we have to define how large the chunk of memory is that we want to put aside as an EEPROM substitute. Here I reserved 100 bytes but you can use as much as 4096 bytes. Quite a lot more as the Arduino allows you.

EEPROM.begin(EEPROM_SIZE);

This line tells the EEPROM library how much memory we want to reserve.

EEPROM.commit();

And this line actually confirms the write to the memory. You NEED to invoke this line after every write to the EEPROM memory.

The rest of the program is the same.

Write limits.

Both the EEPROM memory in the Arduino and the Flash memory in the ESP series have a limited lifespan. You can read as often as you want from the memory but you can write only about 100.000 times before the EEPROM breaks and your Arduino or ESP likely breaks down to.

100.000 times writing boils down to 273 year if you write once a day a value to the EEPROM or Flash memory. If you write a value each hour to the memory the controller will break down after 11 year. Writing every 10 minutes to the EEPROM or Flash memory will bring the lifespan of your controller back to about a year and a half.

Till next time
Have fun

Luc Volders