Skip to content

What is an SD Card?

An SD card gives your tinyCore a place to store data that sticks around after power off. The ESP32-S3’s internal flash is only a few megabytes — a microSD card adds gigabytes of removable storage for data logging, audio files, configuration, and more.

The tinyCore has a built-in microSD card slot. Anytime you want to record sensor data over hours or days, store WAV files for the tinySpeak HAT, save WiFi credentials so you don’t hardcode them, or collect data in the field without an internet connection — you need the SD card. It’s also the easiest way to move data between your tinyCore and a computer: pull the card out, plug it into your laptop, open the CSV in Excel.

How SD Cards Communicate with Microcontrollers

Section titled “How SD Cards Communicate with Microcontrollers”

The tinyCore talks to the SD card using SPI (Serial Peripheral Interface), a four-wire protocol:

WireFull NameWhat It Does
MOSIMaster Out, Slave InESP32-S3 sends data to the card
MISOMaster In, Slave OutCard sends data back to the ESP32-S3
CLKClockTiming signal that keeps both sides in sync
CSChip SelectTells the card “I’m talking to you”

The ESP32-S3 also supports a faster interface called SDMMC that uses fewer wires for higher throughput. Which one the tinyCore uses depends on how the board’s SD slot is wired — check your tinyCore pinout to confirm.

The tinyCore’s slot takes a microSD card. Here’s what matters:

Format: FAT32. The Arduino SD library only supports FAT16 and FAT32. Cards formatted as exFAT (which includes most cards over 32 GB out of the box) will fail with “Card Mount Failed.”

Capacity: 8–32 GB is the sweet spot. Cards 32 GB and under ship pre-formatted as FAT32 and work immediately. Cards over 32 GB (SDXC) ship as exFAT and must be reformatted — it works, it’s just an extra step.

Speed class doesn’t matter much. The ESP32’s SPI bus maxes out around 2 MB/s, well below even a Class 2 card’s capability. A basic Class 10 card is more than enough. Don’t waste money on UHS-II or V90 cards.

One file size limit to know: FAT32 caps individual files at 4 GB minus 1 byte. For data logging this is rarely an issue, but for long audio recordings, you may need to split into multiple files.

Both SD.h and SPI.h come pre-installed with the ESP32 Arduino core — no library installation needed.

#include "FS.h"
#include "SD.h"
#include "SPI.h"
#define CS_PIN 10 // Change to tinyCore's actual CS pin
void setup() {
Serial.begin(115200);
delay(2000);
if (!SD.begin(CS_PIN)) {
Serial.println("Card Mount Failed");
return;
}
Serial.println("SD card ready.");
// Write a file
File file = SD.open("/hello.txt", FILE_WRITE);
if (file) {
file.println("Hello from tinyCore!");
file.close(); // ALWAYS close files after writing
}
// Read it back
file = SD.open("/hello.txt");
if (file) {
while (file.available()) {
Serial.write(file.read());
}
file.close();
}
}
void loop() {}

This is the most common SD card use case — recording sensor readings over time so you can analyze them later in a spreadsheet:

void loop() {
float temp = readSensor(); // your sensor function
unsigned long ms = millis();
File file = SD.open("/datalog.csv", FILE_APPEND);
if (file) {
char line[64];
snprintf(line, sizeof(line), "%lu,%.1f", ms, temp);
file.println(line);
file.close(); // close after every write to prevent corruption
}
delay(5000); // log every 5 seconds
}

Pull the card out, plug it into your computer, and open datalog.csv in Excel or Google Sheets. Each row is a timestamped reading.

ProjectHow It Uses the SD Card
Sensor data loggerAppend timestamped readings to a CSV every few seconds
Audio playback (tinySpeak)Store WAV files that the ESP32-S3 reads and plays through I2S
Portable field recorderCollect data without WiFi, then pull the card to view on a computer
Config file storageSave WiFi credentials, calibration values, or device settings in a text file; read them at boot instead of hardcoding

“Card Mount Failed”

CauseFix
Card formatted as exFAT (common on 64 GB+ cards)Reformat as FAT32
Wrong CS pin in codeVerify SD.begin(CS_PIN) matches your actual hardware pin
Loose connectionCheck that the card is fully seated in the slot
Power supply issue (cards draw up to 100 mA during writes)Use stable 3.3V supply
Counterfeit or defective cardTest with a different card from a reputable brand

Files are corrupted or incomplete

The number one beginner mistake: not calling file.close() after writing. FAT32 doesn’t update the file system table until you close the file. If power cuts during an open write, the file (and sometimes the whole filesystem) can be corrupted.

For long logging sessions, call file.flush() periodically to force data to disk without closing the file. But closing after each write (as shown in the data logging example above) is the safest approach.

Writes are slow

The default SPI clock in the Arduino SD library is 4 MHz. You can increase it:

SD.begin(CS_PIN, SPI, 40000000); // 40 MHz SPI clock

Typical throughput at 40 MHz is around 1–2 MB/s. For most data logging this is plenty. If you need maximum speed, look into SDMMC mode (using SD_MMC.h), which can reach 4–8 MB/s in 4-bit mode.

FeatureDetails
Card typemicroSD
Required formatFAT32
Max file size~4 GB
Recommended capacity8–32 GB
InterfaceSPI (default) or SDMMC
Arduino librarySD.h + SPI.h (pre-installed)
Default SPI speed4 MHz (increase to 40 MHz for better performance)
Key functionSD.begin(CS_PIN)

Robojax — ESP32 with built-in SD slot (similar to tinyCore), full Arduino code walkthrough, writing to card, and viewing files on a PC. About 12 minutes.