We optimized our SRAM. But what if you need to store data—like high scores or settings—and make sure it survives when the Arduino is unplugged? The Uno has 1KB of internal EEPROM, which is practically nothing. Enter the AT24C256 I2C EEPROM Module. It gives you a massive 32 Kilobytes of non-volatile storage. Finally, your Arduino can have long-term memories.
The AT24C256 EEPROM Module is cheap, reliable, and incredibly easy to use.
Connecting the AT24C256 to your Arduino Uno is simple thanks to the I2C bus.
| AT24C256 Pin | Arduino Uno Pin | Description |
|---|---|---|
| VCC | 5V | Power supply |
| GND | GND | Ground |
| SCL | A5 (or SCL) | I2C Clock Line |
| SDA | A4 (or SDA) | I2C Data Line |
| WP | GND | Write Protect (Tie to GND to enable writing) |
(Note: If your module has address pins like A0, A1, A2, leave them unconnected or tie them to GND. This sets the default I2C address, usually 0x50.)
To communicate with the EEPROM, we will use the built-in Wire.h library. We don’t even need a special EEPROM library for basic operations!
Here is a simple sketch that writes a number to memory, and then reads it back:
#include <Wire.h>
// Default I2C address for the AT24C256
#define EEPROM_ADDR 0x50
void setup() {
Serial.begin(9600);
Wire.begin();
Serial.println("EEPROM Write and Read Test");
// 1. Write Data
unsigned int memoryAddress = 0x0000;
byte dataToWrite = 42; // The meaning of life, or just a test number
writeEEPROM(EEPROM_ADDR, memoryAddress, dataToWrite);
Serial.print("Wrote: ");
Serial.println(dataToWrite);
// Give the EEPROM a few milliseconds to complete the write cycle
delay(10);
// 2. Read Data
byte readData = readEEPROM(EEPROM_ADDR, memoryAddress);
Serial.print("Read back: ");
Serial.println(readData);
}
void loop() {
// Nothing to do in the loop for this test
}
// Function to write a byte of data to a specific memory address
void writeEEPROM(int deviceAddress, unsigned int memAddress, byte data) {
Wire.beginTransmission(deviceAddress);
Wire.write((int)(memAddress >> 8)); // MSB of the memory address
Wire.write((int)(memAddress & 0xFF)); // LSB of the memory address
Wire.write(data); // The data byte
Wire.endTransmission();
}
// Function to read a byte of data from a specific memory address
byte readEEPROM(int deviceAddress, unsigned int memAddress) {
byte data = 0xFF;
Wire.beginTransmission(deviceAddress);
Wire.write((int)(memAddress >> 8)); // MSB
Wire.write((int)(memAddress & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(deviceAddress, 1);
if (Wire.available()) {
data = Wire.read();
}
return data;
}
>> 8 and & 0xFF) to split the memory address into a Most Significant Byte (MSB) and a Least Significant Byte (LSB).delay(10) after a write command to ensure the chip is ready for the next operation.Now that you have 32KB of permanent storage, you can build weather stations that log temperatures over weeks, or a custom combination lock that remembers passcodes even if the battery dies.
Happy tinkering!