🛠 Data logger autonome : EEPROM + horloge RTC I²C
Objectives
Build a standalone data logger: read the time from a DS3231 real-time clock on the I²C bus — note that on the Nano Every, the default Wire bus is on the dedicated SDA/SCL pins, not on A4/A5 — and store measurements in the ATmega4809's internal EEPROM (256 bytes, slow persistent memory with limited endurance), without an SD card.
Hardware
- 1 × Arduino Nano Every
- 1 × DS3231 module with coin cell battery (address 0x68)
- Connecting wires (SDA → SDA pin, SCL → SCL pin, VCC 5 V, GND)
- Micro-USB cable for debugging
Complete code
// 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);
}
Expected verification
The serial monitor displays one line per minute with the DS3231 time and the measurement. After a power cut, the EEPROM retains the last write position, and the clock keeps the time thanks to its battery. Preliminary I²C scan: the DS3231 must appear on the Wire bus (SDA/SCL pins) — if it is on an A4/A5 shield, it is not on this bus by default.
Common errors
- Wiring the DS3231 to A4/A5 "as on the classic Nano": the default
Wireis on the dedicated SDA/SCL pins (22/23 in the variant); a legacy I²C shield may require the secondary port.
- Wearing out the EEPROM: 256 bytes and limited write endurance; write in a circular fashion, group bytes, never use a
putper sensor reading. - Confusing EEPROM and flash: the 48 KB flash is riskier to write to (self-programming); EEPROM remains the simple choice for a few hundred bytes.
- Forgetting the DS3231's BCD conversion: registers are in BCD, "0x59" is not 89.
- Saving the write pointer on every loop: plan for a threshold or deferred saving to spare the EEPROM.
- In standalone mode without a serial monitor, do not forget that
Serial.printblocks little but consumes resources; in production, disable it or keep it behind a debug pin.
Other tutorials for this board
Code examples for this board
multi-serie.inoArduinoadc-filtre.inoArduinointerrupt-bouton.inoArduinonvm-consignes.inoArduinosommeil-every.inoArduinowatchdog-secours.inoArduino