SD Card initialization failed - need to remove / reinsert

Hi Arduino community,

I have developped an Arduino prototype to control my swimming pool equipments. For that I needed to have a SD Card Reader (to save data parameters) and an Ethernet link (to access my sensors through Internet with MQTT).

Everything is working fine. But randomly, when I restart the Arduino board, SD card is failing to initialize... I need to remove and reinsert the SD card to unblock the setup immediately.

Hereunder, my setup part of my code. The part which stuck randomly is the function SD.begin(chipSelect)...

Do you see something wrong ?

Technical parts used : Arduino Mega Board R3 / Arduino Ethernet Shield 2 (W5500)

void setup(void) {
  pinMode(12, INPUT);
  pinMode(20, INPUT_PULLUP);
  pinMode(21, INPUT_PULLUP);

  u8g2.begin();
  u8g2_prepare();
  u8g2.clearBuffer();

  // Disable SD SPI
  pinMode(4, OUTPUT);
  digitalWrite(4, HIGH);

  u8g2.drawStr(2, 2, "Init Ethernet...");
  u8g2_prepare();
  u8g2.sendBuffer();
  // Lancement de la connexion Ethernet en DHCP
  if (Ethernet.begin(MAC) == 0) {
    u8g2.clearBuffer();

    u8g2.drawStr(2, 2, "Erreur DHCP.");
    if (Ethernet.hardwareStatus() == EthernetNoHardware) {
      u8g2.drawStr(2, 12, "Erreur Shield.");
    } else if (Ethernet.linkStatus() == LinkOFF) {
      u8g2.drawStr(2, 12, "Cable RJ45 deconnecte.");
    }

    u8g2.drawStr(2, 22, "Passage IP fixe.");
    Ethernet.begin(MAC, IP);

    u8g2_prepare();
    u8g2.sendBuffer();
  }

  u8g2.drawStr(2, 12, "Init SD Card...");
  u8g2_prepare();
  u8g2.sendBuffer();
  setupSDCard();
  String strHeures = lireHeuresMarchesPompe();
  // Initialise le tableau des heures qui est sauvegardé, au démarrage
  int indice = 0;
  for (int i = 0; i < strHeures.length(); i++) {
    if (strHeures.substring(i, i + 1) == "0") {
      heures_marche_pompe[indice] = 0;
      indice++;
    } else if (strHeures.substring(i, i + 1) == "1") {
      heures_marche_pompe[indice] = 1;
      indice++;
    }
  }

  pinMode(pinPompe, OUTPUT);
  pinMode(pinEclairage, OUTPUT);
  pinMode(pinInterrupteurEclairage, INPUT);
  pinMode(pinBoutonConfiguration, INPUT);
  pinMode(pinInterrupteurConfigurationPH, INPUT);
  pinMode(pinInterrupteurConfig3, INPUT);

  u8g2.drawStr(2, 22, "Init RTC...");
  u8g2_prepare();
  u8g2.sendBuffer();
  rtc.begin();

  //rtc.adjust(DateTime(2023, 5, 11, 8, 30, 00));  // Pour mettre à jour l'heure du module RTC

  mqttClient.setCallback(callback);

  // Première initialisation des capteurs
  initialiserPH();

  temperatureAir = getTemp(ds);
  temperatureEau = getTemp(dsEau);

  // Gestion du bidon PH
  if (digitalRead(pinBidonPH) == HIGH) {
    bidonPHVide = false;
    afficherErreur = false;
    texteErreur = "";
  } else {
    bidonPHVide = true;
    afficherErreur = true;
    texteErreur = "Bidon pH bas...";
  }

  wdt_enable(WDTO_4S);

  wdt_reset();
}

void setupSDCard() {
  pinMode(53, OUTPUT);
  digitalWrite(53, HIGH); // Workaround pour éviter les initialization failed
  pinMode(10, OUTPUT);      // set the SS pin as an output (necessary!)
  digitalWrite(10, HIGH);   // but turn off the W5100 chip

  while (!SD.begin(chipSelect)) { }

  if (!SD.exists("heures.txt")) { 
    File myFile = SD.open("heures.txt", FILE_WRITE);
    myFile.close();
  }
}

Thank you !

what is the value of chipSelect?

const int chipSelect = 4;

did you try to initialize the SD card before Ethernet?
but remove all other attempts to fix the problem. the pinmode and high for 4, 10, 53 and the while for SD.begin

  • How do you power the SD Card Module? Do you use the 5V supplied by the MEGA Board or do you have a external power supply? It's recommandable to use external power supply because the SD module need up to 200mA
  • play safe that you used MISO (D50), MOSI (D51), SCK (D52)
  • in my cases i use D53 for chip select which is also marked as SPI "Slave Select" on the pin definition of the MEGA Board. I recommend that you try this out

Yes I will try to init SD Card before but same problem (randomly again).

Your proposal is to remove the pinmode set for 4, 10, 53 (I was reading that it was needed to have SD Card and Ethernet work together) and the while (if I remove the while, I think my SD card will be not initialised randomly).

Thanks for your help :slight_smile:

Yes I used an external power supply (official from Arduino).

So I have to try to init my SD Card with 53 instead of 4 for chipSelect ?

pin 10 has a pullup on the shield (at least on the Arduino Ethernet 2 shield).
pin 53 is initialized and set high by the SPI library.
if you initialize the SD library first it will set pin 4.

@alexandertonn it is the Ethernet shield. it takes power from the 5 V pin and converts it to 3.3 V for W5500 and the SD card. 5 V is from USB.

Not sur to understand your sentence : * play safe that you used MISO (D50), MOSI (D51), SCK (D52)

What does it mean ?

ignore it. you use the shield and it connects to the SPI header

Ok perfect I will try to setup the SD card first.

I will let you if it works or not (as it is randomly, maybe in a couple of days).

By any chance, is there a better way to store some data in Arduino instead of using SD Card ? I see EEPROM could help but it seems to be limited...

ignore it. you use the shield a it connects to the SPI header

ah yes, you are right. I forgot the ethernet shield. :see_no_evil:

By any chance, is there a better way to store some data in Arduino instead of using SD Card ? I see EEPROM could help but it seems to be limited...

I would only use the EEPROM for storing persistent variables which are not written very often, because the write/erase cycles limited to round about 100.000 which is not less but if you write datas each second you will have some problems in the near future.

A question is raised to me : if I remove the while, and if my problem of random is not solved, then my program will crash when I try to access my SD Card in the loop part. Keep the while avoid me that. Right ?

I see also that my issue can be corrected with :

SD.setSpiClock(8);  // Reduces the SPI clock rate to 1MHz (8 times slower)

Do you think it could be a solution ?

  if (!SD.begin(chipSelect)) {
    Serial.println("SD initialization failed.");
    while (true);
  }

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