🛠 Data logger sur EEPROM : persistance sans usure
Objectives
Make the most of the UNO's smallest storage space: the 1 KB of EEPROM on the ATmega328P, which survives power cuts (unlike the 2 KB of SRAM). You will design a data format, write only when the value changes (the EEPROM has a finite write endurance, typically around 100,000 cycles per cell), and verify recovery after a restart.
Hardware
- 1 Arduino UNO R3 + USB-B cable (or a 7–12 V jack power supply to test autonomy)
- 1 LDR + 10 kΩ resistor in a voltage divider on A1
- 1 push button on pin 2 to GND (to trigger saving)
- The ATmega328P is in a socket: in case of failure, you can replace the chip for a few euros, and the board remains usable.
Complete Code
// Logger de maximum de luminosité, persistant en EEPROM (1 Ko).
#include <EEPROM.h>
const uint8_t LDR = A1;
const uint8_t BTN = 2;
// Adresse 0 : un en-tête « magique » pour détecter une EEPROM jamais initialisée.
const uint16_t MAGIC = 0xA5A5;
uint16_t maxVu = 0;
uint16_t dernierEnregistre = 0;
void setup {
Serial.begin(9600);
pinMode(BTN, INPUT_PULLUP);
uint16_t entete = 0;
EEPROM.get(0, entete);
if (entete != MAGIC) {
// Première initialisation : pas de données valides.
EEPROM.put(0, MAGIC);
EEPROM.put(2, (uint16_t)0);
maxVu = 0;
Serial.println(F("EEPROM initialisee"));
} else {
EEPROM.get(2, maxVu);
Serial.print(F("Restaure max=")); Serial.println(maxVu);
}
}
void loop {
int v = analogRead(LDR);
if (v > maxVu) {
maxVu = v;
EEPROM.put(2, maxVu); // écrivons SEULEMENT quand ça change
Serial.print(F("nouveau max=")); Serial.println(maxVu);
}
// Bouton : dump du contenu à la demande.
if (digitalRead(BTN) == LOW) {
Serial.print(F("etat EEPROM[2..3]="));
Serial.println(EEPROM.read(2) | (EEPROM.read(3) << 8));
delay(300); // anti-rebond grossier pour ce bouton de debug
}
Serial.print(F("ldr=")); Serial.println(v);
delay(100);
}
Expected Verification
Note the maximum value, unplug the USB (or plug in the jack), then reconnect: the Serial Monitor displays "Restore max=..." with the preserved value — SRAM is lost, EEPROM is not. Also check wear: with a threshold that causes constant writing, you waste write cycles unnecessarily; the code only calls put when there is an actual change.
Common Errors
- Calling put/get in loop every iteration: at 10 writes/s, you approach the 100,000 cycles/cell limit in just a few days. Write on event or use a deadband.
- Forgetting the magic header: on the first boot, a blank EEPROM contains 0xFF everywhere (65535), so your "max" value will be permanently incorrect.
- Writing a float (4 bytes) without thinking: EEPROM.put handles it, but using EEPROM.write byte by byte with incorrect ordering results in inconsistent values.
- Beware of clones: some low-cost clones have fuses configured differently; if the EEPROM seems dead, test the library with a minimal sketch before doubting your code.
- Confusing EEPROM (1 KB, persistent) with flash (32 KB, including 0.5 KB for the bootloader): for large volumes, you need an SPI SD card, not the EEPROM.
Other tutorials for this board
Code examples for this board
clignotante.inoArduinobouton-poussoir.inoArduinopwm-fade.inoArduinocapteur-lumiere-ldr.inoArduinoservo-balayage.inoArduinoruban-neopixel.inoArduino