The problem is that I will probably be storing various different jpegs in SPIFFS which will have nothing to do with my startup screen animation. If I'd just go through all the files in the "flat" SPIFFS, it would lead to unwanted images being displayed. Also, there will be a number of small .mp3 files in SPIFFS, which the loop would probably also go through (?) and try to open them as jpegs unsuccessfully...
I've tried out @chadwr's code snippet, but now that that part of the code compiles, there is more trouble about. The sketch compiles and uploads, but the ESP32 panics on boot, giving this message:
Guru Meditation Error: Core 1 panic'ed (IntegerDivideByZero)
. Exception was unhandled.
Register dump:
PC : 0x400d0cae PS : 0x00060730 A0 : 0x800d0e4c A1 : 0x3ffcad60
A2 : 0x3ffc2c04 A3 : 0x00000000 A4 : 0x00000000 A5 : 0x3f405286
A6 : 0x00000000 A7 : 0xff000000 A8 : 0x800d3b60 A9 : 0x00000000
A10 : 0x3ffc736c A11 : 0xffffffff A12 : 0x3ffc2c1c A13 : 0x3f405286
A14 : 0x00000072 A15 : 0xff000000 SAR : 0x00000008 EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000 LBEG : 0x4000c46c LEND : 0x4000c477 LCOUNT : 0x00000000
Backtrace: 0x400d0cae:0x3ffcad60 0x400d0e49:0x3ffcadb0 0x400d0f4b:0x3ffcadf0 0x400efa0f:0x3ffcae50
Here is my code as it is so far. It's basically a condensed version of the examples found in the TFT_eSPI library. Looking at it, coud you think of a reason why it does that? I don't see any division by zero in the code. And commenting out my loop section discussed in this thread has no effect on the problem.
#define FS_NO_GLOBALS
#define minimum(a,b) (((a) < (b)) ? (a) : (b))
#include <FS.h>
#include <JPEGDecoder.h>
#include <SPI.h>
#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();
void jpegRender(int xpos, int ypos) {
// retrieve infomration about the image
uint16_t *pImg;
uint16_t mcu_w = JpegDec.MCUWidth;
uint16_t mcu_h = JpegDec.MCUHeight;
uint32_t max_x = JpegDec.width;
uint32_t max_y = JpegDec.height;
uint32_t min_w = minimum(mcu_w, max_x % mcu_w);
uint32_t min_h = minimum(mcu_h, max_y % mcu_h);
// save the current image block size
uint32_t win_w = mcu_w;
uint32_t win_h = mcu_h;
max_x += xpos;
max_y += ypos;
// read each MCU block until there are no more
while ( JpegDec.readSwappedBytes()) { // Swap byte order so the SPI buffer can be used
// save a pointer to the image block
pImg = JpegDec.pImage;
// calculate where the image block should be drawn on the screen
int mcu_x = JpegDec.MCUx * mcu_w + xpos; // Calculate coordinates of top left corner of current MCU
int mcu_y = JpegDec.MCUy * mcu_h + ypos;
// check if the image block size needs to be changed for the right edge
if (mcu_x + mcu_w <= max_x) win_w = mcu_w;
else win_w = min_w;
// check if the image block size needs to be changed for the bottom edge
if (mcu_y + mcu_h <= max_y) win_h = mcu_h;
else win_h = min_h;
// copy pixels into a contiguous block
if (win_w != mcu_w)
{
uint16_t *cImg;
int p = 0;
cImg = pImg + win_w;
for (int h = 1; h < win_h; h++)
{
p += mcu_w;
for (int w = 0; w < win_w; w++)
{
*cImg = *(pImg + w + p);
cImg++;
}
}
}
// draw image MCU block only if it will fit on the screen
if ( ( mcu_x + win_w) <= tft.width() && ( mcu_y + win_h) <= tft.height())
{
tft.pushRect(mcu_x, mcu_y, win_w, win_h, pImg);
}
else if ( ( mcu_y + win_h) >= tft.height()) JpegDec.abort();
}
}
void drawJpeg(const char *filename, int xpos, int ypos) {
// Open the named file (the Jpeg decoder library will close it after rendering image)
fs::File jpegFile = SPIFFS.open( filename, "r"); // File handle reference for SPIFFS
// File jpegFile = SD.open( filename, FILE_READ); // or, file handle reference for SD library
if ( !jpegFile ) {
Serial.print("ERROR: File \""); Serial.print(filename); Serial.println ("\" not found!");
return;
}
// Use one of the three following methods to initialise the decoder:
//boolean decoded = JpegDec.decodeFsFile(jpegFile); // Pass a SPIFFS file handle to the decoder,
//boolean decoded = JpegDec.decodeSdFile(jpegFile); // or pass the SD file handle to the decoder,
boolean decoded = JpegDec.decodeFsFile(filename); // or pass the filename (leading / distinguishes SPIFFS files)
// Note: the filename can be a String or character array type
if (decoded) jpegRender(xpos, ypos);
else Serial.println("Jpeg file format not supported!");
}
void setup() {
Serial.begin(115200);
SPIFFS.begin(true);
tft.begin();
tft.setRotation(2);
tft.fillScreen(TFT_WHITE);
for (int i = 1; i <= 31; i++) {
String fileName = "/" + String(i) + ".jpg";
char jpegs[fileName.length() + 1];
fileName.toCharArray(jpegs, sizeof(jpegs));
drawJpeg(jpegs, 0, 0);
delay(80);
}
}
void loop() {
}