Free Space in Memory Card using SdFat library taking too much time??

Hello!! Everyone i am using Arduino Mega and SDFat library available from this link

I have to interface two memory cards with arduino mega, as this library supports two sd card hence that is not an issue i think.

I am having two memory cards, one is of 2GB (FAT16) and another one is of 4GB(FAT32).

I have to calculate the card size and free space available in card, i done both of the parts and both are working fine, just one issue is the speed.

Reading Card size is okay, and is fast enough, but when tried reading the free space from the card it takes 500 msec for the 2GB card but 19 Seconds for the 4GB card, both cards are of Sandisk and formatted properly.
Is there some method to speed up this, as 19 seconds is huge.

freeSpace = intVolume.freeClusterCount();		// returns number of free cluster in SD Card
 freeSpace = freeSpace * intVolume.blocksPerCluster();	// blocksPerCluster() returns no. of blocks in a cluster
freeSpace = freeSpace * 512.0;					// 1 block = 512 bytes

freeSpace variable is of type float and the last value contains free space in Bytes.

What is formatted properly ?
I think there is a sticky topic at the top of the storage section in this forum to use the SD Formatter 4.0
Use that and let it format the whole SD card.

Or try setting the SPI bus one notch faster than the default value.

Wouldn't it be easier to calculate the used size, instead of the free size ?

Both the cards are formatted using SDFormatter v4.

I increase the SPI, but same effect.
Is there any other way to calculate the free space, because this will block other tasks.
:frowning:

If i use this full speed SPI mode then time for calculating free space in memory card is 13 seconds

intInitStatus = intSD.init(SPI_FULL_SPEED,INT_SD_CS);

But if is changed to half speed then time taken to count size is:-

intInitStatus = intSD.init(SPI_HALF_SPEED,INT_SD_CS);

Have you tried formatting both to FAT16 or FAT32, just to see if that would make a difference?
Do you know what class each card is?

Do you understand that finding free space may mean counting empty sectors and that FAT32 has 64K times as many sectors as FAT16? Just be happy that the card has its own MCU.

Have you tried formatting both to FAT16 or FAT32, just to see if that would make a difference?
Do you know what class each card is?

You can't format a 4 GB SD card FAT16. The class will not make much of a difference for read on an Arduino. Class only translates into speed when used on a PC or other device with lots of RAM to write/read using the 4-bit wide high speed SDIO bus and large multi-block transfers.

Is there any other way to calculate the free space, because this will block other tasks.

No, the only way to find how much free space is to read the entire FAT and count free clusters.

FAT32 uses 32-bit cluster entries so each FAT entry is twice the size of a FAT16 entry. A 4 GB card will have twice as many entries, assuming both have 32 kb clusters. It should take four times longer for the 4 GB card.

I added a time check to SdInfo:

  uint32_t m = micros();      // <<--------------------- add
  uint32_t volFree = sd.vol()->freeClusterCount();
  m = micros() - m;            // <<----------------------add
  cout <<  volFree << endl;
  cout << F("micros: ") << m << endl; // <<-------------add

Here is the result for a 4 GB SanDisk card, 1.82 seconds. I used an Uno.

Volume is FAT32
blocksPerCluster: 64
clusterCount: 124112
freeClusters: 124111
micros: 1821604 <<------------------------------ time in micros
freeSpace: 4066.87 MB (MB = 1,000,000 bytes)

Run SdInfo on your 4 GB card. Does it have 64 blocks per cluster? Is the total cluster count about 124112?

I tried several models of 4 GB cards and the time varies from about 1.7 sec to 2.3 seconds.

2 GB cards take 0.4 to 0.5 seconds.

I just realized that SdInfo uses half speed SPI. Going to full speed, 8 MHz SPI increases the speed.

Here is an 4 GB that runs fast, 1.27 seconds.

Volume is FAT32
blocksPerCluster: 64
clusterCount: 120752
freeClusters: 120740
micros: 1271828
freeSpace: 3956.41 MB (MB = 1,000,000 bytes)

Here is a 2 GB card at 8 MHz. 0.29 seconds.

Volume is FAT16
blocksPerCluster: 64
clusterCount: 61252
freeClusters: 61208
micros: 289884
freeSpace: 2005.66 MB (MB = 1,000,000 bytes)

Hello!!! fat16flib, thanks for the reply.

I run the SDinfo program on my board and found that my 2GB card is having 64 blocks per cluster and the 4GB card is having on 8 blocks per cluster, which is making it slower to read the freecluster.

What can i do to increase the blocks per cluster of my 4GB SD Card.

Here is the report of both cards


Hello!! Thanks fat16lib.

I used Sdformatter4 and then again used it with my code and now the time has reduced to 2300 milli seconds.
I checked the SDInfo code, after formatting the card, and then found that blocks per cluster has changed to 64.

Is there any way to change the blocks per cluster to 128, provided that it will not create any problem.
If somehow i will be able to manage this time around 1 sec, then it will be very helpful for me.

As it might be possible that i have to use 16GB or 32 GB memory card.

Is there any way to change the blocks per cluster to 128, provided that it will not create any problem.

64 KB clusters are not supported in the SD standard and is nonstandard for FAT32. some implementations of FAT32 fail with 64 KB clusters. I have not tested SdFat lately using 64 KB clusters and I never tested the version of SdFat used in the Arduino SD.h library.

Are you using 8 MHz SPI. When I used 8 MHz SPI, my 4 GB SD cards were faster, 1270 ms.

I suspect your 4 GB card is counterfeit, it has the wrong OEM ID, Product, and Version for a SanDisk card.

Here is a typical SanDisk card from 2011.

Manufacturer ID: 0X3
OEM ID: SD
Product: SD04G
Version: 8.0
Serial number: 0XB4708B02
Manufacturing date: 4/2011

Fake SanDisk cards are all over. I recently got one from an Amazon seller. They usually have performance problems.

I suggest you get the free space at startup and then use the size of the file you are writing to keep track of when you are low.

Remember, finding clusters will take forever as you run out of space so your app performance will degrade since there will be some very long write latencies. Maybe you should just use an 8 GB card, check that a few GB are free at startup, and skip checks in your app.

I suggest you get the free space at startup and then use the size of the file you are writing to keep track of when you are low.

Remember, finding clusters will take forever as you run out of space so your app performance will degrade since there will be some very long write latencies. Maybe you should just use an 8 GB card, check that a few GB are free at startup, and skip checks in your app.

I didn't understand this, can you please explain me in detail and also how to implement it, only flow.

I had tested 16GB sandisk card, that takes 19 seconds and my 4GB card takes 1.7 seconds.
I had ordered few other cards, will check performance with that.

I didn't understand this, can you please explain me in detail and also how to implement it, only flow.

When your application starts check the free space. If your card is more than half full, stop and request a new card. This is why I said use a larger card.

Creating or adding space to a file on an almost full card will take even longer than checking for free space. Performance will be very poor if the card is fragmented.

Why are you checking for free space so often? Do you create lots of files or a few large files? Do you delete files?

I don't know at present what is to be done, because the specs of the project are not cleared at present, i have to display free space at a particular point when user selects the menu.
So it has to be discussed whether, free space is to be calculated every-time the menu is traversed or only in the startup.
It will be easier if the startup method is used, anyways thanks for supporting so much and for this wonderful library.