0

I'm currently working on a project using an ESP32 (the Waveshare ESP32 Driver Board), and I am trying to read data from an SD card, but consistently getting a "SD Card Mount Failed" error. I am using the Adafruit SD card reader breakout board and the Arduino IDE.

Here's how I've wired the SD card reader to the ESP32

SD card     ESP32
-------     -----
3.3V        3.3V
GND         GND
CLK         pin 18 (SCK)
DO          pin 19 (MISO)
DI          pin 23 (MOSI)
CS          pin 5 (SS)

And here's the relevant code I'm using to setup and test the SD card:

#define SCK  18
#define MISO  19
#define MOSI  23
#define CS  5

int setup_sd_card() {
  
  SPIClass spi = SPIClass(VSPI);
  spi.begin(SCK, MISO, MOSI, CS);

  if (!SD.begin(CS,spi,80000000)) {
    Serial.println("ERROR: SD Card Mount Failed");
    return -1;
  }
  uint8_t cardType = SD.cardType();
  
  if(cardType == CARD_NONE){
    Serial.println("ERROR: No SD card attached");
    return -1;
  }

  // Code to print out SD card details...

  return 1;
}

I've triple-checked my wiring but the code always fails at if (!SD.begin(CS,spi,80000000)). I've tried 3 different SD cards of different sizes, all formatted to FAT32 (64GB, 256GB, 1024GB)

Could the issue be related to the ESP32 not being a stock one because it has some hardware for driving an e-paper screen? Here is the schematic: https://www.waveshare.com/w/upload/8/80/E-Paper_ESP32_Driver_Board_Schematic.pdf

Waveshare ESP32 Schematic

Can anyone suggest what might be the issue or what else I could try to debug this problem? Any help would be greatly appreciated.

3
  • The Waveshare esp32 appears to use the following SPI pins for the screen. P13: spi clk; P14: spi mosi; P15: cs (not shared). For clk, miso and mosi you should use the same pins. Try printing out the existing values of clk, miso and mosi without (re-) defining them. Only the cs pin is unique to the peripheral. The remaining SPI pins are a shared bus.
    – 6v6gt
    Commented Aug 2, 2023 at 7:31
  • I moved the SPIClass declaration to a global variable and changed the frequency down to 4 from 80 but I'm getting the same result. Thanks for the suggestion.
    – Mike Buss
    Commented Aug 2, 2023 at 11:52
  • I also printed out the existing values of MOSI/MISO/SCK/SS after deleting my redefinition of them and they are: MOSI: 23 MISO: 19 SCK: 18 SS: 5 ; I can try using the same SPI pins the screen uses and see if that works. I'll update this when I know.
    – Mike Buss
    Commented Aug 2, 2023 at 12:32

2 Answers 2

1
+100

There are at least two problems with your code.

First I think you have a typo in the frequency. Default frequency is 4 MHz, but your parameter in begin is 80 MHz, which I doubt will work.

You initialize the spi object on the stack in the function and then supply it to the SD instance. The spi object on stack will be removed when the function ends and the SD object will crash. It has to be an allocation on heap as SPIClass* spi = new SPIClass(VSPI); or a global variable SPIClass spi(VSPI);.

And since you use the default pins of VSPI you can use just spi.begin() without the pin numbers.

0

The issue turned out to be a faulty SD card.

I had tried other SD cards but must have used incorrect wiring for them.

EDIT: Here is the updated code:

#define CS        5
#define SCK       18
#define MOSI      23
#define MISO      19

SPIClass spi(VSPI);

int setup_sd_card() {
  spi.begin(SCK, MISO, MOSI, CS);

  if (!SD.begin(CS,spi,4000000)) {
    Serial.println("ERROR: SD Card Mount Failed");
    delay(1000);
    return -1;
  }
  Serial.println("Finished initializing SD card. Getting card type...");

  uint8_t cardType = SD.cardType();
  
  if(cardType == CARD_NONE){
    Serial.println("ERROR: No SD card attached");
    delay(1000);
    return -1;
  }

  Serial.print("SD Card Type: ");
  if (cardType == CARD_MMC){
    Serial.println("MMC");
  } else if(cardType == CARD_SD){
    Serial.println("SDSC");
  } else if(cardType == CARD_SDHC){
    Serial.println("SDHC");
  } else {
    Serial.println("UNKNOWN");
  }
  Serial.printf("Total space: %lluMB\n", SD.totalBytes() / (1024 * 1024));
  Serial.printf("Used space: %lluMB\n", SD.usedBytes() / (1024 * 1024));

  Serial.println("SUCCESS! (SD CARD)");
  
  return 1;
}
3
  • does it work with the code as it is in the Question?
    – Juraj
    Commented Aug 2, 2023 at 13:43
  • I just edited my answer to add the code that works. It's the same as above with the two suggestions given in the comments.
    – Mike Buss
    Commented Aug 2, 2023 at 14:01
  • so it doesn't begin at 80 mega? what about 8 mega?
    – Juraj
    Commented Aug 2, 2023 at 14:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.