I am aware that you haven't worked on this for a while but I have been trying to figure out my issue for a very long time and was hoping you could help me.
I am using a tjctm24024-spi (ILI9341) TFT screen - Like this - a ESP32 and have tried the built in and an external SD card adapter.
I have had success with the same setup getting jpeg images and displaying them on the screen. I have also run the SD library examples with success. With this I believe that my hardware isn't the issue.
My SD card has a single folder called "GIF" and a single file inside from the example gifs "trump.gif".
the code I am using is below - pulled from the AnimatedGIF fork you have made and is a slightly modified version of the adafruit_gfx_sdcard.ino example sketch.
I run the code and my screen is filled in black - as it should from line 179 ( tft.fillScreen(ILI9341_BLACK) ) then in my serial monitor I get -
SD Card mount succeeded!
About to call gif.open
Error opening file = 5
I am unsure what the error code "5" means and what I am doing wrong. If you have a moment could you give me some advice please.
#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include <SD.h>
#define TFT_CS 5 //10
#define TFT_RST 12 //8
#define TFT_DC 13 //9
#define TFT_MOSI 23 //11
#define TFT_CLK 18 //13
#define TFT_MISO 19 //12
#define BUILTIN_SDCARD 15 //0
#define DISPLAY_WIDTH 320
#define DISPLAY_HEIGHT 240
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);
AnimatedGIF gif;
File f;
void * GIFOpenFile(const char *fname, int32_t *pSize)
{
f = SD.open(fname);
if (f)
{
*pSize = f.size();
return (void *)&f;
}
return NULL;
} /* GIFOpenFile() */
void GIFCloseFile(void *pHandle)
{
File *f = static_cast<File *>(pHandle);
if (f != NULL)
f->close();
} /* GIFCloseFile() */
int32_t GIFReadFile(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen)
{
int32_t iBytesRead;
iBytesRead = iLen;
File *f = static_cast<File *>(pFile->fHandle);
// Note: If you read a file all the way to the last byte, seek() stops working
if ((pFile->iSize - pFile->iPos) < iLen)
iBytesRead = pFile->iSize - pFile->iPos - 1; // <-- ugly work-around
if (iBytesRead <= 0)
return 0;
iBytesRead = (int32_t)f->read(pBuf, iBytesRead);
pFile->iPos = f->position();
return iBytesRead;
} /* GIFReadFile() */
int32_t GIFSeekFile(GIFFILE *pFile, int32_t iPosition)
{
int i = micros();
File *f = static_cast<File *>(pFile->fHandle);
f->seek(iPosition);
pFile->iPos = (int32_t)f->position();
i = micros() - i;
// Serial.printf("Seek time = %d us\n", i);
return pFile->iPos;
} /* GIFSeekFile() */
// Draw a line of image directly on the LCD
void GIFDraw(GIFDRAW *pDraw)
{
uint8_t *s;
uint16_t *d, *usPalette, usTemp[320];
int x, y, iWidth;
iWidth = pDraw->iWidth;
if (iWidth + pDraw->iX > DISPLAY_WIDTH)
iWidth = DISPLAY_WIDTH - pDraw->iX;
usPalette = pDraw->pPalette;
y = pDraw->iY + pDraw->y; // current line
if (y >= DISPLAY_HEIGHT || pDraw->iX >= DISPLAY_WIDTH || iWidth < 1)
return;
s = pDraw->pPixels;
if (pDraw->ucDisposalMethod == 2) // restore to background color
{
for (x=0; x<iWidth; x++)
{
if (s[x] == pDraw->ucTransparent)
s[x] = pDraw->ucBackground;
}
pDraw->ucHasTransparency = 0;
}
// Apply the new pixels to the main image
if (pDraw->ucHasTransparency) // if transparency used
{
uint8_t *pEnd, c, ucTransparent = pDraw->ucTransparent;
int x, iCount;
pEnd = s + iWidth;
x = 0;
iCount = 0; // count non-transparent pixels
while(x < iWidth)
{
c = ucTransparent-1;
d = usTemp;
while (c != ucTransparent && s < pEnd)
{
c = *s++;
if (c == ucTransparent) // done, stop
{
s--; // back up to treat it like transparent
}
else // opaque
{
*d++ = usPalette[c];
iCount++;
}
} // while looking for opaque pixels
if (iCount) // any opaque pixels?
{
tft.startWrite();
tft.setAddrWindow(pDraw->iX+x, y, iCount, 1);
tft.writePixels(usTemp, iCount, false, false);
tft.endWrite();
x += iCount;
iCount = 0;
}
// no, look for a run of transparent pixels
c = ucTransparent;
while (c == ucTransparent && s < pEnd)
{
c = *s++;
if (c == ucTransparent)
iCount++;
else
s--;
}
if (iCount)
{
x += iCount; // skip these
iCount = 0;
}
}
}
else
{
s = pDraw->pPixels;
// Translate the 8-bit pixels through the RGB565 palette (already byte reversed)
for (x=0; x<iWidth; x++)
usTemp[x] = usPalette[*s++];
tft.startWrite();
tft.setAddrWindow(pDraw->iX, y, iWidth, 1);
tft.writePixels(usTemp, iWidth, false, false);
tft.endWrite();
}
} /* GIFDraw() */
void setup() {
Serial.begin(115200);
while (!Serial);
SPI.begin();
// Note - some systems (ESP32?) require an SPI.begin() before calling SD.begin()
// this code was tested on a Teensy 4.1 board
if(!SD.begin(BUILTIN_SDCARD))
{
Serial.println("SD Card mount failed!");
return;
}
else
{
Serial.println("SD Card mount succeeded!");
}
// put your setup code here, to run once:
tft.begin();
tft.setRotation(1);
tft.fillScreen(ILI9341_BLACK);
gif.begin(LITTLE_ENDIAN_PIXELS);
}
void loop() {
// put your main code here, to run repeatedly:
Serial.println("About to call gif.open");
if (gif.open("/GIF/trump.gif", GIFOpenFile, GIFCloseFile, GIFReadFile, GIFSeekFile, GIFDraw))
{
GIFINFO gi;
Serial.printf("Successfully opened GIF; Canvas size = %d x %d\n", gif.getCanvasWidth(), gif.getCanvasHeight());
if (gif.getInfo(&gi)) {
Serial.printf("frame count: %d\n", gi.iFrameCount);
Serial.printf("duration: %d ms\n", gi.iDuration);
Serial.printf("max delay: %d ms\n", gi.iMaxDelay);
Serial.printf("min delay: %d ms\n", gi.iMinDelay);
}
while (gif.playFrame(true, NULL))
{
}
gif.close();
}
else
{
Serial.printf("Error opening file = %d\n", gif.getLastError());
while (1)
{};
}
}```
Hi,
I am aware that you haven't worked on this for a while but I have been trying to figure out my issue for a very long time and was hoping you could help me.
I am using a tjctm24024-spi (ILI9341) TFT screen - Like this - a ESP32 and have tried the built in and an external SD card adapter.
I have had success with the same setup getting jpeg images and displaying them on the screen. I have also run the SD library examples with success. With this I believe that my hardware isn't the issue.
My SD card has a single folder called "GIF" and a single file inside from the example gifs "trump.gif".
the code I am using is below - pulled from the AnimatedGIF fork you have made and is a slightly modified version of the adafruit_gfx_sdcard.ino example sketch.
I run the code and my screen is filled in black - as it should from line 179 ( tft.fillScreen(ILI9341_BLACK) ) then in my serial monitor I get -
SD Card mount succeeded! About to call gif.open Error opening file = 5
I am unsure what the error code "5" means and what I am doing wrong. If you have a moment could you give me some advice please.