and SD.exists still return 1 after SD Card Removed

So I’m completely lost as to what to try next so I figured I would reach out to the community to see what your thoughts are.

For some reason, even after I have removed the SD card, both and SD.exists still return 1 as if they’re still true although they’re not. The thing that is driving me crazy is in the first few drafts of my program, this worked perfectly fine and I was able to use their false Boolean to trigger an error loop. Something changed however that has broken that and I can not figure out what it could be.

Side note: If I remove the SD card AFTER SD.begin but BEFORE or SD.exists runs for the first time, they return false (0) as they should. However, it seems once they run with the SD card in and returns True (1), that value seems to stick even after the SD card is removed.

The code below is part of a data-logger program I took out and simplified to make it easier to follow, however it is similar to my main program. Also the shield I’m using is the Adafruit data-logging shield link along with a Arduino Mega 2560

cardcheck.ino (2.51 KB)

Most likely the directory block containing the file is cached. No access to the SD card is required to open the file or check for exists if the file is found in the cache.

That makes sense, yeah figured it might be a cache thing although I find it strange it use to work on my previous drafts. Is there any way to clear the cache for that on each loop?

Is there any way to clear the cache for that on each loop?

No you can't clear the cache with SD.h, the call is hidden by the SD.h wrapper. You can force it to the SD by calling flush/sync if the cache is dirty.

You can clear the cache with SdFat, the call is:

/** Clear the cache and returns a pointer to the cache.  Not for normal apps.
  * \return A pointer to the cache buffer or zero if an error occurs.
 cache_t* cacheClear();

You must never remove an SD card while the cache is dirty or you will lose data or corrupt the file system.

You will not always get the behavior you see if the the file you are opening or checking for with exists() is not in the first directory block, you will get an error. open() and exists() start with the first directory block.

Ok thanks I'll using SdFat and see. Is there any downside to clearing the cache after each check, like every 20 seconds? Also how would I know if the cache is dirty so it don't remove the card when it is?

Why do you worry about the exist/open problem? You can't just remove the card without other problems.

Is there any downside to clearing the cache after each check, like every 20 seconds?

There is no advantaged to clearing the cache. It may cause a slight performance hit.

The only time it matters is if you remove the card but then you can't use the card again until you initialize it with a begin() call.

So pretty much the logger will log data every 5 minutes and also check for the card every 20 seconds and do an error loop if there is an error. The check serves to check that the card is both still present and that there is no error with opening a file for writing once it's time to log.

I'm making the logger to be used by someone else. They will remove the SD card once a month to retrieve the data off the card so I want an error loop to remind them the logger is no longer logging and to reinsert the card and reset the arduino. The logger with also be outside in a suitable enclosure but lets say some moisture gets inside somehow and shorts the card out or the card gets corrupt, I would like to have an error loop to notify the user the logger is no longer logging and needs attention.

Allowing a user to pull a card without stopping the program is a bad idea.

When you write the card, data is buffered in the card then written to flash when the card schedules it. You should wait at least one second after the card is idle from programming flash. This is a fairly large window and I often hear from users who corrupt data/file systems by removing cards.

The SD spec allows the card to do other housekeeping like wear leveling. The spec does not provide an SPI command to know when it is safe to remove a card. In SDIO mode on a phone, tablet, or PC, there is a command to safely eject a card.

Hmm I see. Currently I have an LED that goes on 20 seconds before the program writes to the cards and stays on 10 seconds after that to signal to the user the card shouldn't be removed at that time. Should I add a button they should press before removing the card to stop the program making it safe to do so? If so what kind of command would that be?

The current solution I came up with to check for the card and that it's writable is, inside my card check loop which runs every 20 seconds, open a test file (which essentially creates a blank file since it doesn't already exist) then delete the file 5 seconds later. I've tested it and it seems to works perfectly, would there be any downside to doing this?

I'm also still trying to figure out a way to stop the program making it safe to remove the card