4. Chapter Read and Write the SDcard
An SDcard slot is integrated on the back of the ESP32-S3 WROOM. In this chapter, we learn how to use ESP32-S3 to read and write SDcard.
4.1. Project 4.1 SDMMC Test
4.1.1. Component List
ESP32-S3 WROOM x1 |
USB cable x1 |
|---|---|
|
|
SD card x1 |
Card reader x1 (random color) |
|
|
4.1.2. Component knowledge
4.1.2.1. SD card read and write method
The ESP32-S3 offers two methods for accessing the SD card: SPI interface and SDMMC interface. The SPI mode requires 4 IOs to access the SD card, while the SDMMC interface supports both one-bit and four-bit bus modes. In the one-bit bus mode of SDMMC, only 3 IOs are required to access the SD card; while, the four-bit bus mode of SDMMC requires 6 IOs to access the SD card.
The above three methods can all be used to access the SD card, the difference of which lies in the speed.
When accessing an SD card, the fastest reading and writing speed is achieved under the four-bit bus mode of SDMMC. The one-bit bus mode of SDMMC offers a slightly slower access speed of around 80% compared to the four-bit bus mode. The slowest access speed is observed with the SPI mode, which offers only around 50% of the speed of the four-bit bus mode of SDMMC.
For most applications, we recommend using the one-bit bus mode because it requires the least number of IO pins while still providing good performance and speed.
4.1.3. Component knowledge
4.1.3.1. SD card read and write method
The ESP32-S3 offers two methods for accessing the SD card: SPI interface and SDMMC interface. The SPI mode requires 4 IOs to access the SD card, while the SDMMC interface supports both one-bit and four-bit bus modes. In the one-bit bus mode of SDMMC, only 3 IOs are required to access the SD card; while, the four-bit bus mode of SDMMC requires 6 IOs to access the SD card.
The above three methods can all be used to access the SD card, the difference of which lies in the speed.
When accessing an SD card, the fastest reading and writing speed is achieved under the four-bit bus mode of SDMMC. The one-bit bus mode of SDMMC offers a slightly slower access speed of around 80% compared to the four-bit bus mode. The slowest access speed is observed with the SPI mode, which offers only around 50% of the speed of the four-bit bus mode of SDMMC.
For most applications, we recommend using the one-bit bus mode because it requires the least number of IO pins while still providing good performance and speed.
4.1.3.2. Format SD card
To begin the project, it is essential to prepare a blank SD card and a card reader. Before proceeding, we need to create a drive letter for the SD card and format it. The following steps provide a guide on how to accomplish this on different computer systems. Please follow the guide that corresponds to your computer.
Note that this step requires a card reader and a blank SD card. Please ensure that you have these components available before proceeding.
4.1.3.3. Windows
Insert the SD card into the card reader, and then insert the card reader into the computer.
In the Windows search box, enter “Disk Management” and select “Create and format hard disk partitions”.
In the newly opened window, locate an unallocated volume with a size close to 1GB.
Click to select the volume, right-click and select “New Simple Volume”.
Click Next.
On the right-hand side, you can select a preferred drive letter for the SD card or simply proceed with the default setting by clicking on the “Next” button.
When formatting the SD card, select the file system as FAT (or FAT32) and set the allocation unit size to 16K. You can set the volume label to any name of your choice. Once you have made these selections, click on the “Next” button to proceed.
Click Finish. Wait for the SD card initialization to complete.
After completing the formatting process, you should be able to see the SD card in the “This PC” section of your computer.
4.1.3.4. MAC
Insert the SD card into the card reader and then insert the card reader into your computer. Some computers may display a prompt with the following message. In this case, please click on the “Ignore” option to proceed.
Find “Disk Utility” in the MAC system and click to open it.
Select “Generic MassStorageClass Media”, note that its size is about 1G. It is important to select the correct item to avoid accidentally erasing the wrong device. Once you have verified that you have selected the correct device, click on the “Erase” button to proceed with erasing the SD card.
Select the configuration as shown in the figure below, and then click “Erase”.
Please wait for the formatting process to complete. Once it is finished, the interface should resemble the image below. You should now be able to see a new disk named “SD” on your desktop.
4.1.4. Circuit
Before connecting the USB cable, insert the SD card into the SD card slot on the back of the ESP32-S3.
Connect Freenove ESP32-S3 to the computer using the USB cable.
4.1.5. Sketch
4.1.5.1. Sketch_04_SDMMC
Compile and upload the code to ESP32-S3-WROOM, open the serial monitor, and press the RST button on the board.
You can see the printout as shown below.
The following is the program code:
1#include "FS.h"
2#include "SD_MMC.h"
3
4#define SD_MMC_CMD 38 //Please do not modify it.
5#define SD_MMC_CLK 39 //Please do not modify it.
6#define SD_MMC_D0 40 //Please do not modify it.
7
8void setup() {
9 Serial.begin(115200);
10 SD_MMC.setPins(SD_MMC_CLK, SD_MMC_CMD, SD_MMC_D0);
11 int error = SD_MMC.begin("/sdcard", true, true, SDMMC_FREQ_DEFAULT, 5);
12 if (!error) {
13 Serial.printf("Card Mount Failed: %d\r\n", error);
14 return;
15 }
16 Serial.println("Card Mount Success.");
17
18 uint8_t cardType = SD_MMC.cardType();
19 if (cardType == CARD_NONE) {
20 Serial.println("No SD_MMC card attached");
21 return;
22 }
23
24 Serial.print("SD_MMC Card Type: ");
25 if (cardType == CARD_MMC) {
26 Serial.println("MMC");
27 } else if (cardType == CARD_SD) {
28 Serial.println("SDSC");
29 } else if (cardType == CARD_SDHC) {
30 Serial.println("SDHC");
31 } else {
32 Serial.println("UNKNOWN");
33 }
34
35 uint64_t cardSize = SD_MMC.cardSize() / (1024 * 1024);
36 Serial.printf("SD_MMC Card Size: %lluMB\n", cardSize);
37
38 listDir(SD_MMC, "/", 0);
39 createDir(SD_MMC, "/mydir");
40 listDir(SD_MMC, "/", 0);
41 removeDir(SD_MMC, "/mydir");
42 listDir(SD_MMC, "/", 2);
43 writeFile(SD_MMC, "/hello.txt", "Hello ");
44 appendFile(SD_MMC, "/hello.txt", "World!\n");
45 readFile(SD_MMC, "/hello.txt");
46 deleteFile(SD_MMC, "/foo.txt");
47 renameFile(SD_MMC, "/hello.txt", "/foo.txt");
48 readFile(SD_MMC, "/foo.txt");
49 testFileIO(SD_MMC, "/test.txt");
50 Serial.printf("Total space: %lluMB\n", SD_MMC.totalBytes() / (1024 * 1024));
51 Serial.printf("Used space: %lluMB\n", SD_MMC.usedBytes() / (1024 * 1024));
52}
53
54void loop() {
55
56}
Add the SD card drive header file.
1#include "FS.h"
2#include "SD_MMC.h"
The drive pins of the SD card are pre-defined and should not be modified as they are fixed. Altering the pins may result in errors or malfunctions while accessing the SD card.
1#define SD_MMC_CMD 38 //Please do not modify it.
2#define SD_MMC_CLK 39 //Please do not modify it.
3#define SD_MMC_D0 40 //Please do not modify it.
Initialize the serial port function. Sets the drive pin for SDMMC one-bit bus mode.
1Serial.begin(115200);
2SD_MMC.setPins(SD_MMC_CLK, SD_MMC_CMD, SD_MMC_D0);
Set the mount point of the SD card, set SDMMC to one-bit bus mode, and set the read and write speed to 20MHz.
1int error = SD_MMC.begin("/sdcard", true, true, SDMMC_FREQ_DEFAULT, 5);
2if (!error) {
3 Serial.printf("Card Mount Failed: %d\r\n", error);
4 return;
5}
Get the type of SD card and print it out through the serial port.
1uint8_t cardType = SD_MMC.cardType();
2if (cardType == CARD_NONE) {
3 Serial.println("No SD_MMC card attached");
4 return;
5}
6
7Serial.print("SD_MMC Card Type: ");
8if (cardType == CARD_MMC) {
9 Serial.println("MMC");
10} else if (cardType == CARD_SD) {
11 Serial.println("SDSC");
12} else if (cardType == CARD_SDHC) {
13 Serial.println("SDHC");
14} else {
15 Serial.println("UNKNOWN");
16}
Call the listDir() function to read the folder and file names in the SD card, and print them out through the serial port. This function can be found in “sd_read_write.cpp”.
1listDir(SD_MMC, "/", 0);
Call createDir() to create a folder, and call removeDir() to delete a folder.
createDir(SD_MMC, "/mydir");
removeDir(SD_MMC, "/mydir");
Call writeFile() to write any content to the txt file. If there is no such file, create this file first.
Call appendFile() to append any content to txt.
Call readFile() to read the content in txt and print it via the serial port.
1writeFile(SD_MMC, "/hello.txt", "Hello ");
2appendFile(SD_MMC, "/hello.txt", "World!\n");
3readFile(SD_MMC, "/hello.txt");
Call deleteFile() to delete a specified file.
Call renameFile() to copy a file and rename it.
1deleteFile(SD_MMC, "/foo.txt");
2renameFile(SD_MMC, "/hello.txt", "/foo.txt");
Call the testFileIO() function to test the time it takes to read 512 bytes and the time it takes to write 2048*512 bytes of data.
1testFileIO(SD_MMC, "/test.txt");
Print the total size and used size of the SD card via the serial port.
1Serial.printf("Total space: %lluMB\n", SD_MMC.totalBytes() / (1024 * 1024));
2Serial.printf("Used space: %lluMB\n", SD_MMC.usedBytes() / (1024 * 1024));
If you are interesting in the implementation of functions, you can check them out here.



