Arduino EEPROM

The Arduino EEPROM (Electrically Erasable Programmable Read Only Memory) is a high endurance Flash memory block. It is dedicated to saving data between sessions (power down and power up of the microcontroller).

How to use Arduino EEPROM to store data between power ups

The EEPROM memory on a microcontroller can serve two very useful calibration purposes.

First, it allows storing calibration parameters so they don't need to be re-done each time the microcontroller restarts. For example, you could save the calibrated offset value for an MCP4922 DAC that is being used with an opamp. Then on restart, it would load the stored value and maintain the calibration.

Second, the EEPROM can hold user-entered data so it doesn't get lost on restart. For example, if your program prompts the user to input various configuration settings, you could store those entries in the EEPROM. Then when the program launches again later, it can load the saved data from EEPROM rather than making the user re-enter all the configuration each time. This provides a nicer user experience by preserving their previous inputs.

Flash Types

There are two rewritable memory types on a microcontroller that are useful to compare: Flash memory and EEPROM.

Flash memory is where the microcontroller program code is stored. It can be re-written, such as when downloading a new program to the Arduino. However, Flash memory has a lower rewrite capability compared to EEPROM. Over time, repeated rewriting of Flash will cause wear and eventual failure.

In contrast, EEPROM (electrically erasable programmable read-only memory) has a much higher maximum rewrite cycle count. It is well-suited for saving calibration constants or other data that needs to persist between runs of a program without wearing out over many rewrite cycles.

On this page your can find out how to preserve the life of EEPROM as well as sketches showing how to save and restore multiple data elements.

There are two rewritable memories and it is useful to compare their capabilities. The Flash memory area of the microcontroller (that stores your program) is capable of being re-written (when you download a new program to the Arduino!). This memory, however, has a lower rewrite capability:

Flash lifetime

A useful thing to do, is to see how long normal Flash memory will last if you write to it 10 times per day. It turns out that it will last at least 10000.0/10.0 = 1000 Days or 2.7 years). Of course you won't update a program every day and you will use a new device for new projects, so it will last far longer than that.

EEPROM lifetime

The EEPROM is far better. For the same example of writing it 10 times a day the EEPROM life will be

100000/10 # 10000 Days or 27 Years!

How to preserve EEPROM

I was once at a firm that managed to have their units randomly fail.

The EEPROM was being written continuously to the same location to save data as parameters changed. The problem was that the data was always written every time round the program loop, so even with the huge lifetime of the EEPROM it was written so much that the EEPROM wore out.

The solution they chose was to move the starting write address after every block of data was written so that the same area of EEPROM was not continuously used; Extending the life of the EEPROM.

A better way is to make sure you only write to the EEPROM at a defined time. For instance if a user starts a calibration sequence - only write it once after that has ended. Alternatively update parameters on brown-out detection or power down initiation.

Never write to the same address in EEPROM memory from within a for loop!

Warning: Don't make your program continuously write to EEPROM.

Note: Reading from the EEPROM does not degrade the memory. You can read an EEPROM address as many times as you want.

TIP: To extend EEPROM life first read the contents to be written - if it is the same as the value you want to write, then don't write to it! - See functions update() and put() that perform a Read-Before-Write.

TIP: Each time you write a set of data - read it back to ensure it was written correctly. If it fails then retry. If there are multiple failures then generate an error e.g an message to a screen or light a red LED.

A write of one byte takes 3.3ms [source Arduino documentation] - however it seems faster (see output from programs below).

Arduino EEPROM functions

EEPROM Read and Write Bytes

The basic unit of an EEPROM transaction is a byte. To read and write these bytes you can use the following functions:

EEPROM Write a Changed byte

 This function will only perform a write operation if the current value is not the same as bytevalue. So it saves you from wearing out EEPROM if you try and write the same byte to the EEPROM.

Really, this is the function you should use to preserve the EEPROM memory. The only reason not to do so, is that it must perform a read first so it will be slower than an EEPROM.write operation.

EEPROM Write Standard type or Structure

It is Ok writing bytes, but there's an easier way to write a set of data to the EEPROM and that us by using the put() function (get is the equivalent for retrieval).

The put function writes out a set of bytes using the update function. In addition it measures the size of the data type being used to write out the correct number of bytes.

You can use this function to write out an char, int, long or float type object without knowing the number of bytes used by the type object. So this function is portable across different compilers (that use different type sizes).

The really useful point about this function is that it can also write out your own defined types e.g. if you create a struct type (with lots if variables inside) then it will write a variable of this type to EEPROM without you having to know the number of bytes that the type occupies.

The upshot is, if you bundle your data into a structure then it is easy to put and get it, to and from EEPROM.

Multi variable EEPROM read/write

The previous member functions are useful for writing single bytes or single struct objects to/from EEPROM but quite often want to switch between sets of data (or store more than just a single variable).

