🛠 Data logger autonome : EEPROM + horloge RTC I²C
Objectifs
Construire un enregistreur autonome : lire l'heure à une horloge temps réel DS3231 sur le bus I²C — attention, sur le Nano Every le bus Wire par défaut est sur les broches dédiées SDA/SCL, pas sur A4/A5 — et stocker les mesures dans l'EEPROM interne de l'ATmega4809 (256 octets, mémoire persistante lente à user), sans carte SD.
Matériel
- 1 × Arduino Nano Every
- 1 × module DS3231 avec pile bouton (adresse 0x68)
- Fils de connexion (SDA → broche SDA, SCL → broche SCL, VCC 5 V, GND)
- Câble micro-USB pour la mise au point
Code complet
// 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);
}
Vérification attendue
Le moniteur série affiche une ligne par minute avec l'heure du DS3231 et la mesure. Après coupure d'alimentation, l'EEPROM conserve la dernière position d'écriture et l'horloge garde l'heure grâce à sa pile. Scanner I²C préalable : le DS3231 doit apparaître sur le bus Wire (broches SDA/SCL) — s'il est sur un shield A4/A5, il n'est pas sur ce bus par défaut.
Erreurs fréquentes
- Câbler le DS3231 sur A4/A5 « comme sur le Nano classique » : le
Wirepar défaut est sur les broches dédiées SDA/SCL (22/23 dans le variant) ; un shield I²C hérité peut nécessiter le port secondaire.
- User l'EEPROM : 256 octets et endurance limitée en écriture ; écrivez en circulaire, regroupez les octets, jamais un
putpar lecture capteur. - Confondre EEPROM et flash : la flash de 48 Ko est en écriture plus risquée (self-programming) ; l'EEPROM reste le choix simple pour quelques centaines d'octets.
- Oublier la conversion BCD du DS3231 : les registres sont en BCD, « 0x59 » n'est pas 89.
- Sauvegarder le pointeur d'écriture à chaque tour : prévoir un seuil ou un enregistrement différé pour ménager l'EEPROM.
- En mode autonome sans moniteur série, ne pas oublier que
Serial.printbloque peu mais consomme ; en production, on le coupe ou on le garde derrière une broche de debug.
Autres tutoriels pour cette carte
Exemples de code pour cette carte
multi-serie.inoArduinoadc-filtre.inoArduinointerrupt-bouton.inoArduinonvm-consignes.inoArduinosommeil-every.inoArduinowatchdog-secours.inoArduino