Did you know the Arduino can store data when it's turned off? Not the sketch stored in flash memory. I'm talking about variable data in the EEPROM. Join me as I show you how to read and write to it, and what it can do for your projects.

If you're new to Arduino, make sure you check out our beginners guide.

What Is EEPROM?

EEPROM stands for electrically erasable programmable read-only memory. It's a type of non-volatile memory. Don't worry if you don't understand what any of that means. It simply stores data even with the power removed (unlike RAM, which needs electricity to retain any data).

EEPROM example shot

EEPROM is built into a myriad of processors, such as the field-programmable gate array (FPGA) used in the Matrix Creator Pi HAT. All Arduinos have EEPROM available, but the capacity varies per model. Make sure you take a look at our buying guide for more details on each board.

How Does It Work?

EEPROM is electrically erased and programmed using Fowler-Nordheim tunneling. You don't need to know the technical details to be able to use it. The basic premise is that electricity is used to change the binary data (what is binary). It can be read, erased, and re-written electronically.

Fortunately, the Arduino Language makes it easy to change data, all without needing a degree in computer science.

EEPROM Close Up

Life Expectancy

While it is easy to use EEPROM in the Arduino, it does have a limited life. EEPROM is specified to handle 100,000 read/erase cycles. This means you can write and then erase/re-write data 100,000 times before the EEPROM will become unstable. In reality, Atmel (the manufacturers of the Arduino "Chip") semiconductors may handle a higher or lower number of cycles, depending on the tolerances of each and every processor.

EEPROM Close Up

Once a location has been written and erased too many times it can start to become unreliable. It may not return the correct data, or return the value from a neighbouring bit.

This may sound like a lot of writes, but it can be easy to reach this limit if reading and writing programmatically (in a loop, for example). Reading data does not degrade the silicon, only writing does. You can read data from EEPROM as much as you like without fear!

It's important to note that this limit applies to each memory location. Your Arduino may have 1,000 or more memory locations available in EEPROM, so if you write too many times to one location, it is only that location impacted, and not any of the others. Later on I'll be discussing wear levelling, which can reduce EEPROM wear by distributing data evenly -- something that SSDs make use of.

What's It Useful For?

EEPROM is incredibly useful for your Arduino projects. As it remembers data even when the power is removed, you could store the state of the Arduino. Maybe you could build a laser turret that remembers its position or how much "ammo" is remaining. You could use it to control your appliances, and log how many times your appliance was activated.

EEPROM is best suited for things like settings or high-scores. If you want to regularly write complex data, maybe consider an ethernet shield (with built-in SD slot) or a Raspberry Pi.

EEPROM Close Up

Read and Write

Now that the theory is out the way, let's look at how to read and write some data! First, include the library (this comes with the Arduino IDE):

            #include <EEPROM.h>
    

Now write some data:

            EEPROM.write(0, 12);
    

This writes the number 12 to EEPROM location 0. Each write takes 3.3 milliseconds (ms, 1000ms = 1 second). Notice how you cannot write letters (char), only the numbers from zero to 255 are allowed. This is why EEPROM is ideal for settings or high scores, but not so good for player names or words. It is possible to store text using this method (you could map each letter of the alphabet to a number), however you will need to have multiple memory locations -- one location for each letter.

Here's how you read that data:

            EEPROM.read(0);
    

Zero is the address you wrote to previously. If you have not written to an address before, it will return the maximum value (255).

There are some slightly more useful methods available. Say you wanted to store a decimal place or string:

            EEPROM.put(2,"12.67");
    

This writes the data to multiple locations -- something that would be easy to write yourself, but handy none the less. You will still need to keep track of how many locations this has written to, so you don't accidentally overwrite your data! You have to use the get method to retrieve this data again:

            float f = 0.00f;
EEPROM.get(2, f);
    

The value from get is stored into the float f variable. Notice how this is initialized with 0.00f as the value. The f lets the compiler know that you might want to store a large number in this variable, so it sets up some additional configurations during compilation.

The EEPROM documentation on the Arduino website has lots more examples.

Wear Leveling

Wear leveling is a technique used to reduce the wear and increase the life of EEPROM. If you are only working on a small project, you may not need to worry about this.

EEPROM Close Up

The simplest thing you can do to preserve EEPROM life is to limit your writes to a particular location. You can do this by reading the address first, and if the value you want to write is already present, there's no need to write it again (remember, reading data does no harm). Here's how you would do that:

            int safeWrite(int data, address) {
    if(EEPROM.read(address) != data) {
        EEPROM.write(address, data);
    }
}
    

That is quite a simple bit of code, however it only works for integers! Instead of re-inventing the wheel, use the function built into the Arduino EEPROM library:

            EEPROM.update(address, val);
    

This method has exactly the same signature as the write method, although it may drastically reduce the number of writes needed!

If you need to write a lot of data, and are concerned about wearing out the silicon, you can keep track of how many writes you do, although this uses more data. Here's a rough implementation in pseudocode:

            var address = 0
var writeCount = 0

if(writeCount > 75,000)
    writeCount = 0
    address += 1

EEPROM.write(address, data)
    

You will need to store address and writeCount in EEPROM (and writeCount will need to be split across address locations). The majority of the time, this level of protection will not be necessary. Arduinos are so cheap as well, so you may find it easier to purchase a backup!

You should now know enough to make some awesome projects. Let us know if you make something cool! Can you recognise all the devices in the pictures? Leave us a comment below!