Si purtroppo sprintf e derivate, a fronte della grande semplicità e praticità introdotta, usano parecchie risorse del micro. Non avevo capito che eri al limite.
Se il tuo algoritmo funziona ed è veloce, continua ad usarlo sereno.
Voglio però proporti un ulteriore metodo che non fa uso di snprintf e che puoi vedere in funzione con il solito simulatore wokwi.
Un approccio simile ti consente di definire una sola funzione generica che è indipendente dalla cartella dove salvi le sequenze e che quindi puoi usare dove serve cambiando solo il folder di riferimento.
#define NUM_FILES 1000
// Convert an integer without itoa() (no leading zero) or sprintf functions
const decimalToString(uint8_t* str, uint8_t len, uint16_t val) {
uint8_t i;
for(i=1; i<=len; i++) {
str[len-i] = (uint8_t) ((val % 10UL) + '0');
val/=10;
}
// str[i-1] = '\0'; // Non è necessario il terminatore in questo caso
}
// Dichiara la funzione per la sequenza in loop
void drawFolder(const char* dir, bool reset = false) {
tft.setRotation(0);
tft.fillScreen(TFT_BLACK);
for (int num = 0; num < NUM_FILES; num++) {
char filestr[3];
// Convert decimal to string with leading zero
decimalToString(filestr, 3, num);
// replace folder string
strncpy(filename, dir, strlen(dir));
// replace numeric substring in filepath[]
strncpy(filename + strlen(dir), filestr, 3);
File file = SD.open(filename, FILE_READ);
if (file) {
digitalWrite(LED_ACT, LOW);
drawRAW(filename, 0, 80, 80, 80); // offset lxa e dimensioni lxa del raw
digitalWrite(LED_ACT, HIGH);
// Secondo me questo reset sarebbe meglio gestirlo con un interrupt esterno
if (digitalRead(RSTBTN) == LOW) {
drawFolder("/stop/", true); // chiamata ricorsiva alla funzione
}
}
else {
Serial.print(filename);
Serial.println(" not found");
if(reset)
resetFunc();
break; // interrompe il ciclo for se i file sono finiti
}
file.close();
}
}
Oltre ad essere più "pulito" è anche maggiormente scalabile e usa meno risorse soprattutto rispetto a snprintf, ma anche un pochino rispetto allo sketch originario (ho provato a compilare su Arduino Uno ovviamente).
Rimane da verificare la velocità di rendering, ma considerato che la dimensione del compilato è sullo stesso ordine di grandezza, mi aspetto che non ci siano differenze significative.
Per quanto riguarda il buffer sinceramente non vedo la necessità di raddoppiarlo quando se ne usa sempre comunque un tot fisso di byte.
Io ho fatto una cosa simile in una mia libreria e funziona con il buffer della dimensione minima necessaria. Dovrei avere un TFT nel cassetto, se riesco mi tolgo questa curiosità.