I need a function that returns how full the Sd card is, that will work with multiple files where the fileNames are not known.
Is this possible? or alternatively is there a way to get a list of fileNames on the SD card that I can use to call the function above once for each fileName?
Have you had a look at the Spark-CardInfo sample with this library?
This should show how to traverse the whole file system allowing you to sum up the file sizes.
I’m not sure if there is a function to just look at the FAT entries to get to the same info quicker.
First you’d need a SDFile object that gives you access to the root folder of your SD card.
Like in the example code
Sd2Card card;
SdVolume volume;
SdFile root;
...
...
root.openRoot(volume); // card and volume have to be set up too
...
And since original ::ls() method was part of the SDFile class it has access to the “internal” functions (like SDFile::rewind()) without explicitly referencing its “owner”.
But as “external” code you’d need to (e.g. root.rewind() or rootPtr->rewind()).
And for filesize += p->fileSize; you have to use be exact - mark the capital S.
I had not realised that the root folder had to be opened.
The function below seems to work, I need to leave my SD logging for a while to double check the percent full returned is correct. I also had to make the readDirCache function public in the sd-file.cpp class. Any way around this?
int16_t SDClass::percentFullSd()
{
//Get total size
uint32_t volumesize = volume.blocksPerCluster();
volumesize *= volume.clusterCount();
volumesize *= 512;
//Open root
root.openRoot(volume);
//Get file size
uint32_t filesize = 0;
dir_t* p;
root.rewind();
while ((p = root.readDirCache()))
{
// done if past last used entry
if (p->name[0] == DIR_NAME_FREE) break;
// skip deleted entry and entries for . and ..
if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') continue;
// only list subdirectories and files
if (!DIR_IS_FILE_OR_SUBDIR(p)) continue;
// add size
filesize += p->fileSize;
}
//Calculate percentage
return round(((double)filesize / (double)volumesize) * 100);
}
For SD cards larger than 4 GB, you can’t use uint32_t.
I am using a 4GB SD card.
You must use the amount of space allocated to the file, not the file size.
Not sure what this means. How can I get the amount of space allocated to the file?
You must use a recursive function to account for sub-directories.
I don’t have any sub-directories.
Note that entries for directories have zero size so you must trace the allocation chain.
Not sure this is relevant for me - see above.
Root on FAT16 volumes is a fixed area, not allocated from clusters so shouldn’t be counted.
Not sure this is relevant to me - the card is formatted as FAT32.
The best way to get used/free space is to scan the FAT, File Allocation Table, and determine what fraction of clusters have been allocated.
How would I do this?