Data logging is an integral part of many embedded projects. Typically, data logging is used to record sensor readings, with or without a timestamp. For example, many IoT applications use data logging to store network changes or data for troubleshooting or verification.
The ideal way to record data locally is using an SD or MicroSD card. Most card readers can interface with microcontrollers or microcomputers through an SPI port.
The MicroPython machine module firmware contains an SDCard class for working with SD and MicroSD card readers. The machine.SDCard class supports SD, MMC, and eMMC storage devices. The communication protocol for all three types of storage devices is through the SPI port.
The SDCard class can be implemented using MicroPython's Pyboard, ESP32, CC3200, and mimxrt ports. The SDCard module is not supported on other ports.
In this article, we will discuss how to interface an SD or MicroSD card reader with ESP32.
With these cards, it is possible to add 4 to 128 GB of storage to the embedded system. Sensor data or other data is recorded in plain text files on the SD/MicroSD card. Most SD or MicroSD cards provide a 1-bit interface to the memory card. The SPI port is used on SD card breakout boards to access the storage device.
Required components
The following components are required for data logging on the ESP32.
1. ESP32 x1
2. MicroSD card module x1
3. 8GB MicroSD Card
4. microUSB cable to connect the ESP32 to the computer
5. Jumper Wires
MicroSD card module
The MicroSD card module contains a slot for inserting the card and six terminals for interfacing with a microcontroller. VDD and ground are two of the pins. The other four pins – MISO, MOSI, SCK and CS – are the SPI port terminals that facilitate the 1-bit interface with the memory card.

The pin configuration of a MicroSD card.
MicroSD card and ESP32
To interface the MicroSD card module with ESP32:
- Connect the module's MOSI, MISO, SCLK, and CS pins to the ESP32's GPIO12, GPIO13, GPIO14, and GPIO27 pins. These pins correspond to the HSPI (SPI1) of the ESP32.
- Connect the module's VCC and GND pins to the ESP32's 3.3V and ground.
MicroSD card readers have built-in voltage regulators to convert the input voltage to 3.3 VDC. But a voltage as high as 5V DC may damage the module or corrupt the memory card.

The circuit connections for interfacing the MicroSD card module with the ESP32.
The MicroPython machine module
The MicroPython machine module was written to handle the hardware functions of the supported ports. The module includes classes to control or manage digital input/output, output signals from external devices, pulse width modulation, analog to digital conversion, peripheral control ADC, UART, SPI, I2C, I2S, timer, RTC, timer watchdog and SD card.
The module's SDcard class supports reading SD, MMC, and eMMC memory cards.
SDCard Class
The SDCard class provides access to SD or MMC memory cards using a dedicated SD/MMC interface on a given MicroPython port or via an SPI channel.
To use the class in a MicroPython script, sdcard.py must be loaded into the ESP32 and then imported into the script. The OS and machine module must also be imported.
To import the required modules, add this statement in a MicroPython script:
import machine, SD card, operating system
An object of the SDCard class must be initialized within the script. The SDCard class constructor has this prototype:
class machine.SDCard(slot=1, width=1, cd=None, wp=None, sck=None, miso=None, mosi=None, cs=None, freq=20000000)
The parameters in the constructor function:
- slot: selects one of the available interfaces or uses the default
- width: selects the bus width for the SD/MMC interface (for SD/MicroSD card adapters, the width is “1”. It is not necessary to specify it explicitly unless the hardware in the SD card port has a parallel to read memory cards.)
- cd: specifies a card detection pin
- wp: specifies a write-protect pin
- sck: specifies an SPI clock pin
- miso: specifies a miso SPI pin
- mosi: specifies a mosi SPI pin
- cs: specifies an SPI chip select pin
- frequency: selects the frequency of the SD/MMC interface in Hz (only supported on ESP32)
There are two hardware SPI blocks in ESP32: HSPI (SPI1) and VSPI (SPI2). For this project, the MicroSD card adapter is interfaced via SPI 1.
To launch the SDCard object, add this statement to the MicroPython script:
sd = sdcard.SDCard(machine.SPI(1), machine.Pin(27))
The operating system module
The MicroPython OS module provides functions for accessing and mounting the file system. The following methods are useful when working with a MicroSD card.
os.VfsFat: Creates a file system object that uses the FAT file system format. A block device, which implements the block protocol, provides FAT file system storage. Essentially, it allows a device to support the MicroPython file system. The physical hardware is represented by the file system class. A FAT file system is used when an object is created with os.VfsFat . The object can be mounted using the os.mount method.

