How to recognize that an SD card has been removed or inserted?

I've been developing yet another weather data logging station, for my own use (but I might eventually post my data publicly). After fits and starts it's now working pretty well, except for one thing.

I have it write weather readings once a minute to a MicroSD card inserted into an SPI-based breakout board I got on eBay a while back. It's been working fine at that.

Once or twice a day I remove the mSD card and insert it into my PC to transfer the data (which I currently store in Excel). I can usually do this in well under a minute, so as to not lose any readings. I have to remember to reset the station for it to recognize the re-inserted card, or otherwise it won't write future readings to it. No bigee, if slightly annoying.

But sometimes I'm not able to do this in under a minute, so I lose a reading or two. Not a huge problem since weather generally doesn't change that quickly, but for the hell of it I added some code to save readings in an array when a card isn't available to be written to, and then write all of them when the card is available again.

The problem with this is that if I reset the station, it loses these temporarily saved readings. So I have to find another way of recognizing when a card that was removed has been reinserted. This would also solve the minor annoyance of having the reset the station even when I can reinsert the card in under a minute.

Any ideas? Neither the standard SD library nor the somewhat more robust SDfile library seem to have obvious ways of recognizing when a card has been inserted, removed or re-inserted. But I'm no expert on either.

Eventually this will be less of an issue as I'm adding WiFi capabilities to this station via an ESP8266 board, that will upload readings to some remote DB. But for now, everything's local. Plus, even when it has WiFi uploading capabilities, I'm still going to want to store readings locally, on an mSD card, in case I lose my internet connection or something on the server or ESP8266 stops working.

Btw, as an aside, I'm thinking of getting a Raspberry Pi and setting it up as a LAMP (Linuxm Apache, MySQL & PHP/Perl/Python) server. Would that work, assuming I can figure out the HTML, PHP & SQL code (I've worked with all three in the past)?

SD cards must be reinitialized if you remove power. If you remove an SD card while the file system is being updated you can cause a corrupt file system.

Newer SD cards buffer data in RAM so you must wait at least one second after the last SD access before removing power.

You should use a switch to tell the program you want to remove the card. When the program has closed the file and delayed for a second it can light an LED to tell you it is safe to remove the card.

Most SD sockets have a card detect switch. you could use the CD SW to detect when to initialize the card and reopen the file.

If you write a record about once a minute, the probability is low that you will corrupt the file system by just pulling the card since only a few ms is required to write the record. So if one in a few thousand are OK odds, just pull the card. You can connect the card detect switch to an interrupt.

I assume you flush data after every record.

I don't remove power, just the card from the slot when I need to access it on my PC. The station itself remains powered, and the card breakout board remains connected to the station and thus is still powered as well.

My sketch always closes the log file once it's done writing the latest set of readings to it. I do this both for better reliability should the station lose power for some reason, and because I create a new log file each night at midnight, and I would have to close the previous day's file anyway when I did this.

Once the latest readings are written to the file and it's closed, I print a message to serial indicating this, so I can safely remove the card. I generally wait a couple of seconds anyway, just in case.

I assume that this means that I don't really need a switch to tell the sketch to close the file, right?

I don't explicitly "flush" the write buffers, but I assumed that closing the file would do this automatically. Is that not the case, and if so, how do I flush them?

In any case, I think you've given me a way to have the sketch know when a card has been removed and inserted. I thought that calling SD.begin() each time I'm ready to open and write to the file might accomplish this, but when I tried it, it sometimes worked, and sometimes acted strangely.

Thanks.

If the auto detect does not work, a low tech solution may be to have a toggle switch that allows you to tell the weather station that you have removed the card and start buffering. Once you have done your thing toggle it back.

Opening and closing the file should work fine since performance is not a problem in your case.

I designed SdFat with sync() as the fundamental call to update the SD. Close is just sync() plus clearing the file open status. flush() is the name the Arduino company uses in their SD.h wrapper for sync().

write() followed by sync() can be 20-30 times faster than open(), write(), close() when there are many files in the directory and/or seek to the end of a long log file. The result is the same in both cases if power is lost.

You must remove power from the SD if you move it from the Arduino.

There is a bug in the old SD.h wrapper so that removing an SD, replacing a different SD, and calling begin() will result in a corrupt file structure on the second SD. begin() will return false but leave the SD in an inconsistent state.

That's interesting that you can't re-insert an SD card into an arduino without power cycling, hopefully for just this library. Luckily the arduino can restart itself if SD is acting up. There MUST be a way to fix that, but it's over my head.

  1. if it's only a few readings, you could use EEPROM to store them on the reboot.

  2. or, maybe you could use 2 SD cards. MCU writes to main SD, then copies files to 2nd SD when they have enough data to be worth it. Deletions from main card only occur when copy was successful to 2nd card. Arduino reboots itself with watchdog between readings to see if the 2nd SD card was re-inserted. Real time clock might be a good addition to this setup to keep readings at regular intervals.

My solution was to use the SDFat library, which is more robust and can deal with removed and reinserted cards w/o resetting the Arduino. I'd originally used the SD library, which can't handle that. Been doing this w/o a problem for over half a year now. Props to fat16lib for cluing me onto this.