🛠 Data logger autonome : EEPROM + horloge RTC I²C
Objetivos
Construir un registrador autónomo: leer la hora de un reloj de tiempo real DS3231 en el bus I²C — atención, en el Nano Every el bus Wire predeterminado está en los pines dedicados SDA/SCL, no en A4/A5 — y almacenar las mediciones en la EEPROM interna del ATmega4809 (256 bytes, memoria persistente lenta y con desgaste), sin tarjeta SD.
Material
- 1 × Arduino Nano Every
- 1 × módulo DS3231 con pila de botón (dirección 0x68)
- Cables de conexión (SDA → pin SDA, SCL → pin SCL, VCC 5 V, GND)
- Cable micro-USB para la depuración
Código completo
// Data logger minimal: horodatage DS3231 (I2C) + EEPROM interne
#include <Wire.h>
#include <EEPROM.h>
const uint8_t RTC_ADDR = 0x68;
const uint16_t TAILLE_EEPROM = 256; // 256 o sur 4809
const uint8_t TAILRE_ENREG = 8; // hh mm ss aa mm jj compteur crc
uint16_t prochainePlace = 0;
uint32_t tPrecedente = 0;
uint8_t bcdToDec(uint8_t b) { return (b >> 4) * 10 + (b & 0x0F); }
void lireHeure(uint8_t* t) {
Wire.beginTransmission(RTC_ADDR);
Wire.write(0x00); // registre secondes
Wire.endTransmission(false);
Wire.requestFrom(RTC_ADDR, (uint8_t)7); // sec..annee
for (uint8_t i = 0; i < 7 && Wire.available; i++) t[i] = bcdToDec(Wire.read);
}
void setup {
Wire.begin; // bus par defaut: broches SDA/SCL
Serial.begin(9600);
EEPROM.get(0, prochainePlace);
if (prochainePlace >= TAILLE_EEPROM) { prochainePlace = 2; EEPROM.put(0, prochainePlace); }
}
void loop {
if (millis - tPrecedente < 60000) return; // 1 mesure/min
tPrecedente = millis;
uint8_t t[7];
lireHeure(t);
uint8_t mesure = (uint8_t)analogRead(A0) >> 2; // 0..255
EEPROM.put(prochainePlace, t[2]); // secondes
EEPROM.put(prochainePlace + 1, t[1]);
EEPROM.put(prochainePlace + 2, t[0]);
EEPROM.put(prochainePlace + 3, mesure);
prochainePlace += 4;
if (prochainePlace + 4 >= TAILLE_EEPROM) prochainePlace = 2; // circulaire
EEPROM.put(0, prochainePlace);
Serial.print(F("20")); Serial.print(t[6]); Serial.print(':');
Serial.print(t[5]); Serial.print(':'); Serial.print(t[4]);
Serial.print(F(" mesure=")); Serial.println(mesure);
}
Verificación esperada
El monitor serie muestra una línea por minuto con la hora del DS3231 y la medición. Tras un corte de alimentación, la EEPROM conserva la última posición de escritura y el reloj mantiene la hora gracias a su pila. Escaneo I²C previo: el DS3231 debe aparecer en el bus Wire (pines SDA/SCL) — si está en un shield A4/A5, no está en este bus por defecto.
Errores frecuentes
- Conectar el DS3231 en A4/A5 «como en el Nano clásico»: el
Wirepredeterminado está en los pines dedicados SDA/SCL (22/23 en la variante); un shield I²C heredado puede requerir el puerto secundario.
- Desgastar la EEPROM: 256 bytes y resistencia limitada a la escritura; escriba de forma circular, agrupe los bytes, nunca un
putpor lectura de sensor. - Confundir EEPROM y flash: la flash de 48 KB es más arriesgada para la escritura (autoprogramación); la EEPROM sigue siendo la opción sencilla para unos cientos de bytes.
- Olvidar la conversión BCD del DS3231: los registros están en BCD, «0x59» no es 89.
- Guardar el puntero de escritura en cada ciclo: prever un umbral o un registro diferido para cuidar la EEPROM.
- En modo autónomo sin monitor serie, no olvidar que
Serial.printbloquea poco pero consume; en producción, se desactiva o se mantiene detrás de un pin de depuración.
Otros tutoriales para esta placa
Ejemplos de código para esta placa
multi-serie.inoArduinoadc-filtre.inoArduinointerrupt-bouton.inoArduinonvm-consignes.inoArduinosommeil-every.inoArduinowatchdog-secours.inoArduino