3

When I remove the SD card and try to open a file, I can detect the error properly.

But how do I detect that the card has been replaced after an error? My first thought was to call SD.begin() again but it appears that this function returns true exactly once and false thereafter.

Simplified example:

void setup() {
  SD.begin(pin); // called exactly once. Works.
}
void loop() {
  // stuff
}

But this does not:

void setup() {
  SD.begin(pin); // first time calling this function: works.
}
void loop() {
  delay(1000);
  SD.begin(pin); // always fails
}

I'd rather not reset the microcontroller just for this.

1
  • I'm looking for a SD.end() function somewhere. That is what you need, but I can't find anything in the reference. Commented Aug 19, 2014 at 22:06

2 Answers 2

3

I know this question is relatively old but still, if you wnat to run SD.begin(chipselect); again first call if(root.isOpen()) root.close(); I added this to the library. This way SD.begin(chipselect) will return true if a card is present and false when it's not.

1
  • 1
    Are you talking about this fix? AFAIK it's not been merged into master. Still, a better solution than what I had before. Thanks. Commented Nov 6, 2015 at 14:23
1

Update

A software reset, while inelegant, was much simpler to implement and debug than trying to add "retry" type functionality to SD.h. The other alternative would be to access SDFatLib.h or the other lower-level stuff (which SD.h is a wrapper for) directly, so if someone has that solution, I'll accept it instead of this one.

Original

Here is something, which is working well enough for me at the moment: does not reliably work:

bool SDState{false};
File LogFile;

bool trySDCard(void)
{
    // sanity check: maybe the SD card is actually here?
    LogFile = SD.open("test.txt", FILE_WRITE);
    delay(10);
    if (LogFile) {
        LogFile.close();
        return true;
    }
    int8_t counter{10};
    while (counter && !SDState) {
        SDState = SD.begin(TFT_CARD_CS);
        Serial.print(counter);
        Serial.print(" ");
        counter--;
        delay(100);
    }   
    Serial.print("SD: ");
    Serial.println(SDState);
    return SDState;
}

void setup() {
    SDState = SD.begin(TFT_CARD_CS);
    Serial.begin(115200);
}

void loop() {
    // NB. Simplified a lot (exitMenuMessage(string) is my custom function defined elsewhere)
    switch (state) {
        case SD_RETRY:
            exitMenuMessage(trySDCard() ? "found SD card" : "no SD card");
            break;
    }
}

Seems to work Sometimes works if I insert the SD card while trySDCard() is running.

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.