MicroPython ports support file systems.
os.mount : Mounts specified file system objects to the virtual file system location provided by a string argument. The file system object can be a virtual object that has a mount method or a block device. If it is a block device, the file system type will be detected automatically; otherwise, an exception will be raised.
The string specifying the location can be '/' to mount the file system object to the root, or '/
os.listdir : if called without argument, lists the current directory. Otherwise, lists the specified directory.
os.umount : “unmounts” a file system. The location can be a string naming the mount location or a previously mounted file system object. During the unmount process, the umount method is called for the file system object.
This is a valid example of a FAT file system for a MicroSD card, mounting the file system object in memory.
vfs = os.VfsFat(sd)
os.mount(vfs, “/fc”)
print(“File system check”)
print(os.listdir(“/fc”))
Creating text files
Adding plain text files to a MicroSD card is simple. You can create multiple plain text files on a memory card. Just create a string specifying the text file path.
Here is a valid example to create simple text files on a MicroSD card using MicroPython.
fn = “/fc/log.txt”
Writing a single block
A single block is a line of text. A file must be specified with a string variable and a specified file path must be opened using the open method to write a block. The “w” argument must also be passed as file mode. A single block can be written by calling the write method.
This is a valid example of writing a single block to a text file on a MicroSD card.
fn = “/fc/one-line-log.txt”
print out
print(“Write in single block”)
with open(fn, “w”) as f:
n = f.write(“1234567890\n”) # a block
print(n, “bytes written”)
Reading a single block
To read a file, the file specified by a string variable must be opened using the open method with the file mode specified as “r”. The file is read by calling the read method.
This is a valid example of reading a text file from a MicroSD card.
fn = “/fc/one-line-log.txt”
print out
print(“Single block read”)
with open(fn, “r”) as f:
result = f.read
print(len(result2), “bytes read”)
print out
print (result)
Writing multiple blocks
Writing multiple blocks to a text file is similar to writing a single block, except that the passed string object contains multiple lines of text.
Here is a valid example of writing multiple blocks to a text file on a MicroSD card.
line = “abcdefghijklmnopqrstuvwxyz\n”
lines = line * 200 # 5400 characters
fn = “/fc/multi-line-log.txt”
print out
print(“Writing in multiple blocks”)
with open(fn, “w”) as f:
n = f.write(lines)
print(n, “bytes written”)
Reading multiple blocks
Multiple lines in a text file are read similarly to a single line. Here is a valid example of reading multiblock text file from a MicroSD card.
fn = “/fc/multi-line-log.txt”
print out
print(“Reading multiple blocks”)
with open(fn, “r”) as f:
result = f.read
print(len(result2), “bytes read”)
print out
print (result)
Preparing the ESP32
Before proceeding, make sure the MicroPython IDE is ready to write, edit, and upload codes. You can use uPyCraft IDE or Thonny IDE as software development. With the help of respective IDE, upload MicroPython firmware for ESP8266 or ESP32.
To find out how click here .
Loading sdcard.py to ESP32
In uPyCraft IDE, create a new file by navigating to Files->New. Copy and paste the following code into the file and save it as sdcard.py.
Click the “DownloadandRun” button to upload sdcard.py to the ESP32 root directory. Check the console log to verify writing and reading text files to the MicroSD card. After files are written, the number of bytes is reported. After reading the files, the number of bytes is read and the read text is printed on the console.