This is especially useful for a system where you are trying out different options (and you don't want to recompile each time just to change a few control parameters!).

You just want to select from a set of previously saved data.

Single Type Method Sketch1

The Idea here is to store a set of simple type variables sequentially in the EEPROM at a specific EEPROM address.

Just attach a push button connected to ground and pin 5 of the Arduino. On start up the EEPROM values are retrieved from the EEPROM and sent to serial Monitor.

When you push the button random values are saved to the EEPROM. To retrieve the values simply press the reset button on the Arduino and these same numbers are displayed (having been read from the EEPROM).

When you hit the button you can also see write execution time.

 #define BUTTON_TEST 5 #define EEADDR 166                                                                                               <span Write time (us) "  <span Write time per byte (us) "        
Here's an example of the output from the serial monitor:
Press button to write to EEPROM EEPROM Written MIN x 58478 MAX x 58479 MIN y 58480 MAX y 58481 EEPROM Write time (us) 23300 EEPROM Write time per byte (us) 2912 Press button to write to EEPROM Press button to write to EEPROM Press button to write to EEPROM Press button to write to EEPROM EEPROM variable read and write. MIN x 58478 MAX x 58479 MIN y 58480 MAX y 58481 Press button to write to EEPROM

The lower text beginning 'MIN X' is the read-back output after hitting the reset button. The first one is the 'write action' after hitting the push button.

Struct type Method Sketch2

The Idea here is to use a structure to store data at a specific EEPROM address.

Using a struct object allows you to group variables together and use the EEPROM.put() and get() to access the EEPROM. These functions make it trivial to store and retrieve the structure data to/from the EEPROM.

The following program is very similar to the above but uses a struct variable instead of lots of different ones. Note how you could use multiple struct variables in the program since pointers are used to display the contents of the struct variable 'StoreData'.

 #define BUTTON_TEST 5 #define EEADDR 166                                                                                                       <span Write time (us) "  <span Write time per byte (us) "        Here an example of the output from the serial monitor:
Press button to write struct to EEPROM EEPROM Written Kp -4639.00 Ki -4638.00 Kd -4637.00 dt -4636 LR -4635 LP -4634 EEPROM Write time (us) 46596 EEPROM Write time per byte (us) 2588 Press button to write struct to EEPROM Press button to write struct to EEPROM Press button to write struct to EEPROM Press button to write struct to EEPROM Press button to write struct to EEPROM Press button to write struct to EEPROM Press button to write struct to EEPROM EEPROM struct read and write. Kp -4639.00 Ki -4638.00 Kd -4637.00 dt -4636 LR -4635 LP -4634 Press button to write struct to EEPROM

The top data is displayed after pressing the button while the lower data is displayed after pressing reset on the Arduino.

Note: Write times will vary if the same data is detected in the EEPROM. For accurate timing use the write function (you would write your own version of put() that does not perform a read).

Frequently Asked Questions

How to reset an EEPROM.

The EEPROM can be erased during programming using the chip erase function.

The EEPROM does not really need resetting since it stores whatever was programmed into it (there is no EEPROM reset operation). You are probably wanting to initialise it.

One way is to perform a write to EEPROM during normal program operation - or use a button input to indicate rewrite (as in above programs - but choose another button).

Alternatively create a separate sketch and loop 0 to 999, write each byte as 0xFF.

Note: The erased state of the EEPROM is 0xff.

How to clear Arduino EEPROM.

You have to to write to it as above or use the chip erase function (during serial programming).

How to erase Arduino EEPROM.

Arduino EEPROM vs Progmem

As described earlier, Flash memory (PROGMEM) has a lower lifetime than EEPROM. So EEPROM is useful for data that should be stored between sessions (or logged in a data logging application).

Arduino EEPROM vs Flash

Arduino EEPROM vs SD card.

The advantage of an EEPROM is that it is fast .
The disadvantage of an EEPROM is that it is small (1k Byte)

The advantage of an SD card is that it is huge (Giga Bytes).
The disadvantage of an SD card is that it is slow.
The disadvantage of an SD card interface is that it needs a RAM buffer (probably 2 of about 512 bytes of SRAM each).

The SD card takes time to write - hence the need for a double buffer. One buffer is updated while the other is written.

Comparisons of EEPROM member functions

Arduino EEPROM put vs update

update() operates on a single byte.
It reads, and then writes to an address only if the byte is different.
This is the byte primitive function used by put().

put() writes multiple bytes starting from an address.
The number of bytes written is the size of the type.
put() uses the update function
(which only overwrites data if it has changed - to preserve memory).

Arduino EEPROM update vs write

update() operates on a single byte.
It reads, and then writes to an address only if the byte is different.
This is the byte primitive function used by put().

write() operates on a single byte.
It writes a single byte to an address.

Arduino EEPROM get vs read

read() operates on a single byte.
It reads a single byte from an address.

get() reads multiple bytes starting from an address.
The number of bytes read is the size of the type.

Arduino EEPROM write vs put

write() operates on a single byte.
It writes a single byte to an address.

put() writes multiple bytes starting from an address.
The number of bytes written is the size of the type.
put() uses the update function
(which only overwrites data if it has changed - to preserve memory).

Conclusions

The Arduino EEPROM library provides easy access to read and write the EEPROM memory. The examples in this page show you how to write individual bytes as well as complete structured data to EEPROM memory.

In this page you found out that the Arduino EEPROM can be extremely useful in your projects. It allows you to save data between power cycles, allowing parameters, calibration values and other settings to persist for your projects.

Through the examples and explanations, you saw how to read and write single bytes as well as structures containing grouped data to sequential EEPROM addresses. The put() and get() Arduino EEPROM functions let you store and retrieve structured data very easily and actually stop too many EEPROM writes in a limited way - they do a pre-read to make sure the data is new.

Tips were provided on how you can maximize EEPROM lifetime through techniques like delaying writes and avoiding consecutive overwriting of addresses in your code. Comparisons to flash memory highlighted EEPROM's significantly higher rewrite endurance for your use.

The provided examples demonstrate the core EEPROM programming techniques you can use - from saving and retrieving simple variables, through to saving and retrieving complete structured data.

This provides you with useful starting point for adding EEPROM data storage methods into any of your Arduino projects, whether sensors, industrial equipment or data loggers.


Written by John Main who has a degree in Electronic Engineering.

Note: Parts of this page were written using claude-instant as a research assistant.