This tutorial explains what is the Arduino EEPROM and what it is useful for. We’re also going to show you how to write and read from the EEPROM and build a project example to put the concepts learned into practice.
We have a similar tutorial for the ESP32: ESP32 Flash Memory – Store Permanent Data (Write and Read)
Introduction
When you define and use a variable, the generated data within a sketch only lasts as long as the Arduino is on. If you reset or power off the Arduino, the data stored disappears.
If you want to keep the data stored for future use you need to use the Arduino EEPROM. This stores the variable’s data even when the Arduino resets or the power is turned off.
What is EEPROM?
The microcontroller on the Arduino board (ATMEGA328 in case of Arduino UNO, shown in figure below) has EEPROM (Electrically Erasable Programmable Read-Only Memory). This is a small space that can store byte variables.
The variables stored in the EEPROM kept there, event when you reset or power off the Arduino. Simply, the EEPROM is permanent storage similar to a hard drive in computers.
The EEPROM can be read, erased and re-written electronically. In Arduino, you can read and write from the EEPROM easily using the EEPROM library.
How many bytes can you store?
Each EEPROM position can save one byte, which means you can only store 8-bit numbers, which includes integer values between 0 and 255.
The bytes you can store on EEPROM dependson the microcontrollers on the Arduino boards. Take a look at the table below:
Microcontroller | EEPROM |
ATmega328 (Arduino Uno, Nano, Mini) | 1024 bytes |
ATmega168 (Arduino Nano) | 512 bytes |
ATmega2560 (Arduino Mega) | 4096 bytes |
However, if you need to store more data you can get an external EEPROM.
The EEPROM finite life
The EEPROM has a finite life. In Arduino, the EEPROM is specified to handle 100 000 write/erase cycles for each position. However, reads are unlimited. This means you can read from the EEPROM as many times as you want without compromising its life expectancy.
Applications in Arduino projects – Remember last state
The EEPROM is useful in Arduino projects that need to keep data even when the Arduino resets or when power is removed.
It is specially useful to remember the last state of a variable or to remember how many times an appliance was activated.
For example, imagine the following scenario:
- You’re controlling a lamp with your Arduino and the lamp is on;
- The Arduino suddenly loses power;
- When the power backs on, the lamp stays off – it doesn’t keep its last change.
You don’t want this to happen. You want the Arduino to remember what was happening before losing power and return to the last state.
To solve this problem, you can save the lamp’s state in the EEPROM and add a condition to your sketch to initially check whether the state of the lamp corresponds to the state previously saved in the EEPROM.
We’ll exemplify this with an example later in this post in the Example: Arduino EEPROM remember stored LED state.
Read and Write
You can easily read and write into the EEPROM using the EEPROM library.
To include the EEPROM library:
#include <EEPROM.h>
Write
To write data into the EEPROM, you use the EEPROM.write() function that takes in two arguments. The first one is the EEPROM location or address where you want to save the data, and the second is the value we want to save:
EEPROM.write(address, value);
For example, to write 9 on address 0, you’ll have:
EEPROM.write(0, 9);
Read
To read a byte from the EEPROM, you use the EEPROM.read() function. This function takes the address of the byte has an argument.
EEPROM.read(address);
For example, to read the byte stored previously in address 0.:
EEPROM.read(0);
This would return 9, which is the value stored in that location.
Update a value
The EEPROM.update() function is particularly useful. It only writes on the EEPROM if the value written is different from the one already saved.
As the EEPROM has limited life expectancy due to limited write/erase cycles, using the EEPROM.update() function instead of the EEPROM.write() saves cycles.
You use the EEPROM.update() function as follows:
EEPROM.update(address, value);
At the moment, we have 9 stored in the address 0. So, if we call:
EEPROM.update(0, 9);
It won’t write on the EEPROM again, as the value currently saved is the same we want to write.
Example: Arduino EEPROM remember stored LED state
In this example, we’re going to show you how to make the Arduino remember the stored LED state, even when we reset the Arduino or the power goes off.
The following figure shows what we’re going to exemplify:
Parts required
Here’s the parts required for this project (click the links below to find the best price at Maker Advisor):
- Arduino UNO – read Best Arduino Starter Kits
- 1x LED
- 1x 220Ω resistor
- 1x Pushbutton
- 1x 1kΩ resistor
- 1x Breadboard
- Jumper wires
You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!
Schematics
Here’s the circuit schematics for this project. This is just a pushbutton that will turn an LED on and off.
Code
Copy the following code to the Arduino IDE and upload it to your Arduino board. Make sure you have the right board and COM port selected.
/*
* Rui Santos
* Complete Project Details https://randomnerdtutorials.com
*/
#include <EEPROM.h>
const int buttonPin = 8; // pushbutton pin
const int ledPin = 4; // LED pin
int ledState; // variable to hold the led state
int buttonState; // the current reading from the input pin
int lastButtonState = LOW; // the previous reading from the input pin
// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long lastDebounceTime = 0; // the last time the output pin was toggled
long debounceDelay = 50; // the debounce time; increase if the output flickers
void setup() {
// set input and output
pinMode(buttonPin, INPUT);
pinMode(ledPin, OUTPUT);
// set initial LED state
digitalWrite(ledPin, ledState);
// initialize serial monitor
Serial.begin (9600);
//check stored LED state on EEPROM using function defined at the end of the code
checkLedState();
}
void loop() {
// read the state of the switch into a local variable
int reading = digitalRead(buttonPin);
if(reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
if((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
// if the button state has changed:
if(reading != buttonState) {
buttonState = reading;
// only toggle the LED if the new button state is HIGH
if(buttonState == HIGH) {
ledState = !ledState;
}
}
}
// set the LED state
digitalWrite(ledPin, ledState);
// save the current LED state in the EEPROM
EEPROM.update(0, ledState);
// save the reading. Next time through the loop,
// it'll be the lastButtonState
lastButtonState = reading;
}
// Prints and upates the LED state
// when the Arduino board restarts or powers up
void checkLedState() {
Serial.println("LED status after restart: ");
ledState = EEPROM.read(0);
if(ledState == 1) {
Serial.println ("ON");
digitalWrite(ledPin, HIGH);
}
if(ledState == 0) {
Serial.println ("OFF");
digitalWrite(ledPin, LOW);
}
}
This is a debounce code that changes the LED state every time you press the pushbutton. But there’s something special about this code – it remembers the saved LED state, even after resetting or powering of the Arduino.
Basically, we save the current LED state in the ledState variable and save it to the EEPROM with the following line:
EEPROM.update(0,ledState);
At the beginning of the code on the setup(), we check the ledState saved on EEPROM and set the led on or off accordingly to that state when we restart the program. We do that with a function we’ve created at the end of the code, checkLedState()
void checkLedState() {
Serial.println("LED status after restart: ");
ledState = EEPROM.read(0);
if (ledState == 1) {
Serial.println ("ON");
digitalWrite(ledPin, HIGH);
}
if (ledState == 0) {
Serial.println ("OFF");
digitalWrite(ledPin, LOW);
}
}
Demonstration
For a demonstration of this example, watch the video below.
Wrapping up
In this post you’ve learned about the Arduino EEPROM and what it is useful for. You’ve created an Arduino sketch that remembers the last LED state even after resetting the Arduino.
This is just a simple example for you to understand how the use of EEPROM. The idea is that you apply the concepts learned in this tutorial to your own projects.
If you like Arduino, we recommend taking a look at our Arduino resources:
We hope you’ve found this article useful.
Thanks for reading.
Great tutorial. Can you please write a tutorial for 24LC04 or similar external Eeprom also. Awaiting your simplified tutorials
Hi Kumaran.
Thanks for the suggestion, we may came up with that tutorial in the future.
Stay tuned. 🙂
We are waiting for that
Hi.
We haven’t created that tutorial yet. We’re busy with other projects at the moment.
Thanks for understanding.
I think you’re skipping over the real significance of the write/erase physical limitation of 100,000.
If you had something that changes state every ten seconds and, each time, you update the state in EEPROM, then you’ll exceed the 100,000 limit in a little over eleven and a half days for a given position.
There are other methods for saving a state at power failure which, although they require a bit of extra hardware, make much better use of the limited nature of EEPROM.
I learnt about the EEPROM limitation the hard way!
Hi Duncan.
We are using the EEPROM.update() and not the EEPROM.write() function. The EEPROM.update() only writes on the EEPROM if the value written is different from the one already saved, so it only updates the state on the EEPROM it there has been a state change.
Read the “Update a value” section on this post to learn about the update() function.
Thanks.
Yee, I accept that, and fully admit that I’d glossed over it. My apologies to all for any confusion caused.
My main point was that doing anything with the EEPROM on each pass through the loop was unnecessary. It would be better to do so only when there has been a change of state and, if the idea is to overcome the risk of data loss on power fail, that there are ways of doing it only when the power actually fails.
Arduino EEPROM, when it decides to fail, loses only the affected locations – in the case of, say, the ESP8266, the entire EEPROM space is rendered unusable.
To many newcomers, the 100,000 limit seems to be a very large number, but the reality can be very different. Anything that reduces the activity (any activity) for the EEPROM is, basically, a good idea and should be incorporated within the program wherever possible.
If it changes state every 10 seconds, as stated, the update() function will update the EEPROM as Duncan has stated. This is a very example to present for the use of the EEPROM.
set all eeprom to FF then you save at address = address +1 . When you reset the program looks for the first FF then sets the address 1 less and reads the Led. Then after next button press save at address = address +1. With a Nano you now get 11000+ days – around 30 + years.
Jet, could you guide me, to write what you explain, I am a novice user, if you want I will send you my email, thank you, in advance!
mario172 at msn.com
How does the EEPROM fail when it is written to too many times?
Is the last value still readable? Does the entire EEPROM fail at once? Can a failing EEPROM cause issues executing code that doesn’t try to write to the EEPROM? What about code that doesn’t even reference the EEPROM at all?
Hi Greg.
That’s a great question.
We’ve never experienced writing too many times on the EEPROM, so we can’t tell you exactly what happens.
However, as far as I know, the EEPROM readings are unlimited, so you must be able to read the last value, but cannot update that value.
Regards.
Uhm… I wonder if the eeprom will last long if it will check/read/write in the loop?
That’s the problem – as it’s written, it’s forcing an update to the EEPROM every pass through the loop.
It would be much better to do the update only if there has been a state change – that would reduce the count dramatically and, frankly, the only time you want to save the state is when it has changed…
By incorporating a counter and a Serial.write, this could be a method for telling you how many write/update cycles the EEPROM lasted for before it died – it wouldn’t be long to wait for an answer!!!
Thanks for the response Duncan. That’s what I was thinking about “update only if there has been a state change”. Thanks.
Extending the thinking further, you only really want to save the state in EEPROM when the power is about to fail – but how would you know when that is going to happen?
One Schottky Diode and a very large capacitor do the trick. Feed the capacitor and the micro through the diode and take the input of the diode to a GPIO.
If the power fails, the GPIO goes low, that fires an interrupt that saves the state in EEPROM and puts the Micro to sleep (or not, as the case may be) whilst the capacitor winds down and the micro turns off…
When you reboot, it checks the EEPROM for a valud value.
EEPROM only gets written when it’s actually required and the limited life problem usually becomes irrelevant.
HI Duncan, I was also thinking of something similar. To detect the power failure and only in that case, update the memory.
Would you be able to provide a circuit diagram for the diode / capacitor method you mentioned? Thanks.
Hi Ray.
We are using the EEPROM.update() and not the EEPROM.write() function. The EEPROM.update() only writes on the EEPROM if the value written is different from the one already saved, so it only updates the state on the EEPROM it there has been a state change.
Thanks.
That would at least double the life of the eeprom.
Hello its showing an error in EEPROM as ‘class EEPROMClass’ has no member named ‘update’. what to do?
Are you using this examples with the Arduino board?
Regards,
Sara
No i am using this code in esp8266 Nodemcu board.
So, that’s the reason.
That function is not available for the ESP8266.
See here: https://github.com/esp8266/Arduino/tree/83166f948bedff85543b1cb5532b905746744df7/libraries/EEPROM/examples
Regards,
Sara
Ok mam the EEPROM.update() function works for arduino board only. But in EEPROM.write() function it takes 3.3 ms to complete to change its current value state.
For that what to do mam.
Oeps. To quick. Like to say that it is a nice example. Only wondering about the lifespan. Sorry.
It is what it is. alternative would be a replaceable external EEPROM
Thumbs up, good tutorial, well explaned with pro and contra’s
Hi Gij Kieken.
Thanks for your support.
Well done! Never used an EEPROM or this section of the Arduino, but I can now.
I understand and appreciate Duncan Amos’ explanation of the 100,000 limit. I’m sure learning of the limitation was quite um, educational–I’ve had a few of those, myself.
Well done tutorial, good job.
Thanks, John 🙂
Hello RUI,
It’s a very useful tutorial and also very well explained.
Hi Rajiv Shankar.
Thanks for your support.
Regards
I liked the description of the EEPROM usage, but I have a few problems with the coding.
In the setup block, I think setting the LED should come after the call to checkLedState().
In the main loop, I think that buttonState and lastButtonState are redundant – you only need one of them.
In the checkLedState(), there is no provision for a value that is not 0 or 1. So if the EEPROM has a 2, the function does not work as planned.
Thanks for the EEPROM explanation.
Hi Dan.
In this example, we’ve used the Arduino example sketch called Debounce and then adapted to use the EEPROM.
This example uses the buttonState and lastButtonState variables to check whether the button state has changed.
The checkLedSate() function works just fine with the LED because its state is either 1 or 0.
Regards
step by step explanation is excellent
Thanks. 🙂
There are cases where update is not enough. I can figure out (I know it is bad design) recording of data, with time-stamp -say, every 10 seconds) : one can guess it will need ten days to wear out the second field -and I do not know what happens to the other fields: is Arduino fully destroyed, is EEPROM fully destroyed or do parts remain usable).
If one has short information to write, maybe length – int8_t – should be written before writing data (an empty flash countains 0xFF or zero; test on length, on an empty flash, would return a zero or negative value length -int8_t has sign info…).
The interesting part of the EEPROM would be the last part where length is > 0.
The plawe where to write would be just after the really readble part of the EEPROM (and writing would imply write/update length; write/update data; write/update empty length)
This would involve reading sequentially (adress would be 0, length[0]+1… adress[n]+length[n]+1) and cycling if EEPROM is full. With the same example as before -time stamped data every 10 seconds: say record to be written is 30 bytes…. one can write 30 records, and EEPROM life expectation is therefore, as writes are uniformly spread, multiplied by 30 -alost one year instead of 10 days.)
I do not know wheteher this way of spreading data over the full EEPROM has been implemented (and maybe there are less naive ones)
SOU INICIANTE EM PROGRAMAÇÃO C++ COM ARDUINO, EM QUAL ESCOPO DEVEREI ESCREVER
EEPROM.write (0, 9); PRA QUE EU POSSA VERIFICAR POSTERIORMENTE SE REALMENTE ESTÁ LÁ O QUE ESCREVI ? GRATO ! ANDRÉ.
Olá André.
Não tenho a certeza se percebi bem a pergunta.
Para verificar o que lá escreveu, pode usar:
EEPROM.read(0);
Que vai ler o que escreveu no address 0.
Cumprimentos,
Sara
P.S. Da próximo vez, tente postar os comentários em inglês, para que todos os leitores possam compreender. Obrigada
Please include a tutorial on the ESP8266 EEPEROM’s ( It is called as Flash in ESPs) as well.
Also – what’s the longevity of the Flash, Is it years, months, and how long before it gets corrupted. Things like that would help ( if that’s available )
I would like to update the Flash every second forever ? as the data could be static or dynamic.
BTW: I like all of your articles and most of my google searches in this area include the search words + ‘Randomnerd’ to get what I want from your web site first.
I’m sorry, below lines didn’t copy,
// include the library code:
#include
#include
#include
You can copy the full code directly from this link: https://raw.githubusercontent.com/RuiSantosdotme/Random-Nerd-Tutorials/master/Projects/Arduino_EEPROM.ino
good day… how can be your tutorial applied if im using sms to turn the LED on and not the push button..
thank your for your help
Hi.
Yes, it works the same way.
Regards,
Sara
Again, nice tutorial. Works great.
Thanks
Joe
Hi Sarah. How can i erase the EEPROM ? I want to erase it periodically to avoid exceeding the 100,000 write cycles.
It doesn’t work that way . At around 100,000 cycles the memory you have used will stop functioning So if you change Address 0 100,000 times it will stop changing . but address 1 should still change,
You should consider adding the EEPROM.put() and EEPROM.get() functions: https://www.arduino.cc/en/Reference/EEPROMPut and https://www.arduino.cc/en/Reference/EEPROMGet and maybe the undocumented EEPROM.end().
One way you could use them to store a richer configuration that protects against EEPROM that exceeded its write count by storing a structure with a flag pointing to the valid and confirmed data.
Or simpler, you could store the EEPROM address of the valid data in EEPROM, and update to a different address if it ever fails to update & check properly. E.g: stateAddress=EEPROM.Read(EEPROM.end()); ledState=EEPROM.Read(stateAddress);
Can you please write this programming in micro C language.
Nice project, interested in the output status maintaining a HIGH or LOW pin, trying to link up with this project on the input button status but still not getting it.