I have created a sketch that logs data points onto a Micro SD card. The sketch will count the number of files in the “LogFiles” folder, and then create another file that is that amount plus one.
I create the new file using the function below:
void createNewFile() {
String FileName = String("LogFiles/Log0") + fileCount + String(".csv");
logFile = SD.open(FileName, FILE_WRITE);
}
The issues is that this function with strings uses an extra 1,792 bytes in my program! Is there a way to do what I want to do without using strings or lowering the program storage space?
Using "S"trings at all might be just the start of your troubles. You might use char instead, as is common practice.
char filename[] = "00000000.CSV";
and go on from there.
Nick_Pyner:
Using "S"trings at all might be just the start of your troubles. You might use char instead, as is common practice.
char filename[] = "00000000.CSV";
and go on from there.
That saves a lot of space using char! Thank you! But how would I implement the fileCount variable into the char? For example, I am currently doing this, but get the error: "initializer fails to determine size of 'FileName'"
char FileName[] = char("LogFiles/Log0") + fileCount;
I'm afraid what you are doing is meaningless, I just use the date as a filename and make new ones at midnight. So, at a guess it will be something like
sprintf(filename, "%04u.csv", fileCount); //9999 files
fileCount++;
but I have no idea what makes the change, or why.
sprintf will pull in a lot of code also, so it's not really worth it, if you only use it in one place.
It easily can be done 'by hand'.
char fName[] = "LogFiles/Log00000.csv";
const byte lastDigit = sizeof(fName) - 6;
void nextFileName() {
if (++fName[lastDigit] > '9') {
fName[lastDigit] = 0;
if (++fName[lastDigit - 1] > '9') {
fName[lastDigit - 1] = 0;
if (++fName[lastDigit - 2] > '9') {
fName[lastDigit - 2] = 0;
if (++fName[lastDigit - 3] > '9') {
fName[lastDigit - 3] = 0;
}
}
}
}
}
void setup() {
Serial.begin(250000);
Serial.println(fName);
nextFileName();
Serial.println(fName);
}
void loop() {}
LogFiles/Log00000.csv
LogFiles/Log00001.csv
J-M-L
February 28, 2020, 9:31am
#6
Whandall:
sprintf will pull in a lot of code also, so it's not really worth it, if you only use it in one place.
It easily can be done 'by hand'.
char fName[] = "LogFiles/Log00000.csv";
const byte lastDigit = sizeof(fName) - 6;
void nextFileName() {
if (++fName[lastDigit] > '9') {
fName[lastDigit] = 0;
if (++fName[lastDigit - 1] > '9') {
fName[lastDigit - 1] = 0;
if (++fName[lastDigit - 2] > '9') {
fName[lastDigit - 2] = 0;
if (++fName[lastDigit - 3] > '9') {
fName[lastDigit - 3] = 0;
}
}
}
}
}
void setup() {
Serial.begin(250000);
Serial.println(fName);
nextFileName();
Serial.println(fName);
}
void loop() {}
LogFiles/Log00000.csv
LogFiles/Log00001.csv
probably that should be (everywhere you overflow)fName[lastDigit] = '0'; // the char '0' not the null char
Absolutely the test was not deep enough.
char fName[] = "LogFiles/Log00000.csv";
const byte lastDigit = sizeof(fName) - 6;
void nextFileName() {
if (++fName[lastDigit] > '9') {
fName[lastDigit] = '0';
if (++fName[lastDigit - 1] > '9') {
fName[lastDigit - 1] = '0';
if (++fName[lastDigit - 2] > '9') {
fName[lastDigit - 2] = '0';
if (++fName[lastDigit - 3] > '9') {
fName[lastDigit - 3] = '0';
}
}
}
}
}
void setup() {
Serial.begin(250000);
Serial.println(fName);
for (uint16_t i = 0; i < 3456; i++ ) {
nextFileName();
}
Serial.println(fName);
}
void loop() {}
LogFiles/Log00000.csv
LogFiles/Log03456.csv
J-M-L
February 28, 2020, 10:56am
#8
(I assume it's intended to not update the first 0 - ie max number is 9999)
I was inspired from the
char FileName[] = char("LogFiles/Log0") + fileCount;
which also has a leading zero and I reused the limit (which is really 10000 for the same format) from
sprintf(filename, "%04u.csv", fileCount); //9999 files
J-M-L
February 28, 2020, 11:12am
#11
yeah, assumed so but weird decision from OP
String FileName = String("LogFiles/Log0") + fileCount + String(".csv");