SD card, open file and restart

Can a restart of the controller (caused by A) Uploading a new version of the sketch, B) Pressing RESET or C) error in the code causing restart) while a file is opened for writing on the SD card cause corruptions on the SD card?

The SD libraries hold a 512 byte buffer and they commit the buffer to the SD file that is open from time to time (when it's full, when you call flush, when you close the file, ...).

if your arduino stops and the memory buffer has not been written and the file system updated accordingly, then you might be left with a file and file system that is in weird state.

So the best thing is to do a flush after each write?

And if the file system is in a weird state, will this cause problem when the controller start up again and want to create a new file?

you'll loose in performance. I'd say it's good to do it when you have completed all the writes for a given "operation" and you want to commit that to the SD.

This has not been my experience, I don't know enough about how the libraries handle the FS.

The SD card is used for continues logging so the controller will "never" complete all writes (since the controller will be running 24/7/365). Often minutes between each write.

Performance is not a big issue in this case.

flushing after a record then should not be an issue and will keep things tidy.

But it will wear out the SD card much faster.
With the current sizes of SD cards that should not be a problem,
at least for simple logging.

I'm not sure I should jump in here because I have a similar problem. I'll end up at the end of a month with several files, except only one of them is a .txt file, which is the most recent. All of the others have variations of the file name that I tell the microSD I want to save to.
I though that any additional data would be appended to the end of the existing data.
But I have been doing many resets to tweak my sketch. I save data to my card every 2 seconds.
Isn't there some piece of code that will check to see if:

" if your arduino stops and the memory buffer has not been written and the file system updated accordingly, then you might be left with a file and file system that is in weird state."<

If I tweak the sketch then up load a new file, the sketch restarts and seems to work fine, but if I just press the Reset button, maybe this is where the sketch hasn't changed, but the memory buffer might be full. Does anyone have any ideas about addressing this problem?

If your Arduino stops, there is no code running that can check things :wink:

Still testing things. Disabled most of the code. Every 100th call to loop() case one line to be written to the SD card:

After some time I start getting error (0 bytes written to the card).

Since I dig into the SD library I managed to get the error code and error data from the SD object when this happens:

7:45:52.436 -> LOG:593;1628477826;DBG;Loop 61000#  [32 bytes writen, filesize=18751 bytes.]
17:45:53.116 -> LOG:594;1628477827;DBG;Loop 61100#  [32 bytes writen, filesize=18783 bytes.]
17:45:54.036 -> LOG:595;1628477827;DBG;Loop 61200#  [32 bytes writen, filesize=18815 bytes.]
17:45:54.876 -> LOG:596;1628477828;DBG;Loop 61300#  [32 bytes writen, filesize=18847 bytes.]
17:45:55.756 -> LOG:597;1628477829;DBG;Loop 61400#  [32 bytes writen, filesize=18879 bytes.]
17:45:56.596 -> LOG:598;1628477830;DBG;Loop 61500#  [32 bytes writen, filesize=18911 bytes.]
17:45:57.516 -> LOG:599;1628477831;DBG;Loop 61600#  [32 bytes writen, filesize=18943 bytes.]
17:45:58.236 -> LOG:600;1628477832;DBG;Loop 61700#  [0 bytes writen, filesize=18943 bytes.]
17:45:58.316 -> ERROR writing to logfile. 0 bytes written
17:45:58.356 -> Error code: 4
17:45:58.356 -> Error data: FF
17:45:59.116 -> LOG:600;1628477833;DBG;Loop 61800#  [0 bytes writen, filesize=18943 bytes.]
17:45:59.156 -> ERROR writing to logfile. 0 bytes written
17:45:59.196 -> Error code: 4
17:45:59.236 -> Error data: FF
17:46:00.036 -> LOG:600;1628477834;DBG;Loop 61900#  [0 bytes writen, filesize=18943 bytes.]
17:46:00.116 -> ERROR writing to logfile. 0 bytes written
17:46:00.156 -> Error code: 4
17:46:00.156 -> Error data: 7F
17:46:00.956 -> LOG:600;1628477834;DBG;Loop 62000#  [0 bytes writen, filesize=18943 bytes.]
17:46:01.036 -> ERROR writing to logfile. 0 bytes written
17:46:01.076 -> Error code: 4
17:46:01.116 -> Error data: FF
17:46:01.956 -> LOG:600;1628477835;DBG;Loop 62100#  [0 bytes writen, filesize=18943 bytes.]

I guess this codes relates to the definition in the Sd2Card.h file?

// SD card errors
/** timeout error for command CMD0 */
uint8_t const SD_CARD_ERROR_CMD0 = 0X1;
/** CMD8 was not accepted - not a valid SD card*/
uint8_t const SD_CARD_ERROR_CMD8 = 0X2;
/** card returned an error response for CMD17 (read block) */
uint8_t const SD_CARD_ERROR_CMD17 = 0X3;
/** card returned an error response for CMD24 (write block) */
uint8_t const SD_CARD_ERROR_CMD24 = 0X4;
/**  WRITE_MULTIPLE_BLOCKS command failed */
uint8_t const SD_CARD_ERROR_CMD25 = 0X05;
/** card returned an error response for CMD58 (read OCR) */
uint8_t const SD_CARD_ERROR_CMD58 = 0X06;
/** SET_WR_BLK_ERASE_COUNT failed */
uint8_t const SD_CARD_ERROR_ACMD23 = 0X07;
/** card's ACMD41 initialization process timeout */
uint8_t const SD_CARD_ERROR_ACMD41 = 0X08;
/** card returned a bad CSR version field */
uint8_t const SD_CARD_ERROR_BAD_CSD = 0X09;
/** erase block group command failed */
uint8_t const SD_CARD_ERROR_ERASE = 0X0A;
/** card not capable of single block erase */
/** Erase sequence timed out */
/** card returned an error token instead of read data */
uint8_t const SD_CARD_ERROR_READ = 0X0D;
/** read CID or CSD failed */
uint8_t const SD_CARD_ERROR_READ_REG = 0X0E;
/** timeout while waiting for start of read data */
uint8_t const SD_CARD_ERROR_READ_TIMEOUT = 0X0F;
/** card did not accept STOP_TRAN_TOKEN */
uint8_t const SD_CARD_ERROR_STOP_TRAN = 0X10;
/** card returned an error token as a response to a write operation */
uint8_t const SD_CARD_ERROR_WRITE = 0X11;
/** attempt to write protected block zero */
uint8_t const SD_CARD_ERROR_WRITE_BLOCK_ZERO = 0X12;
/** card did not go ready for a multiple block write */
uint8_t const SD_CARD_ERROR_WRITE_MULTIPLE = 0X13;
/** card returned an error to a CMD13 status check after a write */
/** timeout occurred during write programming */
uint8_t const SD_CARD_ERROR_WRITE_TIMEOUT = 0X15;
/** incorrect rate selected */
uint8_t const SD_CARD_ERROR_SCK_RATE = 0X16;

Since error code is 4 I assume it means card returned an error response for CMD24 (write block).

What does that mean?

Finally found out all the problems with my SD card. I removed more and more code from my rather big sketch (35000++ lines) until only one home made library was in use - still error. When this (and the code that used it) was removed, it worked.

I then began to dig into this library, which again used a library for the ADS1115 ADC. Digging into this library I noticed that it used the Adafruid BusIO library. Updating the BusIO fixed the problem :slight_smile:

It took me several weeks with trying and failing until I found the cause of my problems. Guess I updated the Adafruit ADS1115 library some time ago, but not the BusIO.

Lesson learned: Always check dependencies when updating libraries.

1 Like