So yes, I have searched and read many threads about this; and I have been through the SdFat source files and documentation many times… here is why I am still posting this:
- I couldn’t find a simple, clear example of how to log data while supporting card removes/inserts. Lots of instructions of how to do it, but no real sample code
- I was looking for a solution using SdFat only (I am seriously memory constrained)
- Many threads are old, and I see several posts from Bill Greinman mentioning updates to improve things and I wasn’t sure what applied and what didn’t anymore
… so I’d like your thoughts about the code below, and whether it could be improved? The goal is to keep the program running (no resets) while the card is occasionally removed & re-inserted. I do understand that corruption could happen if the card is removed while logging, I’ll handle that separately.
I have tested removing / re-inserting the card; and starting w/o a card and inserting it later.
A question I still have: I suspect the **Halt methods may be useful but I am not sure what they do exactly? If I call them every time I detect a failure will the next SD.begin still work?
#include <RTClib.h>
#include <SPI.h>
#include <SdFat.h>
#define SS_PIN 10
#define print2(F,V) if (V < 10) F.print('0'); F.print(V, DEC)
// clock
RTC_DS1307 rtc;
// SD Card
SdFat SD;
uint16_t log_id;
bool sdSetup(bool force = false);
void setup()
{
Serial.begin(9600);
rtcSetup();
sdSetup(true);
}
void rtcSetup()
{
while (! rtc.begin()) {
Serial.println("RTC not found!");
delay(1000);
}
if (! rtc.isrunning()) {
Serial.println("RTC is NOT running, setting the time");
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
else {
Serial.println("RTC is running");
}
}
bool sdSetup(bool force)
{
if (force || SD.cardErrorCode()) {
Serial.println("\nInitializing SD card...");
SD.begin(SS_PIN);
if (SD.cardErrorCode()) {
Serial.print("SD Card init failed! "); SD.errorPrint(&Serial);
}
}
return ! SD.cardErrorCode();
}
void loop () {
writeLog();
delay(10000);
}
void writeLog()
{
SdFile log;
if (! sdSetup()) {
return;
}
if (! log.open(SD.vwd(), "test.csv", FILE_WRITE)) {
Serial.print("Could not open file: "); SD.errorPrint(&Serial);
return;
}
DateTime now = rtc.now();
log.print(log_id); log.print(' ');
log.print(now.year(), DEC);
log.print('-'); print2(log, now.month());
log.print('-'); print2(log, now.day());
log.print(' '); print2(log, now.hour());
log.print(':'); print2(log, now.minute());
log.print(':'); print2(log, now.second());
log.println();
bool log_ok = log.close() && ! log.getError();
if (log_ok) {
Serial.println("Log written");
log_id++;
}
else {
Serial.print("Could not write log: "); SD.errorPrint(&Serial);
}
}