Card detect and write protect
Two mechanical switches on the full-size board, pulled up to 3V3 and connected to nothing else. Neither is part of the card bus, neither does anything on its own, and the write-protect one is a request nothing enforces but your sketch.
Two switches, three states
begin() and you can print “no card” instead of a mount failure nobody can interpret.Both switches sit between their pin and ground, and both pins are pulled up to 3V3 through 10 kΩ on the board. So an open switch reads HIGH and a closed one reads LOW, and there are only three states worth caring about.
On the bench, a card in the socket read CD LOW, cross-checked against the mount succeeding; an unlocked card read WP HIGH. Both matched what the socket was physically doing.
CD is a fact, WP is an opinion
CD tells you a card is physically in the socket. Not that it is formatted, not that it works — a dead card pushes the contact down exactly as well as a good one. Its use is the message you print: "no card" is a better thing for a device in a cupboard to say than a mount failure.
WP tells you where the little slider on the side of the card is. That is all. The card does not refuse writes when the tab is down, the socket does not refuse them, and this board does not either. If you want the tab to mean anything, your sketch has to read it and decide — which is what the sketch above does, and why the check sits before the write rather than after it.
Cross-check your polarity
Different sockets wire these contacts differently, and a sketch that gets the polarity backwards fails in the most confusing way available: it insists there is no card while happily reading one.
So check CD against something that cannot lie. If the mount succeeded, there is a card. If CD disagrees with that, invert the test — the sketch above prints a line saying so rather than leaving you to work it out.
On the microSD board
Neither hole exists, and neither is missing. A microSD card has no lock tab, and this socket brings out no detect contact. The eight holes on that board are the whole of it.
The code
Read both switches before mounting, print what they say, and refuse to write if the card's lock tab is down. The cross-check at the end is the part worth keeping: if CD says no card and the mount succeeded, your polarity is inverted and the sketch tells you so.
// Wiring for this sketch. Full-size SD reader only, SPI 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 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 GPIO5 -> CD (hole 9)
// ESP32-S3 GPIO6 -> WP (hole 10)
//
// CD and WP are switches inside the socket, not bus lines. The board pulls
// both up to 3V3 through 10k, so an open switch reads HIGH.
//
// Arduino IDE: Tools > Board "ESP32S3 Dev Module", USB CDC On Boot
// "Enabled", Flash Size to match your board, Serial Monitor at 115200.
#include <SPI.h>
#include <SD.h>
#define SD_CS 10
#define SD_MOSI 11
#define SD_SCK 12
#define SD_MISO 13
#define CD_PIN 5
#define WP_PIN 6
SPIClass sdSPI(FSPI);
void setup() {
Serial.begin(115200);
delay(500);
// The board's own 10k pull-ups do the work; INPUT is enough.
pinMode(CD_PIN, INPUT);
pinMode(WP_PIN, INPUT);
bool cardIn = digitalRead(CD_PIN) == LOW; // switch closed to GND
bool lockedTab = digitalRead(WP_PIN) == LOW; // switch closed to GND
Serial.printf("CD %s, WP %s\n",
cardIn ? "card in" : "socket empty",
lockedTab ? "locked" : "unlocked");
if (!cardIn) {
Serial.println("no card - not trying to mount");
return;
}
sdSPI.begin(SD_SCK, SD_MISO, SD_MOSI, SD_CS);
bool mounted = SD.begin(SD_CS, sdSPI, 24000000);
// Cross-check: the mount is the ground truth about whether a card is there.
if (mounted != cardIn) {
Serial.println("CD disagrees with the mount - invert the LOW/HIGH test above");
}
if (!mounted) {
Serial.println("card present but would not mount - format it FAT32");
return;
}
if (lockedTab) {
Serial.println("lock tab is down - mounting read only, skipping the write");
} else {
File f = SD.open("/switches.txt", FILE_WRITE);
if (f) { f.println("written with the tab up"); f.close(); }
Serial.println("wrote /switches.txt");
}
}
void loop() {}Both pins are already pulled up to 3V3 by 10 kΩ resistors on the board, so plain INPUT is right and INPUT_PULLUP would only add a second, weaker pull-up in parallel. The full-size board has these two holes; the microSD board does not.
When it does not work
Either the wire is in the wrong hole, or the socket's detect contact is stuck. Count from the GND end: CD is hole 9 and WP is hole 10, the last two on the board. With the card out and the wire off the board entirely, the pin should read whatever your microcontroller's own pull-up does, which is a useful way to prove the wire is the problem.
That is correct behaviour and it is the point of this page. Nothing in the card or the socket enforces the lock tab — it is a note to the host, and your sketch is the host. If you want the tab to mean something, read WP and skip the write yourself, as the sketch above does.
Different sockets wire these switches differently. Change the two comparisons from LOW to HIGH and the rest of the sketch is unchanged. The cross-check against whether the mount succeeded is there to catch exactly this, so run it once with a card in and once with the socket empty.
It has neither, and that is not a missing feature. A microSD card has no lock tab to detect, and this microSD socket brings out no detect contact. If you need to know whether a card is present on the small board, try to mount it — a failed mount and an empty socket look the same to your sketch, which is usually enough.
The reference page: both boards, the full pin table, the downloads and the questions this handbook did not answer.
Back to the SD readers →Edit this page — content/books/sd/card-detect-and-write-protect.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.