Arduino EEPROM Tips & Tricks

Last week I spent most of my leisure time studying nonvolatile memory chips. The result was a better understanding of Arduino’s EEPROM. This might look like novice work, but I hope my thoughts will help you to play with Arduino EEPROM easily!

Arduino & Internal EEPROM

An EEPROM (electrically erasable programmable read-only memory) allows you to permanently store little amounts of data. This is very useful for saving user settings or hoarding small data sets where you need to retain vital data even if the power is turned off. Almost all Arduino microcontroller boards have EEPROM memory build inside the core chip, so no extra hardware is needed for small data retention and retrieval.

Reading does not stress the EEPROM but each writing does stress the memory. Eventually it will become less reliable. The EEPROM is specified with a write endurance of 100,000 cycles. This limit point is not a serious matter if you write to the memory infrequently.

In Arduino Uno, the EEPROM space can store up to 1024 bytes. A single byte can store 8 bits of information, and 8 bits can store a number from 0 to 255. In the Arduino IDE versions prior to 1.6.2 you only had access to read, write, and update which only supported reading or writing to only one Byte at a time. However, from Arduino IDE versions above that you can see these two commands get (similar to read) and put (similar to update). Simply, the new commands will still work when using numbers smaller than 255 but you need to call the new commands if the number is bigger than 255 (reference https://www.brainy-bits.com/eeprom-arduino/).

There are many applications where EEPROM memory is useful. Let us begin.

Storing a value to EEPROM

Now you are going to write two values ​​in the EEPROM.

[code]

#include <EEPROM.h> // EEPROM library

void setup() {

EEPROM.write(0, 1); // Number 1 at address 0

EEPROM.write(1, 2); // Number 2 at address 1

}

void loop() { }


[/code]

Here, do not try to write multiple values ​​on the same address because you’ll lose the value saved before (unless that’s what you want to do)!

Reading a value from EEPROM

After you have stored some values ​​to the EEPROM, you can then reboot your Arduino or simply reset your program. The saved values ​​will still be there and reading them is easy.

[code]

#include <EEPROM.h>

void setup() {

Serial.begin(9600);

int value1 = EEPROM.read(0); // Read address 0

Serial.println("Address 0 Value:");

Serial.println(value1);

int value2 = EEPROM.read(1); // Read address 1

Serial.println("Address 1 Value:");

Serial.println(value2);

}

void loop() { }

[/code]

Look, the 100K times rule is applicable only for writing (and erasing). So, you can read from EEPROM as much as you want without any issue!

EEPROM Read & Write Test

This is a pretty cool Arduino EEPROM read/write test code I found in GitHub written by Ted Hayes (ted.hayes@liminastudio.com). Put a momentary button switch between D11 and GND headers on your Arduino board, upload the code provide below to it, and open the serial monitor. Finally follow the instructions to use the reset switch and momentary button switch!

[code]

#include <EEPROM.h>


#define PIN_SWITCH 11


int lastSwitch = HIGH;

boolean didReset = false;


void setup() {

  Serial.begin(9600);

  pinMode(PIN_SWITCH, INPUT);

  digitalWrite(PIN_SWITCH, HIGH);


  int val = EEPROM.read(0);

  Serial.print("Starting; current EEPROM value is ");

  Serial.println(val);


  if (val != 1) {

    Serial.println("EEPROM byte not set yet; Writing...");

    EEPROM.write(0, 1);

  } else if (val == 1) {

    Serial.println("EEPROM byte was set!");

  }

  Serial.println("Done!!");

}


void loop() {

  int currentSwitch = digitalRead(PIN_SWITCH);

  if (currentSwitch == LOW && lastSwitch != currentSwitch && !didReset) {


    Serial.println("Resetting EEPROM value");

    EEPROM.write(0, 0);

    didReset = true;

  }

}

[/code]




I learned something insightful from all of this! How do you feel?

Servo Retentions

Well, the EEPROM is the little space in chip memory where some data can be stored in the Arduino/ATmega328 even after power down. This seems fabulous! As another example of using EEPROM to help the user, say that you turn your Arduino into the heart and mind of a servo-based actuator, for example an electronic door lock or an automatic pet feeder. One of the annoying things when using a servo with Arduino is the setup impulsions every time you cycle the power supply. In other words, the attached servo will move to its default position (but perhaps not exactly). Since Arduino Uno/Nano allows you to access 1024 memory slots that will subsist while it is powered off, you can store the position of the servo in the EEPROM to avoid the thwarting ‘reference point drift’.

I was not alone in this train of thought. I am going directly to an adapted code proved to be perfect to propel the attached servo in a predefined angle and store the end position every time the travel is initiated. When the setup is switched on, the servo is not moved to a default position. It first checks if there is a viable value in the nonvolatile memory and if so, it will use that as the starting value for the servo (Thanks to Carles Flotats, Tinkering Arduino Blog).

[code]

#include <Servo.h>

#include <EEPROM.h>

Servo myservo;

int switchPin =8; // Button switch input pin D8

int val;

int moveDegrees=20; // Degrees to turn for every button push

int memoryPos=4; // Memory location to store the position

void setup()

{

val=EEPROM.read(memoryPos); // Read the saved position

if (val < 20 || val > 160){ // If it is not a valid position

val=20; // Assign a default value

}

//Serial.begin(9600);

pinMode(switchPin, INPUT);

digitalWrite(switchPin,HIGH); // Enable internal pull-up

myservo.attach(9); // Servo signal pin D9

myservo.write(val); // Move to the stored position

}

void loop()

{

//Serial.println(digitalRead(switchPin));

while(digitalRead(switchPin)){

delay(10);

}

val=val+moveDegrees; // Increase the position

//Serial.println(val);

myservo.write(val); // Set the servo position

EEPROM.write(memoryPos, val); // Save the current position

delay(500); // Wait for servo to get there

if (val == 20 || val == 160) { // If the servo is at the end

moveDegrees = -moveDegrees ; // Change the movement direction

}

}

[/code]

For the quick experiment, I carelessly powered my Tower Pro SG-90 micro servo from the Arduino 5V header pin rather than using a separate power source. Anyway, it is extremely risky going to follow my dirty practice because of the limits of Arduino’s onboard voltage regulator!

Wrapping Up

In this article I discussed about using the built-in EEPROM to store nonvolatile data on the Arduino. It is undoubtedly a very easy and effective way of storing data on the Arduino with zero external hardware. The internal EEPROM only offers limited bytes of storage space. I am still new at this game myself, so I will stop here. If you have any hints of your own, do not hesitate to post a comment. If you have found this post useful please share it to help others discover it.

In the next room, my favorite Arduino board is ready and waiting for a nice meet with an external EEPROM module. A while ago I picked up a couple of 24C256 I2C EEPROM modules to get some more external memory enough for some data-logger projects. In my upcoming post I will show how to start a newfangled play with an EEPROM chip or an EEPROM module. So, stay tuned!

Leave a Comment