Objectives
- Use the M5Stack Core's internal microSD reader (SPI, CS = GPIO4) to log measurements in CSV.
- Format a FAT32 card up to 16 GB (the official slot limit) and create dated files.
- Write safely: open/append/println/flush/close, daily rotation, save before deep-sleep.
- Display the number of records and the card status on the screen.
Hardware
- 1 M5Stack Core (Basic/Gray) with a TF slot on the back (under the cover).
- 1 microSD card ≤ 16 GB, formatted as FAT32 (newer exFAT cards do not work).
- Sensor of choice: here ADC1 G36 (PORT.B) and the IP5306 battery are used as data examples.
Complete code
#include <M5Unified.h>
#include <SD.h>
const int PIN_TF_CS = 4; // CS du slot TF interne
const int PIN_CAPTEUR = 36; // ADC1, PORT.B
File journal;
uint32_t nbLignes = 0;
void setup {
Serial.begin(115200);
auto cfg = M5.config;
M5.begin(cfg);
M5.Display.setTextSize(2);
if (!SD.begin(PIN_TF_CS)) {
M5.Display.println("Carte SD absente");
M5.Display.println("ou pas en FAT32");
while (true) vTaskDelay(1000 / portTICK_PERIOD_MS);
}
journal = SD.open("mesures.csv", FILE_APPEND);
if (!journal) { M5.Display.println("Ouverture fichier KO"); while (true); }
if (journal.size == 0) journal.println("millis,adc36,batterie");
Serial.println("Logger SD pret");
}
void loop {
M5.update;
if (M5.BtnA.wasPressed) {
journal.printf("%lu,%d,%d\n", millis,
analogRead(PIN_CAPTEUR), M5.Power.getBatteryLevel);
journal.flush; // ne depend pas de la cache
nbLignes++;
M5.Speaker.beep;
}
if (M5.BtnB.wasPressed) { journal.close; esp_restart; }
M5.Display.fillRect(0, 30, 320, 60, TFT_BLACK);
M5.Display.setCursor(10, 35);
M5.Display.printf("Lignes : %lu", nbLignes);
vTaskDelay(50 / portTICK_PERIOD_MS);
}
Expected verification
- Pressing A: beep + counter increment; a file
mesures.csv appears at the root of the card with one line "millis,adc36,battery" per press. - Remove the card and read it on a PC: the CSV opens in a spreadsheet.
- Without a card (or with exFAT): message "SD card absent" at startup instead of a crash.
Common errors
- Card larger than 16 GB or formatted as exFAT/NTFS: the slot is limited to 16 GB FAT32 — this is an official limit, not a bug.
- Forgetting
flush before removal or deep-sleep: the last lines are lost. - Keeping the File open for hours without rotation: create one file per day (dated name) to limit damage in case of power loss.
- Confusing the internal slot's CS (GPIO4) with an external CS: GPIO4 is factory-wired to the TF reader.
- Writing over shared SPI during intensive screen refreshes: slowdowns occur; pace the writes (here on button press or every N seconds).
- Removing the card while powered on and reinserting it without
SD.begin: you must remount the filesystem (idf.py restart or RESET button).