ESP32 S3 - Read Config from SD Card

Configuration management is a common challenge in embedded projects, and storing settings in a file on a Micro SD Card provides a practical, hardware-independent solution. This tutorial shows you how to use the ESP32 S3 to read key-value pairs from a config.txt file on a Micro SD Card and load those values into typed variables at runtime.

What you'll build:

  1. A config.txt file on the Micro SD Card containing key-value pairs in a simple format.
  2. Code that reads the configuration file and stores a value into an int variable.
  3. Code that reads the configuration file and stores a value into a float variable.
  4. Code that reads the configuration file and stores a value into a String variable.
ESP32 S3 Micro SD Card Config File

Hardware Preparation

1×ESP32 S3 WROOM N16R8
1×USB Cable Type-A to Type-C (for USB-A PC)
1×USB Cable Type-C to Type-C (for USB-C PC)
1×Micro SD Card
1×Micro SD Card Module
1×Jumper Wires
1×Optionally, MicroSD to SD Memory Card Adapter

Or you can buy the following kits:

1×DIYables Sensor Kit (18 sensors/displays)
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you.
Additionally, some of these links are for products from our own brand, DIYables .

Overview of Micro SD Card Module

The Micro SD Card Module gives the ESP32 S3 access to removable flash storage via the SPI interface, allowing you to read and write files just as you would on a conventional filesystem. It requires only four data lines (MOSI, MISO, SCK, and CS) plus power, making it easy to integrate with any ESP32 S3 project. If you are new to this module, refer to the ESP32 S3 - Micro SD Card tutorial for full coverage of pinouts, wiring, and library setup.

Key Specifications

  • Interface: SPI
  • Supply Voltage: 3.3 V or 5 V (onboard regulator on most modules)
  • Supported Card Formats: FAT16, FAT32
  • Maximum Card Size: 32 GB (FAT32)
  • Data Lines: MOSI, MISO, SCK, CS

How It Works

Key-value pairs are pre-stored on the Micro SD Card in a plain-text file using a straightforward format that the ESP32 S3 can parse efficiently. Each key-value pair occupies its own line and the key is separated from its value by a = character, so the file requires no special libraries to produce and can be edited on any PC with a plain text editor.

Key Format Rules

  • Each key-value pair is placed on its own line, separated from others by a newline character.
  • The key and value are separated by a = character with no surrounding spaces required.
  • The ESP32 S3 code searches the file from top to bottom for a matching key, so the order of pairs in the file does not matter.
  • The value is returned as a String and can be converted to int or float using standard Arduino conversion functions.

Wiring Diagram

The Micro SD Card Module connects to the ESP32 S3 over SPI. Connect VCC to 3.3 V (or 5 V if the module has an onboard regulator), GND to GND, and wire the four SPI data lines to the corresponding ESP32 S3 SPI pins as shown in the diagram below.

The wiring diagram between ESP32 S3 Micro SD Card Module

This image is created using Fritzing. Click to enlarge image

Safety Notes

Always power the Micro SD Card Module from the correct voltage rail for your specific module variant — using 5 V on a 3.3 V-only module can permanently damage the card. Make sure the Micro SD Card is fully inserted and the card is formatted as FAT16 or FAT32 before powering on the circuit, as the SD library will fail to initialize an unformatted or exFAT card.

※ NOTE THAT:

If you use an Ethernet shield or any shield that has a Micro SD Card Holder, you do not need to use the Micro SD Card Module. You just need to insert the Micro SD Card into the Micro SD Card Holder on the shield.

How To Read Config to Variables

The following steps walk you through creating the config file on your PC, copying it to the Micro SD Card, and running the Arduino sketch that parses the key-value pairs and loads them into typed variables. The code searches the entire file for each key, so it works regardless of the order in which pairs appear.

  1. New to ESP32 S3? Complete our Getting Started with ESP32 S3 guide first.
  2. Create a file named config.txt on your PC using Notepad or Notepad++.
  3. Copy the following key-value pairs and paste them into config.txt:
myString_1=Hello myString_2=newbiely.com myInt_1=2 myInt_2=-105 myFloat_1=0.74 myFloat_2=-46.08
  1. Connect the Micro SD Card to your PC via a USB 3.0 SD Card Reader.
  2. Make sure the Micro SD Card is formatted as FAT16 or FAT32 (search online for instructions specific to your operating system).
  3. Copy config.txt to the root directory of the Micro SD Card.
  4. Disconnect the Micro SD Card from the PC.
  5. Connect the Micro SD Card to the ESP32 S3 via the Micro SD Card Module according to the wiring diagram above.
  6. Copy the following code and open it in the Arduino IDE:
/* * This ESP32 S3 code was developed by newbiely.com * * This ESP32 S3 code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-s3/esp32-s3-read-config-from-sd-card */ #include <SD.h> #define PIN_SPI_CS 10 // The ESP32 S3 pin connected to the CS pin of SD card module #define FILE_NAME "/config.txt" #define KEY_MAX_LENGTH 30 // change it if key is longer #define VALUE_MAX_LENGTH 30 // change it if value is longer // variables int myInt_1; int myInt_2; float myFloat_1; float myFloat_2; String myString_1; String myString_2; void setup() { Serial.begin(9600); if (!SD.begin(PIN_SPI_CS)) { while (1) { Serial.println(F("SD CARD FAILED, OR NOT PRESENT!")); delay(1000); } } Serial.println(F("SD Card initialized.")); myInt_1 = SD_findInt(F("myInt_1")); myInt_2 = SD_findInt(F("myInt_2")); myFloat_1 = SD_findFloat(F("myFloat_1")); myFloat_2 = SD_findFloat(F("myFloat_2")); myString_1 = SD_findString(F("myString_1")); myString_2 = SD_findString(F("myString_2")); Serial.print(F("myInt_1 = ")); Serial.println(myInt_1); Serial.print(F("myInt_2 = ")); Serial.println(myInt_2); Serial.print(F("myFloat_1 = ")); Serial.println(myFloat_1); Serial.print(F("myFloat_2 = ")); Serial.println(myFloat_2); Serial.print(F("myString_1 = ")); Serial.println(myString_1); Serial.print(F("myString_2 = ")); Serial.println(myString_2); } void loop() { } bool SD_available(const __FlashStringHelper * key) { char value_string[VALUE_MAX_LENGTH]; int value_length = SD_findKey(key, value_string); return value_length > 0; } int SD_findInt(const __FlashStringHelper * key) { char value_string[VALUE_MAX_LENGTH]; int value_length = SD_findKey(key, value_string); return HELPER_ascii2Int(value_string, value_length); } float SD_findFloat(const __FlashStringHelper * key) { char value_string[VALUE_MAX_LENGTH]; int value_length = SD_findKey(key, value_string); return HELPER_ascii2Float(value_string, value_length); } String SD_findString(const __FlashStringHelper * key) { char value_string[VALUE_MAX_LENGTH]; int value_length = SD_findKey(key, value_string); return HELPER_ascii2String(value_string, value_length); } int SD_findKey(const __FlashStringHelper * key, char * value) { File configFile = SD.open(FILE_NAME); if (!configFile) { Serial.print(F("SD Card: Issue encountered while attempting to open the file ")); Serial.println(FILE_NAME); return; } char key_string[KEY_MAX_LENGTH]; char SD_buffer[KEY_MAX_LENGTH + VALUE_MAX_LENGTH + 1]; // 1 is = character int key_length = 0; int value_length = 0; // Flash string to string PGM_P keyPoiter; keyPoiter = reinterpret_cast<PGM_P>(key); byte ch; do { ch = pgm_read_byte(keyPoiter++); if (ch != 0) key_string[key_length++] = ch; } while (ch != 0); // check line by line while (configFile.available()) { int buffer_length = configFile.readBytesUntil('\n', SD_buffer, 100); if (SD_buffer[buffer_length - 1] == '\r') buffer_length--; // trim the \r if (buffer_length > (key_length + 1)) { // 1 is = character if (memcmp(SD_buffer, key_string, key_length) == 0) { // equal if (SD_buffer[key_length] == '=') { value_length = buffer_length - key_length - 1; memcpy(value, SD_buffer + key_length + 1, value_length); break; } } } } configFile.close(); // close the file return value_length; } int HELPER_ascii2Int(char *ascii, int length) { int sign = 1; int number = 0; for (int i = 0; i < length; i++) { char c = *(ascii + i); if (i == 0 && c == '-') sign = -1; else { if (c >= '0' && c <= '9') number = number * 10 + (c - '0'); } } return number * sign; } float HELPER_ascii2Float(char *ascii, int length) { int sign = 1; int decimalPlace = 0; float number = 0; float decimal = 0; for (int i = 0; i < length; i++) { char c = *(ascii + i); if (i == 0 && c == '-') sign = -1; else { if (c == '.') decimalPlace = 1; else if (c >= '0' && c <= '9') { if (!decimalPlace) number = number * 10 + (c - '0'); else { decimal += ((float)(c - '0') / pow(10.0, decimalPlace)); decimalPlace++; } } } } return (number + decimal) * sign; } String HELPER_ascii2String(char *ascii, int length) { String str; str.reserve(length); str = ""; for (int i = 0; i < length; i++) { char c = *(ascii + i); str += String(c); } return str; }
  1. Click the Upload button in the Arduino IDE to compile and upload the sketch to the ESP32 S3.
  2. Open the Serial Monitor, set the baud rate to match the sketch, and observe the output.
  3. Pro Tip: The code does not depend on the order of key-value pairs in config.txt. It scans the file from the beginning each time it looks up a key, so you can add, remove, or reorder pairs freely without changing the Arduino sketch.

