🛠 Persister une calibration dans l'EEPROM de l'ATmega (512 octets ou 1 Ko)
Objetivos
Una de las verdaderas ventajas del AVR frente a la Due (que tiene 0 bytes de EEPROM): la Duemilanove incorpora 512 bytes de EEPROM (ATmega168) o 1 KB (ATmega328), que se conservan sin alimentación. Vas a almacenar un valor de calibración en una estructura, escribirla solo cuando cambie (la EEPROM tiene un número limitado de ciclos de escritura) y verificar que sobreviva a un corte total de la alimentación.
Material
- 1 Arduino Duemilanove (se recomienda ATmega328: 1 KB de EEPROM)
- 1 botón pulsador (pin 2 a GND) para solicitar el guardado
- 1 potenciómetro en A0 para simular la medida a calibrar
- Cable mini-USB o fuente de alimentación autónoma
Código completo
// 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
}
}
}
Verificación esperada
Primera ejecución: «Calibration initialisee». Apagar completamente (desconectar USB Y alimentación), reconectar: la placa muestra «Calibration rechargee : zero=…» con el valor anterior, no una reinicialización. Pulsar el botón con el potenciómetro en una posición diferente cambia el valor persistido. En una 168, la misma estructura ocupa 4 de los 512 bytes disponibles.
Errores frecuentes
- Escribir en la EEPROM en cada
loop: la especificación AVR anuncia ~100 000 ciclos por byte; unEEPROM.update(que solo escribe si el valor cambia) o una escritura por evento son obligatorios en ejecución continua. - Escribir más allá del tamaño real: 512 bytes en ATmega168, 1024 en ATmega328 — un
EEPROM.puten la dirección 1020 de una estructura de 4 bytes funciona, pero en 1024 desborda silenciosamente según los casos. - Creer que
EEPROM.geten un chip nuevo devuelve 0: una EEPROM virgen vale 0xFF; de ahí el marcadormagicpara detectar el primer uso. - Cambiar la estructura de la struct sin cambiar la dirección o el magic: el contenido anterior se reinterpreta incorrectamente — versionar tus estructuras.
- Mezclar placas: un sketch compilado para 328 subido a una 168 falla antes incluso de hablar con la EEPROM (ver el tutorial Blink y la elección del microcontrolador).
- Comparar flotantes leídos de la EEPROM con
==: preferir enteros (aquí uint16_t) o una tolerancia.
Otros tutoriales para esta placa
- 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
Ejemplos de código para esta placa
clignotante.inoArduinobouton-led.inoArduinopwm-respiration.inoArduinopotentiometre-plotter.inoArduinoservo-balayage.inoArduinobuzzer-melodie.inoArduino