0

I am working on an Arduino application that logs sensors values into SD files. It is essential that the SD is inserted and working when a test is started, thus I need to check the presence of the SD regularly (every 2 seconds or so) to prevent launching a test without SD inserted by the user.

When I run the following code, it runs very fast when the SD test succeeds (<10ms), but it takes more than 2000ms when the test fails. Is there another test I could run that does not takes 2 seconds to indicate that the SD is not inserted (or not working)? All my buttons are frozen and they do not trigger any action while checking if no SD is inserted.

Here is my code (both loops have the same issue):

#define csSD   53
#include <SD.h>

Sd2Card card;

void setup() {
  Serial.begin(57600);
  bool SDOK = SD.begin(csSD);
  if(SDOK) {
    Serial.println("SD.Begin Setup OK");
  } else {
    Serial.println("SD.Begin Setup Fail");
  }
}

unsigned long t;
//void loop() {
//  t=millis();
//  if(SD.begin(csSD)){ // SD.Begin test runs fast when there is a SD, even though it return true when you try to begin SD a second time
//    Serial.print("SD.Begin loop OK : ");
//  }else {
//    Serial.print("SD.Begin loop Fail : ");
//  }
//  Serial.println(String(millis()-t)+"ms");
//  delay(500);
//}

void loop() {
  t=millis();
  if(card.init(SPI_HALF_SPEED, csSD)) {
    // card.init test returns true as it should (when SD is present and working), but runs fast only when SD is working
    Serial.print("card.init loop OK : ");
  } else {
    Serial.print("SD.Begin loop Fail : ");
  }
  Serial.println(String(millis()-t)+"ms");
  delay(500);
}
2
  • Many SD card sockets have a presence detect switch, of course something in the socket which activates that is not necessarily a functional SD card. Oct 18 '16 at 18:09
  • What if you attempt to read from a card if it's not inserted. Maybe this can return the state of the SD card faster.
    – Paul
    Nov 17 '16 at 17:15
1

The SD library builds on the sdfatlib library, in which SD_INIT_TIMEOUT is defined as 2000 ms, which gives your 2 second timeout. You could try lowering that number to get a faster response, although that may run the risk of timing out even when a card is present.

Four different timeout periods are defined in the sdfatlib source:

/** init timeout ms */
uint16_t const SD_INIT_TIMEOUT = 2000;
/** erase timeout ms */
uint16_t const SD_ERASE_TIMEOUT = 10000;
/** read timeout ms */
uint16_t const SD_READ_TIMEOUT = 300;
/** write time out ms */
uint16_t const SD_WRITE_TIMEOUT = 600;

The 300 ms read timeout is faster, as @Paul suggests in his comment, so you could just use a card read as the test rather than an initialisation, or try setting the init timeout to 300 instead. A read test would be simpler, as it doesn't involve modifying library files. It might not cope with a re-inserted card, though - I suspect that requires reinitialisation each time.

Note: the version of sdfatlib included with the SDlib in my Arduino install appears rather older than the current version. The included version defines the timeouts in Sd2Card.h, while the latest has is in SdInfo.h. The snippet above is from the older, included code.

0

You could always try this very simple sketch. I have never measured how quick it runs, but it is pretty quick.

Serial.print("Initializing SD card...");

  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

Just make sure to change 4 in !SD.begin(4) to whatever your ChipSelect pin happens to be for your component.

Furthermore, you could add a return statement after your "initilization fails" loop because that will immediately stop the program, after all you do not want to run it if the SD card is not reading data! And last thing, it may be a little overkill to check the SD card after initial initilization, after all, it will be highly unlikely for an error to occur once everything is working fine unless you mess with the SD card alot while it is running, which I am sure you won't.

4
  • This sketch is not working as I would like it to : if placed in setup, it works fine, but as soon as it is run a second time, it returns false. See : arduino.stackexchange.com/questions/3850/… Also, when no SD is inserted, this test takes 2000 to 2300ms on my device.
    – Etienne P.
    Jul 20 '16 at 9:05
  • Have you tried removing the verification from the loop itslef. Like I mentioned before, you should not need to verify the SD card every time you run through the loop, that is a bit overkill.
    – tyler a
    Jul 20 '16 at 11:16
  • If you perform the check out of the loop, it would work. However, in my application, I need to check the SD regularly as the Arduino board will be embedded into a package and will not be able to reset if not by shutting down the power of the whole machine. Also, the user will want to remove the SD to transfer the file onto the computer while the board is on. I would like to prevent a test start if no SD is detected. Thus, I would prefer regular checks on the SD.
    – Etienne P.
    Jul 21 '16 at 8:26
  • If you will have interaction with the SD Card while it is reading, you could potentially have the SD Card detection happen once every 30 seconds or so to prevent from constant button freezing. Or, you could have a manual check at the push of a button or input from the Serial Monitor, so that will allow you to check the SD at you disgression.
    – tyler a
    Jul 21 '16 at 10:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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