Hi everyone! I'm intellectually stumped at trying to figure this out. Thanks in advance for any suggestions/help.
I'm trying to make my Arduino UNO read from, but also certainly write to an SD card.
I need my code to check all the file names on the SD card, compare them (text0.txt, text1.txt,...tex19.txt) to see which file name has the highest number, and then create the next file text20.txt to which I will write data.
The only thing I have thought of so far is to count the number of files and then create a new file with the next incremented name. However, I do not know how to count the number of files.
To compare straight string values is pretty easy. You can use strcmp(). However, you would have to rename your filenames in order for that to work the way you want. That's because "text3.txt" compares as greater than "text15.txt", because '3' is greater than '1'. You would have to rename it so it had leading zeros. For example, "text03.txt". If there are going to be more than 99 files, you'll have to add 2 zeros.
There are other ways, of course. If all your filenames are exactly the same format--"textX.txt", it would be possible to convert the digits to a value and compare them. There are C routines to do it for you, like atoi() or sscanf(), or you can convert them yourself with a little bit of subtracting and multiplying and adding.
I believe the SD library as a list function of some sort, which you will need for either counting the files or calculating the highest number or both.
The easiest solution is to store in EEPROM the last file ID, so that when you need to create the next file, you just read that ID and add one to it, then use sprintf or something like that, to make the file name.
If the maximum number of files you need to support is not huge, and you don't mind wasting a little time each time a new file needs to be opened, you could just brute-force it and loop through trying every file from 0 upwards until you find one that isn't there, and pick that as the next file.
Otherwise, the 'best' approach would depend on how you're going to manage the files - whether anything is ever going to delete any files, whether they will be deleted in any particular order, whether you want to re-use previous numbers if the file has been deleted, and so on.
I pulled this algorithm for incrementing a decimal number within a C string from a forum somewhere. I forgot to put the credit in my source so I don't remember from whom I got the code. It worked for me the time I used it. It basically brute forces changing an intended file name by incrementally finding the next available number. No magic, no sorting through directory listings. Just simple "go to the next one if the current one exists". Plenty fast enough for me since I never really had many more than 10 log files saved at a time.
Variable initialization that I did as a global:
char fileName[] = "LOGGER00.CSV"; // Base filename for logging.
Next part I did in setup():
// Construct the filename to be the next incrementally indexed filename in the set [00-99].
for (int i = 1; i <= 99; i++) { // check before modifying target filename.
if (!SD.exists(fileName)) { // make sure file doesn't exist.
File logfile = SD.open(fileName, FILE_WRITE); // write to flush cache.
logfile.close();
break; // break out of the for loop.
}
// If we reach this point the file exists so increment the 2 digit filename index.
fileName[6] = i/10 + '0';
fileName[7] = i%10 + '0';
}
I'm not sure if the SD.open() part is really necessary because I'm not sure what caches existed right at the start of a sketch. It probably works just as well without it, but it didn't break anything with my method.
I can share the full sketch code if you want, but be warned it contains a lot of String usage. But, it was a single use, specialty program and one of my first half-dozen projects with Arduino. (And before I learned of the memory fragmentation issues with Strings.) I was trying to capture intermittent wire breaks as I abused a cable end to test durability.