journal-sd.ino
The case has everything for an autonomous station: internal SD, NTP clock, battery. This logger writes a CSV line every 5 s with flush — the data survives power cuts, unlike the buffer.
Hardware required
An M5Stack Core Basic/Gray (ESP32 in an enclosure with a 320×240 TFT, A/B/C buttons, speaker, microSD slot, 110 mAh battery). 1 microSD card (FAT32, ≤ 32 GB advised) in the side slot.
Wiring
No wiring: the SD slot sits on the internal SPI bus. Remove the card with power off to avoid corruption.
How it works
SD.begin mounts the bus, open(FILE_APPEND) creates or extends the file, flush forces the physical write. time/localtime_r give NTP time once Wi-Fi syncs. In the Arduino IDE (esp32 package), board « M5Stack-Core-ESP32 »; install the « M5Stack » (or M5Unified) library from the Library Manager, then Upload.
Going further
Truncate the file past 1 MB, or add a Grove sensor on port A to enrich the columns.
journal-sd.ino
// Journal CSV sur la micro SD interne (SPI HS) + horloge NTP.
#include <M5Stack.h>
#include <SD.h>
#include <WiFi.h>
#include <time.h>
const char *SSID = "votre-wifi", *CLE = "votre-cle";
File journal;
unsigned long precedent = 0;
void setup() {
M5.begin(true, true, true, false);
Serial.begin(115200);
if (!SD.begin()) { M5.Lcd.drawString("SD absente!", 10, 10, 2); for (;;); }
WiFi.begin(SSID, CLE);
configTime(3600 * 2, 0, "pool.ntp.org"); // heure locale +2, sans DST
journal = SD.open("/mesures.csv", FILE_APPEND);
if (!journal) for (;;);
if (journal.size() == 0) journal.println("epoch;heure;tension_mv;bouton");
}
void loop() {
if (millis() - precedent < 5000) return;
precedent = millis();
time_t maintenant = time(nullptr);
struct tm t; localtime_r(&maintenant, &t);
char horo[24]; strftime(horo, sizeof(horo), "%F %T", &t);
journal.printf("%ld;%s;%d;%d\n", (long)maintenant, horo,
M5.Power.getBatteryLevel(), M5.GetPowerKey());
journal.flush(); // survit a une coupure d'alim
Serial.printf("%s ecrit\n", horo);
}