Switching to 4-bit mode
Two more wires into the holes marked NC, a different library, and no chip select at all. On an ESP32-S3 you may choose the six pins; on the original ESP32 you may not, and one of the fixed six can stop the board booting.
The two extra wires
Set the Mode control to 4-bit. Two new wires appear, and they land in the holes the front of the board calls NC — DATA2 in hole 3 and DATA1 in hole 8.
The hole printed CS is still wired, but it is not a chip select any more. In
SD mode it is DATA3, the fourth data line, and SD_MMC never asks you for a
chip select at all.
Which pins you may use
On an ESP32-S3, S2 or C3 the card host goes through the GPIO matrix, so
SD_MMC.setPins() works and any six free pins will do. Keep off GPIO19 and
GPIO20 — those are the USB pair — and off the strapping pins 0, 3, 45 and 46.
On the original ESP32 there is no choice. The six pins are fixed, one of them is GPIO12, and GPIO12 is read at reset to choose the flash voltage. A data line sitting high on it is a board that will not start. If you are on a classic ESP32, 1-bit mode uses only CLK, CMD and D0, never touches GPIO12, and gives up about a third of the read speed for the peace.
What good looks like
card mounted, 30436 MB
read back: four data linesSame two lines as the SPI sketch. What is different is what happened to get there: six signal wires, no chip select, and a bus clock the driver negotiated rather than one you fixed.
If it will not mount at 40 MHz
Ask for 20000 instead. A mount that works at 20 MHz and fails at 40 is a
wiring result, not a card result — the card is the same card either way. Four
wires, one clock is what to do about it, and
the short version is: shorten the ground wire, cut the four data wires to the
same length, and stop.
The code
The same write-and-read-back as the SPI version, in SD_MMC 4-bit mode. It prints the bus frequency it settled on, which is the number that tells you whether your wiring is good enough for the mode you asked for.
// Wiring for this sketch. Either board, SD_MMC 4-bit mode. Holes counted
// from the GND end, with the name printed on the front and then on the back.
//
// ESP32-S3 3V3 -> 3V3 (hole 2)
// ESP32-S3 GND -> GND (hole 1)
// ESP32-S3 GPIO9 -> NC (hole 3, printed DATA2 on the back)
// ESP32-S3 GPIO10 -> CS (hole 4, printed DATA3 on the back)
// ESP32-S3 GPIO11 -> MOSI (hole 5, printed CMD on the back)
// ESP32-S3 GPIO12 -> SCK (hole 6, printed CLK on the back)
// ESP32-S3 GPIO13 -> MISO (hole 7, printed DATA0 on the back)
// ESP32-S3 GPIO14 -> NC (hole 8, printed DATA1 on the back)
//
// The two holes printed NC are wired to the card and pulled up on the
// board. 4-bit mode needs both of them, and all four data lines must reach
// the microcontroller - the pull-ups alone are not enough.
//
// Arduino IDE: Tools > Board "ESP32S3 Dev Module", USB CDC On Boot
// "Enabled", Flash Size to match your board, Serial Monitor at 115200.
// setPins() needs an S3, S2 or C3 core - the original ESP32 has fixed pins.
#include <FS.h>
#include <SD_MMC.h>
#define SDMMC_CLK 12
#define SDMMC_CMD 11
#define SDMMC_D0 13
#define SDMMC_D1 14
#define SDMMC_D2 9
#define SDMMC_D3 10
void setup() {
Serial.begin(115200);
delay(500);
if (!SD_MMC.setPins(SDMMC_CLK, SDMMC_CMD, SDMMC_D0, SDMMC_D1, SDMMC_D2, SDMMC_D3)) {
Serial.println("setPins failed - this chip has fixed SD_MMC pins");
return;
}
// mountpoint, mode1bit = false, format_if_mount_failed = false, kHz
if (!SD_MMC.begin("/sdcard", false, false, 40000)) {
Serial.println("no card at 40 MHz - check D1, D2 and D3, then try 20000");
return;
}
Serial.printf("card mounted, %llu MB\n", SD_MMC.cardSize() / (1024ULL * 1024ULL));
File f = SD_MMC.open("/hello4.txt", FILE_WRITE);
if (!f) { Serial.println("mounted, but could not open /hello4.txt"); return; }
f.println("four data lines");
f.close();
f = SD_MMC.open("/hello4.txt");
Serial.print("read back: ");
while (f.available()) Serial.write(f.read());
f.close();
}
void loop() {}If it fails to mount, ask for 20000 instead of 40000 and try again. If that works, the wiring is the limit rather than the card — see Four wires, one clock. SD_MMC takes its frequency in kHz, not Hz, which is the easiest typo to make here.
When it does not work
The two extra wires. 4-bit mode needs DATA1, DATA2 and DATA3 all reaching the microcontroller, and the board's 10 kΩ pull-ups on their own are not enough — a data line the host never drives leaves the card unsure which mode it is in. Count the holes again: DATA2 is hole 3 and DATA1 is hole 8, both printed NC on the front.
A card that has already answered in SPI stays in SPI until its supply is cut, so running the SPI sketch and then this one on the same power-up will not work. Unplug the board rather than pressing reset.
You are on an original ESP32 rather than an S3, S2 or C3. Its card host is wired to one fixed set of pins, so delete the setPins() call and wire CLK to GPIO14, CMD to GPIO15, D0 to GPIO2, D1 to GPIO4, D2 to GPIO12 and D3 to GPIO13 instead. Read the note about GPIO12 before you do.
Almost certainly GPIO12 on a classic ESP32. That pin is read at reset to choose the flash voltage, and a data line resting high on it can leave the board refusing to start. Unplug the D2 wire, confirm the board boots, and then use 1-bit mode — CLK, CMD and D0 only — which never touches GPIO12.
The two switches on the full-size board, what each state reads, and why nothing enforces the lock tab except your sketch.
Card detect and write protect →Edit this page — content/books/sd/switching-to-four-bit.mdx
Questions about this product
See what other owners have asked, and read their solutions.
This page covers several products. Choose yours to see the right discussions.
Discuss this article
Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.