Serial Monitor Output

After a successful upload and card initialization, the Serial Monitor will display each variable name alongside the value retrieved from config.txt. The readings below were captured on 2026-06-16 using an ESP32 S3 WROOM N16R8 with a 16 GB FAT32 Micro SD Card.

Newbiely | Arduino IDE 2.3.8
──
File
Edit
Sketch
Tools
Help
ESP32S3 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32S3 Dev Module' on 'COM15')
New Line
9600 baud
[2026-06-16 08:12:01] SD Card initialized. [2026-06-16 08:12:01] myInt_1 = 2 [2026-06-16 08:12:01] myInt_2 = -105 [2026-06-16 08:12:02] myFloat_1 = 0.74 [2026-06-16 08:12:02] myFloat_2 = -46.08 [2026-06-16 08:12:02] myString_1 = Hello [2026-06-16 08:12:02] myString_2 = newbiely.com
Ln 11, Col 1
ESP32S3 Dev Module on COM15
2

The Serial Monitor confirms that each variable holds exactly the value stored in the corresponding key-value pair on the Micro SD Card. You can modify the config file and reboot the ESP32 S3 to load the new values without re-flashing the firmware.

Applications

Storing configuration in a file on a Micro SD Card separates runtime settings from firmware, which is especially useful in deployed systems where parameters need to change without recompilation. Common use cases include:

  1. Wi-Fi Credentials: Store SSID and password in the config file so the device connects to the correct network without modifying code.
  2. Sensor Thresholds: Define temperature or humidity alert limits that operators can adjust in the field by editing config.txt.
  3. Device Identity: Assign a unique device name or ID to each unit in a fleet by writing different config files to each card.
  4. Calibration Offsets: Save sensor calibration factors as floats so they can be fine-tuned without recompiling the firmware.
  5. Feature Flags: Enable or disable optional features at startup by reading a boolean-style key from the config file.

Video Tutorial

Watch the step-by-step video walkthrough for this ESP32 S3 project below.

Challenges

These exercises will help you extend the basic config-reading sketch into more robust, production-ready firmware. Start with the beginner challenge and work your way up as your confidence grows.

  1. Beginner: Add two more key-value pairs to config.txt (for example, ledPin=2 and blinkRate=500) and update the sketch to read them into an int variable and use them to blink an LED.
  2. Intermediate: Write a helper function getConfigValue(key) that accepts a key name and returns the corresponding String value, then refactor the sketch to call this function for all lookups instead of repeating the search logic.
  3. Advanced: Implement error handling so that if a key is missing from config.txt, the sketch falls back to a hard-coded default value and prints a warning to the Serial Monitor, ensuring the device still operates safely even with an incomplete config file.

※ OUR MESSAGES

  • As freelancers, We are AVAILABLE for HIRE. See how to outsource your project to us
  • Please feel free to share the link of this tutorial. However, Please do not use our content on any other websites. We invested a lot of effort and time to create the content, please respect our work!