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. – Anonymous Penguin Aug 19 '14 at 22:06
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. – Alex Shroyer Nov 6 '15 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, privacy policy and cookie policy

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