Sd card stops working after a day of use.

I recently finished an rfid door access system for my house and everything works as intended. The only issue I am having is after about a day of running the system, it will act is if the sd card has been removed or as if it can no longer access the card.

I have attached a copy of the code I am using.

khkrfid_ino.txt (9.5 KB)

Looks like there there are paths through the code where cardFile is opened but never closed. This will cause a memory leak and SD operations will fail.

SD.h has a nasty property of allocating memory with malloc() when a file is opened and releasing the memory on close. This often causes memory leaks.

fat16lib:
SD.h has a nasty property of allocating memory with malloc() when a file is opened and releasing the memory on close. This often causes memory leaks.

How does SdFat differ? I thought it did the same at about 500 bytes per open file.

fat16lib:
Looks like there there are paths through the code where cardFile is opened but never closed. This will cause a memory leak and SD operations will fail.

SD.h has a nasty property of allocating memory with malloc() when a file is opened and releasing the memory on close. This often causes memory leaks.

why would the program still work then but the sd card fail?

So a solution would be to open the file after a card read is detected and then close the file when the operation is complete?

why would the program still work then but the sd card fail?

I don't know for certain, but if it is a well-mannered library, it will fail to open if there is insufficient memory to open the file.

SurferTim,

I assume SD.h does fail to open files when memory is exhausted.

SdFat does not use dynamic memory. The SD.h wrapper for SdFat uses malloc().

SdFat allocates a single 512 byte block buffer from global memory here:

SdFat sd;

Each file requires 31 bytes for AVR boards and 40 bytes for ARM boards. This memory is allocated from global memory or the stack, depending where this statement is.

SdFile file;

@fat16lib: You are THE MAN when it comes to SD! +1 for you. Thanks for the info. :slight_smile:

I modified the ReadWrite.ino example that comes with SD.h like this:

  if (!SD.begin(10)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  for (int i =0 ;; i++) {
    myFile = SD.open("test.txt", FILE_WRITE);
    if (!myFile)  {
      Serial.println(i);
      while(1);
    }
  }

It fails and prints

Initializing SD card...initialization done.
28

So memory is exhausted after about 28 open calls in this case.

Great test! Just as a comparison, how does SdFat do? How many can you open and not close with it?

You can't, I catch an attempt to open an already open file and return an error to catch this bug.

SD.h can't do that due to the poor API design.

Here is an SdFat example:

  if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt();

  if (!myFile.open("test.txt", O_RDWR | O_CREAT | O_AT_END)) {
    sd.errorHalt("opening test.txt first time failed");
  }
  if (!myFile.open("test.txt", O_RDWR | O_CREAT | O_AT_END)) {
    sd.errorHalt("opening test.txt second time failed");

it prints:

error: opening test.txt second time failed