Hi there, Merry Christmas to all of you.
I'm making a birthday calendar and have problems with three lines of code inside a for loop.
First line prints the right name, but I can't make it into a file name for getting it from flash.
const char *const birthdayName[] PROGMEM = { "Miranda" }; // one of many
char fileName[13];
for(...
Serial.println(birthdayName[i]); // prints Miranda
snprintf(fileName, 12, "/%c.bin", birthdayName[i]);
Serial.println(fileName); // prints /x.bin instead of "/Miranda.bin"
Where x shows a random single character.
Any pointers?
Leo..
Thank you. That could be it.
Copied the formatter from another part of the code without thinking.
Too much Christmas port wine could be the cause.
Will post the results tomorrow.
Leo..
Do you need to add the suffix \0 to the array ("Miranda\0")?
Add a second element to the array, for example, "Wawa" or "Wawa\0" and try to print out just the first element ("Miranda\0"). The size difference of the elements might also give clues to what is needed.
The first creates a 2-dimensional array, with each element of the array being composed of an array of 9 char.
The second creates an array of pointers to individual char arrays.
The first is somewhat easier to use, particularly when PROGMEM is needed, but other than that not a lot of difference in your application. The first tends to waste a lot of memory if the texts are different lengths, with only a few very long and the majority very short. The second can waste memory if all or nearly all of the texts are the same length, since storage is needed for the pointer as well as the text. Not really a concert with a processor with as much memory as an ESP32.
Thanks for the explanation.
Names are maximum 8 charcters long, to stay within the 8.3 file name scheme.
Maybe 50 entries or so for now. I will see how much is actually wasted.
The ESP32-S3 used has 8MB flash, but I am going to Use a custom partition scheme, to store more images. Best not to waste program flash.
Leo..
I would use the 2-dimensional array, since an ESP32 pointer is 4 bytes. A 50 element array of char* would be 200 byte, in addition to what is needed for the names themselves. The two-dimensional array would be 50 * 9 = 450 bytes total.
If you're always going to loop through all of them in sequence (instead of doing random access by array index) you can take advantage of the fact that the compiler with mush all contiguous literal strings together. It's more readable than one giant string, and you can use multiple lines. Putting NUL at the end of each name will result in double-NUL at the end of the resulting C-string.
const char *names = "Samantha\0" "Tim\0" "Miranda\0"
"Dancer\0" "Prancer\0" "Donner\0" "Blitzen\0";
void setup() {
Serial.begin(115200);
}
void loop() {
delay(1200);
if (*names) {
char buf[20];
int len = snprintf(buf, sizeof(buf), "/%s.bin", names);
len -= 5; // "/" and ".bin"
Serial.print(len);
Serial.print('\t');
Serial.println(buf);
names += len + 1; // skip NUL separator
}
}
I guess this is most likely not what you wanted to do. This line of code would put Mirnada into RAM and a pointer to it into a PROGMEM. If you rewrite it to
const char birthdayName[] PROGMEM = "Miranda";
an array containing Miranda would be placed in a PORGEMEM and you can still use birthdayName as a pointer if you need.
But PROGMEM only works on AVR boards. WIth XIAO ESP32-S3 I would mind putting an additional 450 bytes in RAM if you are not having problems with it. Besides that accessing RAM is faster than accessing PROGMEM.
To achieve the similar behaviour on ESP32 you can use String s = F("Miranda"); but I personally do not like Strings particularly when running low on memory since there is a chance they are not being constructed and this is something that your code should take into account.
As long as you have plenty of memory I'd rather focus on the speed and clarity of the code than complicate it with memory management.
The problem has been solved.
And I can now store about 50 240x240 .bin (113k each) images on an XIAO ESP32-S3.
Custom partition, 1.3MB program, 6.6MB LittleFS.
Leo..