user889: 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.

user889: 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.

user14624: 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.

889: <p>When I remove the SD card and try to open a file, I can detect the error properly.</p>

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

<p>Simplified example:</p>

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

<p>But this does not:</p>

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

<p>I'd rather not reset the microcontroller just for this.</p>
 889: <h1>Update</h1>

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

<h1>Original</h1>

<p>Here is something, which <s>is working well enough for me at the moment:</s> does not reliably work:</p>

<pre><code>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 &amp;&amp; !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;
    }
}
</code></pre>

<p><s>Seems to work</s> Sometimes works if I insert the SD card <em>while</em> <code>trySDCard()</code> is running.</p>
 14624: <p>I know this question is relatively old but still, if you wnat to run  <code>SD.begin(chipselect);</code> again first call <code>if(root.isOpen()) root.close();</code> I added this to the library. This way <code>SD.begin(chipselect)</code> will return <code>true</code> if a card is present and <code>false</code> when it's not.</p>
