Inquire: Call 0086-755-23203480, or reach out via the form below/your sales contact to discuss our design, manufacturing, and assembly capabilities.
Quote: Email your PCB files to Sales@pcbsync.com (Preferred for large files) or submit online. We will contact you promptly. Please ensure your email is correct.
Notes: For PCB fabrication, we require PCB design file in Gerber RS-274X format (most preferred), *.PCB/DDB (Protel, inform your program version) format or *.BRD (Eagle) format. For PCB assembly, we require PCB design file in above mentioned format, drilling file and BOM. Click to download BOM template To avoid file missing, please include all files into one folder and compress it into .zip or .rar format.
In my years designing embedded control systems, I’ve seen countless projects lose critical configuration data after power cycles. Calibration values vanish, user settings reset, and operation counters start over—all because the developer didn’t implement proper non-volatile storage.
This Arduino EEPROM tutorial will show you how to permanently store data that survives power loss, resets, and even firmware updates. Whether you’re building smart home controllers, industrial sensors, or instrumentation, understanding Arduino EEPROM is essential for professional-grade projects.
EEPROM stands for Electrically Erasable Programmable Read-Only Memory. It’s a small section of non-volatile memory built into your Arduino’s microcontroller that retains data even when power is removed.
Think of EEPROM as your Arduino’s permanent notebook. While SRAM (your regular variables) forgets everything when powered off, EEPROM remembers. This makes it perfect for storing:
User preferences and settings
Calibration coefficients
Device configuration parameters
Runtime counters and statistics
Small lookup tables
System state information
The ATmega328P in Arduino Uno has 1KB of EEPROM—small by modern standards, but perfectly sized for configuration data. Larger boards offer more:
Arduino Board
EEPROM Size
Microcontroller
Write Cycles
Uno / Nano
1024 bytes (1KB)
ATmega328P
100,000
Mega 2560
4096 bytes (4KB)
ATmega2560
100,000
Leonardo
1024 bytes (1KB)
ATmega32U4
100,000
Due
0 bytes
SAM3X8E
N/A (use Flash)
ESP32
Emulated
ESP32
~100,000
Basic Arduino EEPROM Operations
The EEPROM library provides simple read and write functions. Let me walk you through the fundamentals I use in every project.
Writing Single Bytes
#include <EEPROM.h>
void setup() {
Serial.begin(9600);
// Write a single byte to address 0
int address = 0;
byte value = 123;
EEPROM.write(address, value);
Serial.println(“Value written to EEPROM”);
}
void loop() {
// Empty
}
Each write takes approximately 3.3ms on ATmega microcontrollers—important when writing multiple values.
Reading Single Bytes
#include <EEPROM.h>
void setup() {
Serial.begin(9600);
// Read the byte from address 0
int address = 0;
byte value = EEPROM.read(address);
Serial.print(“Value read from EEPROM: “);
Serial.println(value);
}
void loop() {
// Empty
}
EEPROM reads are fast—essentially instantaneous compared to writes.
Update vs Write: Extending EEPROM Life
Here’s a crucial tip from my experience: always use EEPROM.update() instead of EEPROM.write() for production code:
// DON’T do this repeatedly
EEPROM.write(address, value); // Writes even if value unchanged
// DO this instead
EEPROM.update(address, value); // Only writes if value different
The update() function checks if the current value differs before writing. This dramatically extends EEPROM lifespan by avoiding unnecessary write cycles.
Storing Different Data Types in Arduino EEPROM
EEPROM only stores bytes directly, but we frequently need to store integers, floats, or strings. Here’s how I handle each type.
Storing Integers
#include <EEPROM.h>
void writeInt(int address, int value) {
byte lowByte = value & 0xFF;
byte highByte = (value >> 8) & 0xFF;
EEPROM.update(address, lowByte);
EEPROM.update(address + 1, highByte);
}
int readInt(int address) {
byte lowByte = EEPROM.read(address);
byte highByte = EEPROM.read(address + 1);
return (highByte << 8) | lowByte;
}
void setup() {
Serial.begin(9600);
// Write integer
writeInt(0, 12345);
// Read it back
int value = readInt(0);
Serial.println(value); // Prints: 12345
}
Storing Float Values
Floats require special handling since they’re 4 bytes:
#include <EEPROM.h>
void writeFloat(int address, float value) {
byte *bytePointer = (byte *)(void *)&value;
for (int i = 0; i < sizeof(float); i++) {
EEPROM.update(address + i, bytePointer[i]);
}
}
float readFloat(int address) {
float value;
byte *bytePointer = (byte *)(void *)&value;
for (int i = 0; i < sizeof(float); i++) {
bytePointer[i] = EEPROM.read(address + i);
}
return value;
}
void setup() {
Serial.begin(9600);
// Store calibration coefficient
writeFloat(10, 3.14159);
// Read calibration value
float pi = readFloat(10);
Serial.println(pi, 5); // Prints: 3.14159
}
Storing Strings
#include <EEPROM.h>
void writeString(int address, String data) {
int length = data.length();
for (int i = 0; i < length; i++) {
EEPROM.update(address + i, data[i]);
}
// Null terminator
EEPROM.update(address + length, ‘\0’);
}
String readString(int address) {
char data[100]; // Buffer size
int i = 0;
char c;
while ((c = EEPROM.read(address + i)) != ‘\0’ && i < 99) {
data[i] = c;
i++;
}
data[i] = ‘\0’;
return String(data);
}
Practical Arduino EEPROM Applications
User Settings Storage
One of my most common uses is storing user-configurable settings:
#define ADDR_TOTAL_RUNTIME 54 // 4 bytes for unsigned long
void incrementRunCount() {
unsigned long count = readULong(ADDR_RUN_COUNT);
count++;
writeULong(ADDR_RUN_COUNT, count);
}
void writeULong(int address, unsigned long value) {
for (int i = 0; i < 4; i++) {
EEPROM.update(address + i, (value >> (i * 8)) & 0xFF);
}
}
unsigned long readULong(int address) {
unsigned long value = 0;
for (int i = 0; i < 4; i++) {
value |= ((unsigned long)EEPROM.read(address + i) << (i * 8));
}
return value;
}
void setup() {
Serial.begin(9600);
incrementRunCount();
unsigned long runCount = readULong(ADDR_RUN_COUNT);
Serial.print(“Device has run “);
Serial.print(runCount);
Serial.println(” times”);
}
Understanding EEPROM Write Cycles and Wear Leveling
The most critical limitation of Arduino EEPROM is its finite write endurance: typically 100,000 write cycles per cell. In my industrial projects, this requires careful management.
EEPROM Lifespan Calculation
If you write to the same address every second:
Write Interval
Writes per Day
Days to Failure
1 second
86,400
~1.16 days
1 minute
1,440
~69 days
10 minutes
144
~694 days
1 hour
24
~4,167 days (11 years)
Simple Wear Leveling
For frequently updated data, distribute writes across multiple addresses:
#include <EEPROM.h>
#define COUNTER_START 100
#define COUNTER_SLOTS 10 // Use 10 addresses
unsigned long currentSlot = 0;
void saveCounterWithWearLeveling(unsigned long value) {
int address = COUNTER_START + (currentSlot * 4);
writeULong(address, value);
currentSlot = (currentSlot + 1) % COUNTER_SLOTS;
}
unsigned long loadNewestCounter() {
unsigned long newestValue = 0;
// Find the highest value (most recent)
for (int i = 0; i < COUNTER_SLOTS; i++) {
int address = COUNTER_START + (i * 4);
unsigned long value = readULong(address);
if (value > newestValue) {
newestValue = value;
}
}
return newestValue;
}
This simple technique extends lifespan by 10x.
Critical Data Redundancy
For mission-critical data, I implement redundancy:
ATmega328P Datasheet: Microchip’s official documentation (Section on EEPROM)
Essential Libraries:
EEPROM (Built-in): Included with Arduino IDE
EEPROMWearLevel: Advanced wear leveling library
EEPROMex: Extended EEPROM functions for easier data handling
External EEPROM Options:
AT24C256 (256Kbit I2C EEPROM): Popular external option
24LC512 (512Kbit): Larger capacity option
FRAM MB85RC256V: Non-volatile RAM alternative
Development Tools:
EEPROM Reader Sketch: Simple diagnostic tool
Memory Calculator: Planning EEPROM layout
Hex Editor: Examining EEPROM contents
Learning Resources:
Arduino Playground EEPROM: Community examples and tips
AVR Freaks EEPROM Forum: Technical deep dives
Adafruit EEPROM Tutorial: Beginner-friendly guide
Hardware Tools:
Logic Analyzer: For I2C external EEPROM debugging
Arduino ISP: For reading EEPROM via programming interface
Frequently Asked Questions
Q: Can I increase Arduino EEPROM size beyond the built-in capacity?
A: Yes, add external EEPROM chips via I2C or SPI. I frequently use AT24C256 (32KB) or 24LC512 (64KB) modules in projects requiring more storage. These connect with just two wires (I2C: SDA, SCL) and often provide 1 million write cycles versus the internal 100,000. For projects needing gigabytes, SD cards are more practical. The external EEPROM sits at a unique I2C address (typically 0x50), allowing multiple chips on the same bus.
Q: How do I clear or reset the entire Arduino EEPROM?
A: Write zeros to all addresses, but this counts toward your write cycle limit. Here’s the safe method I use:
for (int i = 0; i < EEPROM.length(); i++) {
EEPROM.write(i, 0);
}
On Arduino Uno, this takes about 3.3 seconds (1024 bytes × 3.3ms). Only clear EEPROM when absolutely necessary—like after major firmware changes. For testing, use a magic number approach instead of repeatedly clearing everything.
Q: Does uploading new code erase Arduino EEPROM data?
A: No, EEPROM is separate from program memory. I’ve uploaded hundreds of firmware updates without losing calibration data. However, the bootloader burning process (done via ISP programmer with wrong fuse settings) can erase EEPROM. Standard USB uploads through the Arduino IDE never touch EEPROM. This persistence makes EEPROM perfect for storing device serial numbers and calibration—they survive every code update.
Q: What happens when EEPROM reaches its 100,000 write cycle limit?
A: Individual cells typically fail by getting stuck at 1 or 0, or becoming unreliable rather than catastrophically failing. In my testing, some cells survived 300,000+ cycles before showing errors. When designing critical systems, I implement error detection (checksums) and redundancy. For high-write-frequency applications exceeding 100 writes per day, consider FRAM (virtually unlimited cycles) or external EEPROM (1M cycles rated). Wear leveling extends lifespan significantly.
Q: Can I use Arduino EEPROM for data logging applications?
A: Generally no—EEPROM is too small and wears too quickly for continuous logging. Logging sensor data every second exhausts EEPROM in about a day. Use SD cards for data logging (gigabytes of storage, fast writes, removable). EEPROM works perfectly for logging summary statistics (daily max/min), event counters, or infrequent events. I use EEPROM for storing the last 10 alarm events with timestamps—useful for diagnostics without needing SD complexity.
Conclusion
Mastering Arduino EEPROM opens up professional-level firmware development. Throughout my career designing embedded systems, proper non-volatile storage has separated amateur projects from production-ready devices.
The key principles to remember: use update() instead of write(), implement initialization checks with magic numbers, add checksums for critical data, consider wear leveling for frequently updated values, and understand when alternative storage (external EEPROM, SD cards, FRAM) makes more sense.
Start with simple settings storage—device brightness, alarm thresholds, or user preferences. Progress to calibration data that survives firmware updates. For advanced applications, implement wear leveling and redundancy.
Whether you’re building IoT sensors, industrial controllers, or scientific instruments, Arduino EEPROM provides the permanent storage foundation your projects need. Now go build something that remembers!
Inquire: Call 0086-755-23203480, or reach out via the form below/your sales contact to discuss our design, manufacturing, and assembly capabilities.
Quote: Email your PCB files to Sales@pcbsync.com (Preferred for large files) or submit online. We will contact you promptly. Please ensure your email is correct.
Notes: For PCB fabrication, we require PCB design file in Gerber RS-274X format (most preferred), *.PCB/DDB (Protel, inform your program version) format or *.BRD (Eagle) format. For PCB assembly, we require PCB design file in above mentioned format, drilling file and BOM. Click to download BOM template To avoid file missing, please include all files into one folder and compress it into .zip or .rar format.