Runtime remove and insert a SD card ?

Hi,

I would like to remove and insert a SD card while the Arduino is running.
There is no SD.end() function in the library, and I don't know if SD.begin() can be called repeatedly.

I am using the normal Arduino SD library. The SD socket is on a Ethernet Shield attached to a Mega board. The Mega board is running a website, and I would like to keep that running.

An 'eject' button will be added to disable the use of the SD card, so I can safely remove the SD card.
Inserting the SD card and continue the website from the SD card is the problem.

Is this possible with the normal SD library, or do I have to reset the Arduino after inserting the SD card ?

You can remove the the SD after closing all files that are open for write.

The SD.h library has an old bug that prevents a second call to begin().

The bug is in the wrapper for the old version SdFat used with SD.h.

Add the line shown below.

boolean SDClass::begin(uint8_t csPin) {
  /*

    Performs the initialisation required by the sdfatlib library.

    Return true if initialization succeeds, false otherwise.

   */
  if (root.isOpen()) root.close();  // <<<<<<<<<<<<<<<<<<  ADD THIS LINE

  return card.init(SPI_HALF_SPEED, csPin) &&
         volume.init(card) &&
         root.openRoot(volume);
}

I have been trying to get the Arduino company to fix the many bugs in SD.h for five years with little success.

Thanks fat16lib, you are always a great help with questions about SD storage.

I know the Arduino SD library is an old version of your library, but I don't want to change the library every time I upgrade to a new version. I also develop my sketch with different OS's and different Arduino IDE's.

The Arduino SD library and Wire library definitely need an upgrade.

but I don't want to change the library every time I upgrade to a new version

I understand. There are about a dozen bugs in SD.h that would be easy to fix. I submitted fixes years ago but only one minor performance problem was fixed.

SD.h is adequate for most users and 20-30 lines of code would fix bugs that keep biting users.

Is it of any benefit to set the SD card interface's CS pin low prior to ejecting the card?

Hi,

This thread is quite timely for a project I am working on.

I have a log file on on the SD. I added the following to my command parser:

    // After inserting the SD card.
    case 'i':
        reopenLog();
        break;
    // Before removing the SD card.
    case 'e':
        closeLog();
        break;

then added the following routines:

bool
closeLog(void)
{
    Logfile.close();
}

bool
reopenLog(void)
{
    SdFile::dateTimeCallback(sdDateTime);
    Logfile = SD.open(logFileName, FILE_WRITE);
    Logfile.seek(Logfile.size());
}

Before someone mentions it, I know I need to check results of the close/open calls and return the proper bool...
Not sure why the compiler didn't flag this for me.

Does this look about right?

Steve

I've played around with things a bit, here's my final code:

bool
useSD(void)
{
    // See if the card is present and can be initialized:
    if (!SD.begin(cardSelect)) {
        return false;
    }

    return true;
}

void
closeLog(void)
{
    Logfile.close();

    delay(50);
    digitalWrite(cardSelect, LOW);
}

bool
reopenLog(void)
{
    useSD();

    Logfile = SD.open(logFileName, FILE_WRITE);
    if (! Logfile) {
        Out.printf(OUT_SERIAL, "couldn't reopen: %s\n", logFileName);
        return false;
    }

    if (Logfile.seek(Logfile.size()) == false) {
        return false;
    }

    Out.printf(OUT_SERIAL | OUT_LOGFILE, "%s reopened\n", logFileName);

    return true;
}

I am using a Seeed W5500, which uses IC level shifters, so I tried using FULL_SPEED, but that fails...

Steve