A microSD card turns the S3 into a data logger that keeps working without Wi-Fi — useful for solar, tank-level or temperature logs in places with patchy internet.
Wire the common blue module to 5V and the S3’s default SPI pins (CS 10, MOSI 11, SCK 12, MISO 13). The sketch appends a CSV line every 5 s that opens directly in a spreadsheet.
Wiring
| ESP32-S3-DevKitC-1 | MicroSD card module (SPI) | Wire | Notes |
|---|---|---|---|
| 5V | VCC | red | The blue module’s AMS1117 needs 5 V in; 3.3 V leaves the card under-powered. |
| GND | GND | black | |
| 10 | CS | purple | |
| 11 | MOSI | green | |
| 12 | SCK | yellow | |
| 13 | MISO | blue |
4.5–5.5 V on the common module with regulator (3.3 V-only boards also sold) part, 3.3 V board. The common blue module has an AMS1117 3.3 V regulator and a 74LVC125 level shifter, so it needs 5 V on VCC — 3.3 V leaves the card under-powered. Its signal pins accept 3.3 V or 5 V logic, so ESP32, Pico and Uno all connect directly.
Board quirks
- The S3’s default SPI (FSPI) pins are GPIO10–13. The sketch passes them to
SPI.begin()explicitly so you can move the card to other free pins if a display already uses these. - Use the SD library that ships with the ESP32 core (
SD.h) — not the AVR SD library. It mounts FAT32 cards up to 32 GB; format bigger cards to FAT32 or use a smaller one. - The file is opened and closed for every line, so a power cut loses at most one line — worth it in areas with frequent outages.
temperatureRead()is the S3’s on-chip sensor: it shows how warm the chip runs, not the room temperature. Swap in a real sensor for a weather log.
Code
// microSD card module on an ESP32-S3-DevKitC-1 — logs the chip's internal temperature to a CSV file.
// VCC → 5V (the common module has its own 3.3 V regulator), GND → GND,
// CS → GPIO10, MOSI → GPIO11, SCK → GPIO12, MISO → GPIO13 (the S3's default SPI pins).
// Card: FAT32, 32 GB or smaller.
#include <SPI.h>
#include <SD.h>
constexpr uint8_t SD_CS = 10;
void setup() {
Serial.begin(115200);
SPI.begin(12, 13, 11, SD_CS); // SCK, MISO, MOSI, SS
if (!SD.begin(SD_CS, SPI, 4000000)) {
Serial.println("Card mount failed - check wiring, 5V on VCC and that the card is FAT32");
while (true) delay(1000);
}
uint8_t type = SD.cardType();
Serial.printf("Card type: %s, size: %llu MB\n",
type == CARD_SDHC ? "SDHC" : type == CARD_SD ? "SD" : type == CARD_MMC ? "MMC" : "unknown",
SD.cardSize() / (1024ULL * 1024ULL));
if (!SD.exists("/log.csv")) {
File f = SD.open("/log.csv", FILE_WRITE);
if (f) {
f.println("uptime_s,chip_temp_c");
f.close();
}
}
}
void loop() {
File f = SD.open("/log.csv", FILE_APPEND);
if (!f) {
Serial.println("Could not open /log.csv");
} else {
float t = temperatureRead(); // the S3's built-in sensor: chip temperature, not room temperature
f.printf("%lu,%.1f\n", millis() / 1000, t);
f.close(); // close every time so a power cut loses at most one line
Serial.printf("Logged: %lu s, %.1f C\n", millis() / 1000, t);
}
delay(5000);
}// microSD card module on an ESP32-S3-DevKitC-1 — logs the chip's internal temperature to a CSV file.
// VCC → 5V (the common module has its own 3.3 V regulator), GND → GND,
// CS → GPIO10, MOSI → GPIO11, SCK → GPIO12, MISO → GPIO13 (the S3's default SPI pins).
// Card: FAT32, 32 GB or smaller.
#include <SPI.h>
#include <SD.h>
constexpr uint8_t SD_CS = 10;
void setup() {
Serial.begin(115200);
SPI.begin(12, 13, 11, SD_CS); // SCK, MISO, MOSI, SS
if (!SD.begin(SD_CS, SPI, 4000000)) {
Serial.println("Card mount failed - check wiring, 5V on VCC and that the card is FAT32");
while (true) delay(1000);
}
uint8_t type = SD.cardType();
Serial.printf("Card type: %s, size: %llu MB\n",
type == CARD_SDHC ? "SDHC" : type == CARD_SD ? "SD" : type == CARD_MMC ? "MMC" : "unknown",
SD.cardSize() / (1024ULL * 1024ULL));
if (!SD.exists("/log.csv")) {
File f = SD.open("/log.csv", FILE_WRITE);
if (f) {
f.println("uptime_s,chip_temp_c");
f.close();
}
}
}
void loop() {
File f = SD.open("/log.csv", FILE_APPEND);
if (!f) {
Serial.println("Could not open /log.csv");
} else {
float t = temperatureRead(); // the S3's built-in sensor: chip temperature, not room temperature
f.printf("%lu,%.1f\n", millis() / 1000, t);
f.close(); // close every time so a power cut loses at most one line
Serial.printf("Logged: %lu s, %.1f C\n", millis() / 1000, t);
}
delay(5000);
}Library: SD (Arduino, SparkFun (ESP32 and Pico cores ship their own SD library)).
Expected serial output
Card type: SDHC, size: 15193 MB
Logged: 0 s, 41.3 C
Logged: 5 s, 41.5 CCard type: SDHC, size: 15193 MB Logged: 0 s, 41.3 C Logged: 5 s, 41.5 C
Common errors
“Card mount failed”
Module on 3V3 instead of 5V, card not FAT32, or MISO/MOSI swapped.
Works once, then fails after reset
Another SPI device on the bus is holding MISO. Give every SPI device its own CS and keep the others HIGH.