🛠 Persister une calibration dans l'EEPROM de l'ATmega (512 octets ou 1 Ko)
Objectives
One of the true joys of the AVR compared to the Due (which has 0 bytes of EEPROM): the Duemilanove includes 512 bytes of EEPROM (ATmega168) or 1 KB (ATmega328), preserved without power. You will store a calibration value in a structure, write it only when it changes (EEPROM has limited write cycles), and verify that it survives a complete power cut.
Hardware
- 1 Arduino Duemilanove (ATmega328 recommended: 1 KB of EEPROM)
- 1 push button (pin 2 to GND) to request saving
- 1 potentiometer on A0 to simulate the measurement to be calibrated
- Mini-USB cable or standalone power supply
Complete code
// Calibration persistee en EEPROM (bibliothque EEPROM fournie avec le core)
#include <EEPROM.h>
struct Calibration { // 4 octets
uint16_t zero; // offset de calibration
uint16_t magic; // marqueur de validite
};
const uint16_t MAGIC = 0xABCD;
const byte BOUTON = 2;
Calibration cal;
void setup {
pinMode(BOUTON, INPUT_PULLUP);
Serial.begin(9600);
EEPROM.get(0, cal); // lecture adresse 0
if (cal.magic != MAGIC) { // premiere vie de la carte ?
cal.zero = analogRead(A0);
cal.magic = MAGIC;
EEPROM.put(0, cal); // ecriture initiale
Serial.println("Calibration initialisee");
} else {
Serial.print("Calibration rechargee : zero=");
Serial.println(cal.zero);
}
}
void loop {
if (digitalRead(BOUTON) == LOW) { // bouton enfonce
delay(50); // anti-rebond grossier
if (digitalRead(BOUTON) == LOW) {
cal.zero = analogRead(A0);
EEPROM.put(0, cal); // écrit seulement sur demande
Serial.print("zero enregistre : ");
Serial.println(cal.zero);
while (digitalRead(BOUTON) == LOW) { } // attend le relachement
}
}
}
Expected verification
First execution: "Calibration initialized". Turn off completely (unplug USB AND power supply), plug back in: the board displays "Calibration reloaded: zero=…" with the previous value, not a reset. Pressing the button with the potentiometer in a different position changes the persisted value. On a 168, the same structure occupies 4 of the 512 available bytes.
Common errors
- Writing to EEPROM in every
loop: the AVR spec announces ~100,000 cycles per byte; anEEPROM.update(which only writes if the value changes) or an event-based write is mandatory for continuous operation. - Writing beyond the actual size: 512 bytes on ATmega168, 1024 on ATmega328 — an
EEPROM.putat address 1020 of a 4-byte structure works, at 1024 it silently overflows depending on the case. - Believing that
EEPROM.geton a new chip returns 0: a blank EEPROM is 0xFF; hence themagicmarker to detect the first run. - Changing the struct definition without changing the address or the magic number: the old content is reinterpreted arbitrarily — version your structures.
- Mixing up boards: a sketch compiled for 328 uploaded to 168 crashes before even talking to the EEPROM (see the Blink tutorial and processor selection).
- Comparing floats read from EEPROM with
==: prefer integers (hereuint16_t) or a tolerance.
Other tutorials for this board
- Faire clignoter la LED 13 d'une Duemilanove (et choisir le bon ATmega)
- Bouton poussoir et moniteur série sur la Duemilanove (avec ses 0,5 s de silence)
- Potentiomètre et variation LED : l'ADC 10 bits et le PWM 8 bits version AVR
- Ajouter un deuxième port série avec SoftwareSerial (GPS sur broches 10/11)
- Régler la référence de mesure avec AREF et analogReference
- Convertir la Duemilanove en programmateur AVR (ArduinoISP) pour graver des puces nues
Code examples for this board
clignotante.inoArduinobouton-led.inoArduinopwm-respiration.inoArduinopotentiometre-plotter.inoArduinoservo-balayage.inoArduinobuzzer-melodie.inoArduino