SD card not always registering

Hi, I'm trying to figure out why my sd card sometimes work. but then at some point just stops working and keeps throwing:

SD card initialization failed!
begin() failed
Do not reformat the SD.
SdError: 0X17,0XFF

the hardware is the following:

The setup code I'm using is the following:

// Setup handlers
CardHandler cardHandler = CardHandler();

//
void setup()
{
  Serial.begin(115200);

  while (!Serial)
  {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }
  Serial.println("Connected to WiFi");

  // Print the local IP address
  Serial.print("Local IP address: ");
  Serial.println(WiFi.localIP());

  // print the gateway IP address
  Serial.print("Gateway IP address: ");
  Serial.println(WiFi.gatewayIP());

  // print the subnet mask
  Serial.print("Subnet mask: ");
  Serial.println(WiFi.subnetMask());

  // disable bluetooth
  esp_bt_controller_disable();

  // Add some delay so we can see the serial output
  try
  {
    // initialize card reader
    cardHandler.init();
    Serial.println("Card reader initialized");

  }
  catch (const std::exception &e)
  {
    Serial.println(e.what());
    while (true)
    {
      delay(1000);
    }
  }
}

the cardreader looks like this:

#include "FS.h"
#include "SPI.h"
#include <SdFat.h>
#include "Wire.h"
#include "CardReader.h"

// Try to select the best SD card configuration.
#if HAS_SDIO_CLASS
#define SD_CONFIG SdioConfig(FIFO_SDIO)
#elif ENABLE_DEDICATED_SPI
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SPI_CLOCK)
#else // HAS_SDIO_CLASS
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SPI_CLOCK)
#endif // HAS_SDIO_CLASS

CardHandler::CardHandler()
{
}

void CardHandler::init()
{
  try
  {
    Serial.println("CardHandler Setup");

    if (!_sd.begin(SD_CONFIG))
    {
      Serial.println("SD card initialization failed!");
      _sd.initErrorHalt(&Serial);
      return;
    }

    uint32_t size = _sd.card()->sectorCount();
    if (size == 0)
    {
      Serial.println("Can't determine the card size.\n");
      return;
    }

    Serial.print("Card size: ");
    Serial.print(size / 1024);
    Serial.println(" MB");
  }
  catch (const std::exception &e)
  {
    Serial.println("CardHandler Setup Failed");

    Serial.print("Exception: ");
    Serial.println(e.what());
  }
  catch (...)
  {
    Serial.println("CardHandler Setup Failed");
  }
}

file_t CardHandler::getFile(const char *filename, uint8_t oflag)
{
#if SD_FAT_TYPE == 0
  File file;
#elif SD_FAT_TYPE == 1
  File32 file;
#elif SD_FAT_TYPE == 2
  ExFile file;
#elif SD_FAT_TYPE == 3
  FsFile file;
#else // SD_FAT_TYPE
#error Invalid SD_FAT_TYPE
#endif // SD_FAT_TYPE

  // Open or create
  if (!file.open(filename, oflag))
  {
    _sd.errorHalt(&Serial, "Failed to open file for writing");
    return file_t();
  }

  // Return
  return file;
}

void CardHandler::removeFile(const char *filename)
{
  if (!_sd.remove(filename))
  {
    _sd.errorHalt(&Serial, "Failed to remove file");
  }
}

void CardHandler::closeFile(file_t file)
{
  file.close();
}

and it's header file

#ifndef CARD_READER_H
#define CARD_READER_H

#include <FS.h>
#include <SD.h>
#include <SdFat.h>
#include <driver/i2s.h>
#include <Arduino.h>

#define SD_FAT_TYPE 2

// SDCARD_SS_PIN is defined for the built-in SD on some boards.
#ifndef SDCARD_SS_PIN
const uint8_t SD_CS_PIN = GPIO_NUM_5;
#else  // SDCARD_SS_PIN
// Assume built-in SD is used.
const uint8_t SD_CS_PIN = SDCARD_SS_PIN;
SDCARD_SS_PIN
#endif //

// Try max SPI clock for an SD. Reduce SPI_CLOCK if errors occur.
#define SPI_CLOCK SD_SCK_MHZ(50)

#if SD_FAT_TYPE == 0
typedef File file_t;
typedef SdFat sd_t;
#elif SD_FAT_TYPE == 1
typedef SdFat32 sd_t;
typedef File32 file_t;
#elif SD_FAT_TYPE == 2
typedef SdExFat sd_t;
typedef ExFile file_t;
#elif SD_FAT_TYPE == 3
typedef SdFs sd_t;
typedef FsFile file_t;
#else // SD_FAT_TYPE
#error Invalid SD_FAT_TYPE
#endif // SD_FAT_TYPE

class CardHandler
{
public:
  CardHandler();
  void init();
  file_t getFile(const char *filename, uint8_t oflag = O_APPEND | O_WRITE | O_CREAT);
  void removeFile(const char *filename);
  void closeFile(file_t file);

private:
  sd_t _sd;
  bool _connected;
};

#endif // CARD_READER_H

I've been trying a lot of things (changing baudrate, the clockspeed, ...). but it's just random when it starts failing and when it works.
Sometimes reformatting does the trick, sometimes this doesn't do anything

I'm scratching in my hair trying to find this out

Reduce SPI_CLOCK.

These are the same links.

Is your wiring correct?

Please post a schematic of your wiring.

Hi,

Thanks for the quick response. I've updated the card linkie: https://www.aliexpress.com/item/1005005171638894.html?spm=a2g0o.order_list.order_list_main.16.5bef1802YzJ3El

I have been lowering the SPI_CLOCK up untill 5 mhz and still having the same error. Should I lower it even further? seems like 10% of the default value should already be enought to validate that this isn't the reason why it isn't working?

Wiring diagram is the following:

3V3 = 3v3
GPIO5 = CS
GPIO23 = MOSI
GPIO18 = CLK
GPIO19 = MISO
GND = GND

They are currently wired on a breadboard. the board is connected via USB to my pc, and I use the 3v3 pins of the nodemcu to power the sdcard reader

Unfortunately only sd card sizes up to 32GB are guaranteed to be supported by Arduino or SdFat.

Either partition your card to 32GB and format with FAT32, or buy a 32GB card. :slightly_smiling_face:

I don't think partitioning will make a difference. The large cards operate differently. But my memory is that SdFat, or at least one version of it, will handle SDXC cards, which is what that link points to.

It may be that the 3.3V ouput of the nodemcu is not capable of supplying enough current to power the SD card properly. If you could put a scope lead on that line, it should show any drooping.

I have partitioned a 64GB card to ~30GB and it works fine.

This could quite likely be the problem, but still not sure about running the large capacity SD card. :expressionless:

Ok. I must be wrong about that. I guess SDHC and SDXC address sectors and clusters the same way. So if you partition to 32GB and format as FAT32, it will work. But I think version 2 of SdFat may support SDXC and xFAT directly.

1 Like

It is quite possible that this is the source of your random SD card failures.

Would I be correct in assuming that the error relates to initialising the SD card on power on?

Does your setup operate as you intended if it gets past the SD card initialisation?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.