The EEPROM (Electrically Erasable Programmable Read-Only Memory) library in [Arduino](https://www.ampheo.com/c/development-board-arduino) allows you to store data persistently even after power loss. EEPROM is useful for saving settings, calibration data, or logs.

**1. Including the EEPROM Library**
First, include the EEPROM library in your sketch:
```
cpp
#include <EEPROM.h>
```
**2. Basic EEPROM Functions**
**A. EEPROM.write(address, value)**
Writes a byte (0–255) to a specific EEPROM address.
Example:
```
cpp
EEPROM.write(0, 123); // Write value 123 to address 0
```
**B. EEPROM.read(address)**
Reads a byte (0–255) from an EEPROM address.
Example:
```
cpp
byte storedValue = EEPROM.read(0); // Read from address 0
Serial.println(storedValue); // Prints "123"
```
**C. EEPROM.update(address, value)**
Only writes if the value differs from what’s already stored (reduces wear).
Example:
```
cpp
EEPROM.update(0, 200); // Updates only if different
```
**D. EEPROM.put(address, data)**
Stores any data type (e.g., int, float, struct).
Example:
```
cpp
float sensorCalibration = 3.14;
EEPROM.put(10, sensorCalibration); // Store at address 10
```
**E. EEPROM.get(address, data)**
Retrieves any data type stored with EEPROM.put().
Example:
```
cpp
float readValue;
EEPROM.get(10, readValue); // Read float from address 10
Serial.println(readValue); // Prints "3.14"
```
**3. Storing Strings (Char Arrays)**
Since EEPROM works with bytes, strings must be written character by character.
**Writing a String**
```
cpp
void writeString(int addr, const String &data) {
for (int i = 0; i < data.length(); i++) {
EEPROM.write(addr + i, data[i]);
}
EEPROM.write(addr + data.length(), '\0'); // Null terminator
}
```
**Reading a String**
```
cpp
String readString(int addr) {
char data[50]; // Max expected length
int len = 0;
do {
data[len] = EEPROM.read(addr + len);
len++;
} while (data[len - 1] != '\0' && len < 50);
return String(data);
}
```
**Example Usage**
```
cpp
writeString(20, "Hello EEPROM!"); // Store at address 20
String message = readString(20); // Retrieve
Serial.println(message); // Prints "Hello EEPROM!"
```
**4. EEPROM Size & Limitations**

⚠️ **Wear Leveling Warning:**
* EEPROM has a limited write cycle life (~100,000 writes per cell).
* Use EEPROM.update() instead of EEPROM.write() when possible.
**5. Clearing EEPROM**
To reset all EEPROM values to 0:
```
cpp
void clearEEPROM() {
for (int i = 0; i < EEPROM.length(); i++) {
EEPROM.write(i, 0);
}
}
```
**6. Full Example: Storing Sensor Data**
```
cpp
#include <EEPROM.h>
struct SensorData {
float temperature;
int humidity;
char timestamp[20];
};
void setup() {
Serial.begin(9600);
EEPROM.begin(); // Required for ESP boards
// Write data
SensorData data = {25.5, 60, "2024-01-01 12:00"};
EEPROM.put(0, data); // Store at address 0
// Read data
SensorData retrievedData;
EEPROM.get(0, retrievedData);
Serial.print("Temp: "); Serial.println(retrievedData.temperature);
Serial.print("Humidity: "); Serial.println(retrievedData.humidity);
Serial.print("Time: "); Serial.println(retrievedData.timestamp);
}
void loop() {}
```
**Key Takeaways**
* Use EEPROM.write()/read() for bytes.
* Use EEPROM.put()/get() for complex data (structs, floats, etc.).
* Prefer EEPROM.update() to reduce wear.
* ESP8266/ESP32 require EEPROM.begin(size) before use.
* Clear EEPROM if corrupted.