thelastoutpostworkshop / AnimatedGIF340_240

Animated GIF on a 320x240 LCD Display (ILI9341) with the ESP32
https://youtu.be/omUWkUqFYrQ
MIT License
3 stars 0 forks source link

AnimatedGIF340_240 for 1.14" ST7789V Display #1

Open GarnetUngar opened 4 days ago

GarnetUngar commented 4 days ago
#include <bb_spi_lcd.h>
#include <AnimatedGIF.h>

// Master Animated GIF on a 320x240 SPI LCD Screen
// Youtube Tutorial: https://youtu.be/omUWkUqFYrQ
// Tested with Espressif ESP32 Arduino Core v3.0.2, 3.0.3
// Using ESP32-S3 with 8MB of PSRAM
// See also the Tutorial on how to create ESP32 custom partitions:
//
#include "esp_flash.h"
#include "esp_partition.h"

#include <bb_spi_lcd.h>  // gif_files\hud_a.h: No such file or directory
                         // Tested on version 2.5.4, 2.6.0
#include <AnimatedGIF.h> // Install this library with the Arduino IDE Library Manager
                         // Tested on version 2.1.1

// GIF files
#include "hud_a.h"                 //GIF size in FLASH memory is 1.7MB
#include "x_wing.h"                //GIF size in FLASH memory is 0.9MB
#include "death_star.h"            //GIF size in FLASH memory is 1.7MB
#include "star_destroyer.h"        //GIF size in FLASH memory is 1MB
#include "star_destroyer_planet.h" //GIF size in FLASH memory is 2.3MB
#include "scanner.h"               //GIF size in FLASH memory is 1.1MB
#include "star_trek_hud.h"         //GIF size in FLASH memory is 1.6MB
#include "Sickbay_11_26.h"
#include "jedi_battle.h"           //GIF size in FLASH memory is 3.3MB (use partitions.csv for this one, if you your ESP32 board has 4MB Flash size)

BB_SPI_LCD tft; // Main object for the display driver

// GIF to display
#define GifData Sickbay_11_26 // Change image to display (image name in gif_files\[image header file].h)

void setup()
{
  Serial.begin(115200);
 spilcdInit(&_lcd, LCD_ST7789, FLAGS_INVERT, 40000000, 15, 2, -1, 21, 12, 13, 14, 1); // Cheap Yellow Display 2 USB (2.8 w/resistive touch, 2 USB ports)
 spilcdSetOrientation(&_lcd, LCD_ORIENTATION_270);

 tft.fillScreen(TFT_BLACK);

  AnimatedGIF *gif;
  gif = openGif((uint8_t *)GifData, sizeof(GifData));
  if (gif == NULL)
  {
    Serial.println("Cannot open GIF");
    while (true)
    {
      //  no need to continue
    }
  }

  while (true)
  {
    gif->playFrame(true, NULL);
  }
}

void loop()
{
  delay(1);
}

// Open Gif and allocate memory
AnimatedGIF *openGif(uint8_t *gifdata, size_t gifsize)
{
  AnimatedGIF *gif;
  gif = (AnimatedGIF *)malloc(sizeof(AnimatedGIF));
  if (gif == NULL)
  {
    Serial.println("Not RAM Enough memory for GIF structure");
    return NULL;
  }

  gif->begin(GIF_PALETTE_RGB565_BE); // Set the cooked output type we want (compatible with SPI LCDs)

  if (gif->open(gifdata, gifsize, GIFDraw))
  {
    Serial.printf("Successfully opened GIF; Canvas size = %d x %d\n", gif->getCanvasWidth(), gif->getCanvasHeight());
    Serial.printf("GIF memory size is %ld (%2.2f MB)", gifsize, (float)gifsize / (1024 * 1024));
    gif->setDrawType(GIF_DRAW_COOKED); // We want the Animated GIF library to generate ready-made pixels
    if (gif->allocFrameBuf(GIFAlloc) != GIF_SUCCESS)
    {
      Serial.println("Not Enough RAM memory for frame buffer");
      return NULL;
    }
    return gif;
  }
  else
  {
    printGifErrorMessage(gif->getLastError());
    return NULL;
  }
}

//
// The memory management functions are needed to keep operating system
// dependencies out of the core library code
//
// memory allocation callback function
void *GIFAlloc(uint32_t u32Size)
{
  return malloc(u32Size);
} /* GIFAlloc() */
// memory free callback function
void GIFFree(void *p)
{
  free(p);
}

// Draw callback from the AnimatedGIF decoder
void GIFDraw(GIFDRAW *pDraw)
{
  if (pDraw->y == 0)
  { // set the memory window (once per frame) when the first line is rendered
    tft.setAddrWindow(pDraw->iX, pDraw->iY, pDraw->iWidth, pDraw->iHeight);
  }
  // For all other lines, just push the pixels to the display. We requested 'COOKED'big-endian RGB565 and
  tft.pushPixels((uint16_t *)pDraw->pPixels, pDraw->iWidth);
}

// Get human-readable error related to GIF
void printGifErrorMessage(int errorCode)
{
  switch (errorCode)
  {
  case GIF_DECODE_ERROR:
    Serial.println("GIF Decoding Error");
    break;
  case GIF_TOO_WIDE:
    Serial.println("GIF Too Wide");
    break;
  case GIF_INVALID_PARAMETER:
    Serial.println("Invalid Parameter for gif open");
    break;
  case GIF_UNSUPPORTED_FEATURE:
    Serial.println("Unsupported feature in GIF");
    break;
  case GIF_FILE_NOT_OPEN:
    Serial.println("GIF File not open");
    break;
  case GIF_EARLY_EOF:
    Serial.println("GIF early end of file");
    break;
  case GIF_EMPTY_FRAME:
    Serial.println("GIF with empty frame");
    break;
  case GIF_BAD_FILE:
    Serial.println("GIF bad file");
    break;
  case GIF_ERROR_MEMORY:
    Serial.println("GIF memory Error");
    break;
  default:
    Serial.println("Unknown Error");
    break;
  }
}
thelastoutpostworkshop commented 4 days ago

here is the code corrected. I have commented out your gif because I do not have them, just uncomment them on your side:


#include <AnimatedGIF.h>

// Master Animated GIF on a 320x240 SPI LCD Screen
// Youtube Tutorial: https://youtu.be/omUWkUqFYrQ
// Tested with Espressif ESP32 Arduino Core v3.0.2, 3.0.3
// Using ESP32-S3 with 8MB of PSRAM
// See also the Tutorial on how to create ESP32 custom partitions:
//
#include "esp_flash.h"
#include "esp_partition.h"

#include <bb_spi_lcd.h>  // gif_files\hud_a.h: No such file or directory
                         // Tested on version 2.5.4, 2.6.0
#include <AnimatedGIF.h> // Install this library with the Arduino IDE Library Manager
                         // Tested on version 2.1.1

// GIF files
#include "hud_a.h"                 //GIF size in FLASH memory is 1.7MB
#include "x_wing.h"                //GIF size in FLASH memory is 0.9MB
#include "death_star.h"            //GIF size in FLASH memory is 1.7MB
#include "star_destroyer.h"        //GIF size in FLASH memory is 1MB
#include "star_destroyer_planet.h" //GIF size in FLASH memory is 2.3MB
// #include "scanner.h"               //GIF size in FLASH memory is 1.1MB
#include "star_trek_hud.h"         //GIF size in FLASH memory is 1.6MB
// #include "Sickbay_11_26.h"
#include "jedi_battle.h"           //GIF size in FLASH memory is 3.3MB (use partitions.csv for this one, if you your ESP32 board has 4MB Flash size)

BB_SPI_LCD tft; // Main object for the display driver

// GIF to display
#define GifData hud_a // Change image to display (image name in gif_files\[image header file].h)

void setup()
{
  Serial.begin(115200);
 tft.begin(LCD_ST7789, FLAGS_INVERT, 40000000, 15, 2, -1, 21, 12, 13, 14); // Cheap Yellow Display 2 USB (2.8 w/resistive touch, 2 USB ports)
 tft.setRotation(LCD_ORIENTATION_270);

 tft.fillScreen(TFT_BLACK);

  AnimatedGIF *gif;
  gif = openGif((uint8_t *)GifData, sizeof(GifData));
  if (gif == NULL)
  {
    Serial.println("Cannot open GIF");
    while (true)
    {
      //  no need to continue
    }
  }

  while (true)
  {
    gif->playFrame(true, NULL);
  }
}

void loop()
{
  delay(1);
}

// Open Gif and allocate memory
AnimatedGIF *openGif(uint8_t *gifdata, size_t gifsize)
{
  AnimatedGIF *gif;
  gif = (AnimatedGIF *)malloc(sizeof(AnimatedGIF));
  if (gif == NULL)
  {
    Serial.println("Not RAM Enough memory for GIF structure");
    return NULL;
  }

  gif->begin(GIF_PALETTE_RGB565_BE); // Set the cooked output type we want (compatible with SPI LCDs)

  if (gif->open(gifdata, gifsize, GIFDraw))
  {
    Serial.printf("Successfully opened GIF; Canvas size = %d x %d\n", gif->getCanvasWidth(), gif->getCanvasHeight());
    Serial.printf("GIF memory size is %ld (%2.2f MB)", gifsize, (float)gifsize / (1024 * 1024));
    gif->setDrawType(GIF_DRAW_COOKED); // We want the Animated GIF library to generate ready-made pixels
    if (gif->allocFrameBuf(GIFAlloc) != GIF_SUCCESS)
    {
      Serial.println("Not Enough RAM memory for frame buffer");
      return NULL;
    }
    return gif;
  }
  else
  {
    printGifErrorMessage(gif->getLastError());
    return NULL;
  }
}

//
// The memory management functions are needed to keep operating system
// dependencies out of the core library code
//
// memory allocation callback function
void *GIFAlloc(uint32_t u32Size)
{
  return malloc(u32Size);
} /* GIFAlloc() */
// memory free callback function
void GIFFree(void *p)
{
  free(p);
}

// Draw callback from the AnimatedGIF decoder
void GIFDraw(GIFDRAW *pDraw)
{
  if (pDraw->y == 0)
  { // set the memory window (once per frame) when the first line is rendered
    tft.setAddrWindow(pDraw->iX, pDraw->iY, pDraw->iWidth, pDraw->iHeight);
  }
  // For all other lines, just push the pixels to the display. We requested 'COOKED'big-endian RGB565 and
  tft.pushPixels((uint16_t *)pDraw->pPixels, pDraw->iWidth);
}

// Get human-readable error related to GIF
void printGifErrorMessage(int errorCode)
{
  switch (errorCode)
  {
  case GIF_DECODE_ERROR:
    Serial.println("GIF Decoding Error");
    break;
  case GIF_TOO_WIDE:
    Serial.println("GIF Too Wide");
    break;
  case GIF_INVALID_PARAMETER:
    Serial.println("Invalid Parameter for gif open");
    break;
  case GIF_UNSUPPORTED_FEATURE:
    Serial.println("Unsupported feature in GIF");
    break;
  case GIF_FILE_NOT_OPEN:
    Serial.println("GIF File not open");
    break;
  case GIF_EARLY_EOF:
    Serial.println("GIF early end of file");
    break;
  case GIF_EMPTY_FRAME:
    Serial.println("GIF with empty frame");
    break;
  case GIF_BAD_FILE:
    Serial.println("GIF bad file");
    break;
  case GIF_ERROR_MEMORY:
    Serial.println("GIF memory Error");
    break;
  default:
    Serial.println("Unknown Error");
    break;
  }
}
GarnetUngar commented 4 days ago

Thanks! Here's the latest error:

C:\Users\Griselda Grumpy\Documents\Arduino\AnimatedGIF340_240\AnimatedGIF340_240_for_ST7789v_version_2\AnimatedGIF340_240_for_ST7789v_version_2\AnimatedGIF340_240_for_ST7789v_version_2.ino:156:2: error: stray '' in program 156 | }``` | ^ C:\Users\Griselda Grumpy\Documents\Arduino\AnimatedGIF340_240\AnimatedGIF340_240_for_ST7789v_version_2\AnimatedGIF340_240_for_ST7789v_version_2\AnimatedGIF340_240_for_ST7789v_version_2.ino:156:3: error: stray '' in program 156 | } | ^ C:\Users\Griselda Grumpy\Documents\Arduino\AnimatedGIF340_240\AnimatedGIF340_240_for_ST7789v_version_2\AnimatedGIF340_240_for_ST7789v_version_2\AnimatedGIF340_240_for_ST7789v_version_2.ino:156:4: error: stray '`' in program 156 | } | ^

exit status 1

Compilation error: stray '`' in program

thelastoutpostworkshop commented 4 days ago

very strange error, does not say much, line 156 is almost the end of the file.
Have you pasted the whole code correctly ? If yes try compiling it with the code corrected above, without your gif to see if it worls

GarnetUngar commented 4 days ago

Hi, I just pasted it again, with only your code, no changes. Got the same error, line 158 is the very last line.

C:\Users\Griselda Grumpy\Documents\Arduino\AnimatedGIF340_240\AnimatedGIF340_240_for_ST7789v_version_2\AnimatedGIF340_240_for_ST7789v_version_2\AnimatedGIF340_240_for_ST7789v_version_2.ino:158:2: error: stray '' in program 158 | }``` | ^ C:\Users\Griselda Grumpy\Documents\Arduino\AnimatedGIF340_240\AnimatedGIF340_240_for_ST7789v_version_2\AnimatedGIF340_240_for_ST7789v_version_2\AnimatedGIF340_240_for_ST7789v_version_2.ino:158:3: error: stray '' in program 158 | } | ^ C:\Users\Griselda Grumpy\Documents\Arduino\AnimatedGIF340_240\AnimatedGIF340_240_for_ST7789v_version_2\AnimatedGIF340_240_for_ST7789v_version_2\AnimatedGIF340_240_for_ST7789v_version_2.ino:158:4: error: stray '`' in program 158 | } | ^

exit status 1

Compilation error: stray '`' in program

thelastoutpostworkshop commented 4 days ago

ok found out what the problem is, there are characters at the end of the file that I copied that should not be there. I have corrected it above, you can copy it again

GarnetUngar commented 4 days ago

Hi, it compiled without error, but now the lcd screen is blank. I did include my own gif back into it. I also tried unplugging and then repowering the esp32. No luck:

#include <AnimatedGIF.h>

// Master Animated GIF on a 320x240 SPI LCD Screen
// Youtube Tutorial: https://youtu.be/omUWkUqFYrQ
// Tested with Espressif ESP32 Arduino Core v3.0.2, 3.0.3
// Using ESP32-S3 with 8MB of PSRAM
// See also the Tutorial on how to create ESP32 custom partitions:
//
#include "esp_flash.h"
#include "esp_partition.h"

#include <bb_spi_lcd.h>  // gif_files\hud_a.h: No such file or directory
                         // Tested on version 2.5.4, 2.6.0
#include <AnimatedGIF.h> // Install this library with the Arduino IDE Library Manager
                         // Tested on version 2.1.1

// GIF files
#include "hud_a.h"                 //GIF size in FLASH memory is 1.7MB
#include "x_wing.h"                //GIF size in FLASH memory is 0.9MB
#include "death_star.h"            //GIF size in FLASH memory is 1.7MB
#include "star_destroyer.h"        //GIF size in FLASH memory is 1MB
#include "star_destroyer_planet.h" //GIF size in FLASH memory is 2.3MB
#include "scanner.h"               //GIF size in FLASH memory is 1.1MB
#include "star_trek_hud.h"         //GIF size in FLASH memory is 1.6MB
#include "Sickbay_11_26.h"
#include "jedi_battle.h"           //GIF size in FLASH memory is 3.3MB (use partitions.csv for this one, if you your ESP32 board has 4MB Flash size)

BB_SPI_LCD tft; // Main object for the display driver

// GIF to display
#define GifData Sickbay_11_26 // Change image to display (image name in gif_files\[image header file].h)

void setup()
{
  Serial.begin(115200);
 tft.begin(LCD_ST7789, FLAGS_INVERT, 40000000, 15, 2, -1, 21, 12, 13, 14); // Cheap Yellow Display 2 USB (2.8 w/resistive touch, 2 USB ports)
 tft.setRotation(LCD_ORIENTATION_270);

 tft.fillScreen(TFT_BLACK);

  AnimatedGIF *gif;
  gif = openGif((uint8_t *)GifData, sizeof(GifData));
  if (gif == NULL)
  {
    Serial.println("Cannot open GIF");
    while (true)
    {
      //  no need to continue
    }
  }

  while (true)
  {
    gif->playFrame(true, NULL);
  }
}

void loop()
{
  delay(1);
}

// Open Gif and allocate memory
AnimatedGIF *openGif(uint8_t *gifdata, size_t gifsize)
{
  AnimatedGIF *gif;
  gif = (AnimatedGIF *)malloc(sizeof(AnimatedGIF));
  if (gif == NULL)
  {
    Serial.println("Not RAM Enough memory for GIF structure");
    return NULL;
  }

  gif->begin(GIF_PALETTE_RGB565_BE); // Set the cooked output type we want (compatible with SPI LCDs)

  if (gif->open(gifdata, gifsize, GIFDraw))
  {
    Serial.printf("Successfully opened GIF; Canvas size = %d x %d\n", gif->getCanvasWidth(), gif->getCanvasHeight());
    Serial.printf("GIF memory size is %ld (%2.2f MB)", gifsize, (float)gifsize / (1024 * 1024));
    gif->setDrawType(GIF_DRAW_COOKED); // We want the Animated GIF library to generate ready-made pixels
    if (gif->allocFrameBuf(GIFAlloc) != GIF_SUCCESS)
    {
      Serial.println("Not Enough RAM memory for frame buffer");
      return NULL;
    }
    return gif;
  }
  else
  {
    printGifErrorMessage(gif->getLastError());
    return NULL;
  }
}

//
// The memory management functions are needed to keep operating system
// dependencies out of the core library code
//
// memory allocation callback function
void *GIFAlloc(uint32_t u32Size)
{
  return malloc(u32Size);
} /* GIFAlloc() */
// memory free callback function
void GIFFree(void *p)
{
  free(p);
}

// Draw callback from the AnimatedGIF decoder
void GIFDraw(GIFDRAW *pDraw)
{
  if (pDraw->y == 0)
  { // set the memory window (once per frame) when the first line is rendered
    tft.setAddrWindow(pDraw->iX, pDraw->iY, pDraw->iWidth, pDraw->iHeight);
  }
  // For all other lines, just push the pixels to the display. We requested 'COOKED'big-endian RGB565 and
  tft.pushPixels((uint16_t *)pDraw->pPixels, pDraw->iWidth);
}

// Get human-readable error related to GIF
void printGifErrorMessage(int errorCode)
{
  switch (errorCode)
  {
  case GIF_DECODE_ERROR:
    Serial.println("GIF Decoding Error");
    break;
  case GIF_TOO_WIDE:
    Serial.println("GIF Too Wide");
    break;
  case GIF_INVALID_PARAMETER:
    Serial.println("Invalid Parameter for gif open");
    break;
  case GIF_UNSUPPORTED_FEATURE:
    Serial.println("Unsupported feature in GIF");
    break;
  case GIF_FILE_NOT_OPEN:
    Serial.println("GIF File not open");
    break;
  case GIF_EARLY_EOF:
    Serial.println("GIF early end of file");
    break;
  case GIF_EMPTY_FRAME:
    Serial.println("GIF with empty frame");
    break;
  case GIF_BAD_FILE:
    Serial.println("GIF bad file");
    break;
  case GIF_ERROR_MEMORY:
    Serial.println("GIF memory Error");
    break;
  default:
    Serial.println("Unknown Error");
    break;
  }
}
thelastoutpostworkshop commented 4 days ago

Give me the link to the display you are using

GarnetUngar commented 4 days ago

https://www.aliexpress.us/item/3256804938214567.html?spm=a2g0o.order_list.order_list_main.34.21ef1802rkdEnY&gatewayAdapt=glo2usa

GarnetUngar commented 4 days ago

Is my wiring right? Or does the new sketch require the use of different pins on the esp32?

ST7789V --- esp32S3 BLK --- 3.3V RES --- 17 DC --- 18 CS --- 8 SCL --- 3 SDA --- 9 GND --- GND VCC --- 3.3V

thelastoutpostworkshop commented 4 days ago

I can't tell, what do you use as a reference for the pinout of your screen ?

GarnetUngar commented 4 days ago

I used the same wiring as in your video, finding the alternate names for the terminals on the ST7789v: Esp32 wiring

BL=BLK RST=RES DC=DC CS=CS CLK=SCL DIN=SDA GNA=GND VCC=VCC

thelastoutpostworkshop commented 4 days ago

so your screen has the same labels as in my video ?

GarnetUngar commented 4 days ago

Only if you use the alternate names (see my little chart above). My screen looks exactly like the Ali Espress link.

GarnetUngar commented 4 days ago

Forgive my ignorance, but does the new code indicate which terminals are to be used?

tft.begin(LCD_ST7789, FLAGS_INVERT, 40000000, 15, 2, -1, 21, 12, 13, 14);

thelastoutpostworkshop commented 4 days ago

They indicate the pins to use. Change this line : tft.begin(LCD_ST7789, FLAGS_INVERT, 40000000, 15, 2, -1, 21, 12, 13, 14); // Cheap Yellow Display 2 USB (2.8 w/resistive touch, 2 USB ports) To tft.begin(LCD_ST7789, FLAGS_INVERT, 40000000, 8, 18, 17, -1, -1, 9, 3);

GarnetUngar commented 4 days ago

I will give it a go. Thank you so much for all your time!!

thelastoutpostworkshop commented 4 days ago

for better comprehension, here is the updated code with pins as you are using them:


#include <AnimatedGIF.h>

// Master Animated GIF on a 320x240 SPI LCD Screen
// Youtube Tutorial: https://youtu.be/omUWkUqFYrQ
// Tested with Espressif ESP32 Arduino Core v3.0.2, 3.0.3
// Using ESP32-S3 with 8MB of PSRAM
// See also the Tutorial on how to create ESP32 custom partitions:
//
#include "esp_flash.h"
#include "esp_partition.h"

#include <bb_spi_lcd.h>  // gif_files\hud_a.h: No such file or directory
                         // Tested on version 2.5.4, 2.6.0
#include <AnimatedGIF.h> // Install this library with the Arduino IDE Library Manager
                         // Tested on version 2.1.1

// GIF files
#include "hud_a.h"                 //GIF size in FLASH memory is 1.7MB
#include "x_wing.h"                //GIF size in FLASH memory is 0.9MB
#include "death_star.h"            //GIF size in FLASH memory is 1.7MB
#include "star_destroyer.h"        //GIF size in FLASH memory is 1MB
#include "star_destroyer_planet.h" //GIF size in FLASH memory is 2.3MB
// #include "scanner.h"               //GIF size in FLASH memory is 1.1MB
#include "star_trek_hud.h" //GIF size in FLASH memory is 1.6MB
// #include "Sickbay_11_26.h"
#include "jedi_battle.h" //GIF size in FLASH memory is 3.3MB (use partitions.csv for this one, if you your ESP32 board has 4MB Flash size)

BB_SPI_LCD tft; // Main object for the display driver
// Screen pins
#define TFT_BL -1
#define TFT_RST 17
#define TFT_DC 18
#define TFT_CS 8
#define TFT_CLK 3
#define TFT_DIN 9 // MOSI
#define TFT_MISO -1

// GIF to display
#define GifData hud_a // Change image to display (image name in gif_files\[image header file].h)

void setup()
{
  Serial.begin(115200);
  tft.begin(LCD_ST7789, FLAGS_INVERT, 40000000, TFT_CS, TFT_DC, TFT_RST, TFT_BL, TFT_MISO, TFT_DIN, TFT_CLK);
  tft.setRotation(LCD_ORIENTATION_270);

  tft.fillScreen(TFT_BLACK);

  AnimatedGIF *gif;
  gif = openGif((uint8_t *)GifData, sizeof(GifData));
  if (gif == NULL)
  {
    Serial.println("Cannot open GIF");
    while (true)
    {
      //  no need to continue
    }
  }

  while (true)
  {
    gif->playFrame(true, NULL);
  }
}

void loop()
{
  delay(1);
}

// Open Gif and allocate memory
AnimatedGIF *openGif(uint8_t *gifdata, size_t gifsize)
{
  AnimatedGIF *gif;
  gif = (AnimatedGIF *)malloc(sizeof(AnimatedGIF));
  if (gif == NULL)
  {
    Serial.println("Not RAM Enough memory for GIF structure");
    return NULL;
  }

  gif->begin(GIF_PALETTE_RGB565_BE); // Set the cooked output type we want (compatible with SPI LCDs)

  if (gif->open(gifdata, gifsize, GIFDraw))
  {
    Serial.printf("Successfully opened GIF; Canvas size = %d x %d\n", gif->getCanvasWidth(), gif->getCanvasHeight());
    Serial.printf("GIF memory size is %ld (%2.2f MB)", gifsize, (float)gifsize / (1024 * 1024));
    gif->setDrawType(GIF_DRAW_COOKED); // We want the Animated GIF library to generate ready-made pixels
    if (gif->allocFrameBuf(GIFAlloc) != GIF_SUCCESS)
    {
      Serial.println("Not Enough RAM memory for frame buffer");
      return NULL;
    }
    return gif;
  }
  else
  {
    printGifErrorMessage(gif->getLastError());
    return NULL;
  }
}

//
// The memory management functions are needed to keep operating system
// dependencies out of the core library code
//
// memory allocation callback function
void *GIFAlloc(uint32_t u32Size)
{
  return malloc(u32Size);
} /* GIFAlloc() */
// memory free callback function
void GIFFree(void *p)
{
  free(p);
}

// Draw callback from the AnimatedGIF decoder
void GIFDraw(GIFDRAW *pDraw)
{
  if (pDraw->y == 0)
  { // set the memory window (once per frame) when the first line is rendered
    tft.setAddrWindow(pDraw->iX, pDraw->iY, pDraw->iWidth, pDraw->iHeight);
  }
  // For all other lines, just push the pixels to the display. We requested 'COOKED'big-endian RGB565 and
  tft.pushPixels((uint16_t *)pDraw->pPixels, pDraw->iWidth);
}

// Get human-readable error related to GIF
void printGifErrorMessage(int errorCode)
{
  switch (errorCode)
  {
  case GIF_DECODE_ERROR:
    Serial.println("GIF Decoding Error");
    break;
  case GIF_TOO_WIDE:
    Serial.println("GIF Too Wide");
    break;
  case GIF_INVALID_PARAMETER:
    Serial.println("Invalid Parameter for gif open");
    break;
  case GIF_UNSUPPORTED_FEATURE:
    Serial.println("Unsupported feature in GIF");
    break;
  case GIF_FILE_NOT_OPEN:
    Serial.println("GIF File not open");
    break;
  case GIF_EARLY_EOF:
    Serial.println("GIF early end of file");
    break;
  case GIF_EMPTY_FRAME:
    Serial.println("GIF with empty frame");
    break;
  case GIF_BAD_FILE:
    Serial.println("GIF bad file");
    break;
  case GIF_ERROR_MEMORY:
    Serial.println("GIF memory Error");
    break;
  default:
    Serial.println("Unknown Error");
    break;
  }
}
GarnetUngar commented 4 days ago

OK, the previous code went through but the image is very distorted. Same with this latest version--in looks like it did before i made any changes at all to the first version,

thelastoutpostworkshop commented 4 days ago

change this line: tft.begin(LCD_ST7789, FLAGS_INVERT, 40000000, TFT_CS, TFT_DC, TFT_RST, TFT_BL, TFT_MISO, TFT_DIN, TFT_CLK); to : tft.begin(LCD_ST7789, FLAGS_NONE, 40000000, TFT_CS, TFT_DC, TFT_RST, TFT_BL, TFT_MISO, TFT_DIN, TFT_CLK);

and change this line : tft.setRotation(LCD_ORIENTATION_270); to: LCD_ORIENTATION_0

GarnetUngar commented 4 days ago

Sorry for the delay. I think we are getting close. The image is clear and the correct size, but tilted 90 degrees and still only half visible center. I changed it to LCD_ORIENTATION_90; that did nothing. Here's a pic. 1000021356 Many thanks again.

thelastoutpostworkshop commented 4 days ago

ok i see you are using a 135x240 screen. So you should use this line: tft.begin(LCD_ST7789_135, FLAGS_NONE, 40000000, TFT_CS, TFT_DC, TFT_RST, TFT_BL, TFT_MISO, TFT_DIN, TFT_CLK); and try different orientations : LCD_ORIENTATION_0 LCD_ORIENTATION_90 LCD_ORIENTATION_180 LCD_ORIENTATION_270

thelastoutpostworkshop commented 4 days ago

Make sure your gif is 135x240

GarnetUngar commented 4 days ago

Stupid question, but is 240x135 ok? Should I go back to the gif editor and rotate it?

thelastoutpostworkshop commented 4 days ago

yes it's ok, you just have to play with tft.setRotation(LCD_ORIENTATION_270);

GarnetUngar commented 4 days ago

So far with orientations 0 and 90 the picture is scrambled. Trying 270...

GarnetUngar commented 4 days ago

Even at 270 the image is totally scrambled.

thelastoutpostworkshop commented 4 days ago

and you have use LCD_ST7789_135 in : tft.begin(LCD_ST7789_135, FLAGS_NONE, 40000000, TFT_CS, TFT_DC, TFT_RST, TFT_BL, TFT_MISO, TFT_DIN, TFT_CLK);

GarnetUngar commented 4 days ago

Yes:

#include <AnimatedGIF.h>

// Master Animated GIF on a 320x240 SPI LCD Screen
// Youtube Tutorial: https://youtu.be/omUWkUqFYrQ
// Tested with Espressif ESP32 Arduino Core v3.0.2, 3.0.3
// Using ESP32-S3 with 8MB of PSRAM
// See also the Tutorial on how to create ESP32 custom partitions:
//
#include "esp_flash.h"
#include "esp_partition.h"

#include <bb_spi_lcd.h>  // gif_files\hud_a.h: No such file or directory
                         // Tested on version 2.5.4, 2.6.0
#include <AnimatedGIF.h> // Install this library with the Arduino IDE Library Manager
                         // Tested on version 2.1.1

// GIF files
#include "hud_a.h"                 //GIF size in FLASH memory is 1.7MB
#include "x_wing.h"                //GIF size in FLASH memory is 0.9MB
#include "death_star.h"            //GIF size in FLASH memory is 1.7MB
#include "star_destroyer.h"        //GIF size in FLASH memory is 1MB
#include "star_destroyer_planet.h" //GIF size in FLASH memory is 2.3MB
#include "scanner.h"               //GIF size in FLASH memory is 1.1MB
#include "star_trek_hud.h" //GIF size in FLASH memory is 1.6MB
#include "Sickbay_11_26.h"
#include "jedi_battle.h" //GIF size in FLASH memory is 3.3MB (use partitions.csv for this one, if you your ESP32 board has 4MB Flash size)

BB_SPI_LCD tft; // Main object for the display driver
// Screen pins
#define TFT_BL -1
#define TFT_RST 17
#define TFT_DC 18
#define TFT_CS 8
#define TFT_CLK 3
#define TFT_DIN 9 // MOSI
#define TFT_MISO -1

// GIF to display
#define GifData Sickbay_11_26 // Change image to display (image name in gif_files\[image header file].h)

void setup()
{
  Serial.begin(115200);
  tft.begin(LCD_ST7789_135, FLAGS_NONE, 40000000, TFT_CS, TFT_DC, TFT_RST, TFT_BL, TFT_MISO, TFT_DIN, TFT_CLK);
  LCD_ORIENTATION_180;

  tft.fillScreen(TFT_BLACK);

  AnimatedGIF *gif;
  gif = openGif((uint8_t *)GifData, sizeof(GifData));
  if (gif == NULL)
  {
    Serial.println("Cannot open GIF");
    while (true)
    {
      //  no need to continue
    }
  }

  while (true)
  {
    gif->playFrame(true, NULL);
  }
}

void loop()
{
  delay(1);
}

// Open Gif and allocate memory
AnimatedGIF *openGif(uint8_t *gifdata, size_t gifsize)
{
  AnimatedGIF *gif;
  gif = (AnimatedGIF *)malloc(sizeof(AnimatedGIF));
  if (gif == NULL)
  {
    Serial.println("Not RAM Enough memory for GIF structure");
    return NULL;
  }

  gif->begin(GIF_PALETTE_RGB565_BE); // Set the cooked output type we want (compatible with SPI LCDs)

  if (gif->open(gifdata, gifsize, GIFDraw))
  {
    Serial.printf("Successfully opened GIF; Canvas size = %d x %d\n", gif->getCanvasWidth(), gif->getCanvasHeight());
    Serial.printf("GIF memory size is %ld (%2.2f MB)", gifsize, (float)gifsize / (1024 * 1024));
    gif->setDrawType(GIF_DRAW_COOKED); // We want the Animated GIF library to generate ready-made pixels
    if (gif->allocFrameBuf(GIFAlloc) != GIF_SUCCESS)
    {
      Serial.println("Not Enough RAM memory for frame buffer");
      return NULL;
    }
    return gif;
  }
  else
  {
    printGifErrorMessage(gif->getLastError());
    return NULL;
  }
}

//
// The memory management functions are needed to keep operating system
// dependencies out of the core library code
//
// memory allocation callback function
void *GIFAlloc(uint32_t u32Size)
{
  return malloc(u32Size);
} /* GIFAlloc() */
// memory free callback function
void GIFFree(void *p)
{
  free(p);
}

// Draw callback from the AnimatedGIF decoder
void GIFDraw(GIFDRAW *pDraw)
{
  if (pDraw->y == 0)
  { // set the memory window (once per frame) when the first line is rendered
    tft.setAddrWindow(pDraw->iX, pDraw->iY, pDraw->iWidth, pDraw->iHeight);
  }
  // For all other lines, just push the pixels to the display. We requested 'COOKED'big-endian RGB565 and
  tft.pushPixels((uint16_t *)pDraw->pPixels, pDraw->iWidth);
}

// Get human-readable error related to GIF
void printGifErrorMessage(int errorCode)
{
  switch (errorCode)
  {
  case GIF_DECODE_ERROR:
    Serial.println("GIF Decoding Error");
    break;
  case GIF_TOO_WIDE:
    Serial.println("GIF Too Wide");
    break;
  case GIF_INVALID_PARAMETER:
    Serial.println("Invalid Parameter for gif open");
    break;
  case GIF_UNSUPPORTED_FEATURE:
    Serial.println("Unsupported feature in GIF");
    break;
  case GIF_FILE_NOT_OPEN:
    Serial.println("GIF File not open");
    break;
  case GIF_EARLY_EOF:
    Serial.println("GIF early end of file");
    break;
  case GIF_EMPTY_FRAME:
    Serial.println("GIF with empty frame");
    break;
  case GIF_BAD_FILE:
    Serial.println("GIF bad file");
    break;
  case GIF_ERROR_MEMORY:
    Serial.println("GIF memory Error");
    break;
  default:
    Serial.println("Unknown Error");
    break;
  }
}
thelastoutpostworkshop commented 4 days ago

post a pic of of your display with the gif scrambled

GarnetUngar commented 4 days ago

https://github.com/user-attachments/assets/11bff2a1-9559-4900-96cd-dc51afe5e0c2

thelastoutpostworkshop commented 4 days ago

let's try some flags in the begin function, first try this : tft.begin(LCD_ST7789_135, FLAGS_BITBANG, 40000000, TFT_CS, TFT_DC, TFT_RST, TFT_BL, TFT_MISO, TFT_DIN, TFT_CLK); if it does not work try this : tft.begin(LCD_ST7789_135, FLAGS_MEM_RESTART, 40000000, TFT_CS, TFT_DC, TFT_RST, TFT_BL, TFT_MISO, TFT_DIN, TFT_CLK);

GarnetUngar commented 4 days ago

The first results in a blank screen. The second a scrambled image.

thelastoutpostworkshop commented 4 days ago

i have just tested here with a ST7789 display 240x240 and it works fine with FLAGS_NONE I do not have your specific display, but give me time to see if I find something

GarnetUngar commented 4 days ago

Is ST7789V (what I have) the same as ST7789?

thelastoutpostworkshop commented 4 days ago

i am not sure

GarnetUngar commented 4 days ago

I was looking to maybe buy an ST7789 but everything I found was the V version...I will look some more.

thelastoutpostworkshop commented 4 days ago

I was able to reproduce the problem on my display using LCD_ST7789_135, let me see if I find a workaround

thelastoutpostworkshop commented 4 days ago

I was able to make it work on my side, let's see if it works with your display. First is the bb_spi_lcd library in your documents folder, mine is here : C:\Users\Charles\Documents\Arduino\libraries\bb_spi_lcd\src

GarnetUngar commented 4 days ago

Yes, found it.

GarnetUngar commented 4 days ago

What do I do?

thelastoutpostworkshop commented 4 days ago

I will have to send you the .cpp file by email, i cannot attach it here

thelastoutpostworkshop commented 4 days ago

in the folder we have to change this file : bb_spi_lcd.cpp

GarnetUngar commented 4 days ago

My email is gu2@evansville.edu

thelastoutpostworkshop commented 4 days ago

bb_spi_lcd.zip

thelastoutpostworkshop commented 4 days ago

ok i add to zip it, unzip it and replace the bb_spi_lcd.cpp in the folder with the one in the zip file. then use this line in the code: tft.begin(LCD_ST7789_135, FLAGS_NONE, 40000000, TFT_CS, TFT_DC, TFT_RST, TFT_BL, TFT_MISO, TFT_DIN, TFT_CLK); recompile and upload

GarnetUngar commented 4 days ago

OK, now the image is back to clear, but 90 degrees rotated and not centered. There is also a little bit of extra "junk" below the image.

thelastoutpostworkshop commented 4 days ago

play with the tft.setRotation(LCD_ORIENTATION_0); LCD_ORIENTATION_0 LCD_ORIENTATION_90 LCD_ORIENTATION_180 LCD_ORIENTATION_270

GarnetUngar commented 4 days ago

[20241129_162138.jpg

GarnetUngar commented 4 days ago

Just to be clear, we are back to using

tft.setRotation(LCD_ORIENTATION_270);

and not

LCD_ORIENTATION_270?

thelastoutpostworkshop commented 4 days ago

Try different orientation

Le ven. 29 nov. 2024 à 17:34, GarnetUngar @.***> a écrit :

Just to be clear, we are back to using

tft.setRotation(LCD_ORIENTATION_270);

and not

LCD_ORIENTATION_270?

— Reply to this email directly, view it on GitHub https://github.com/thelastoutpostworkshop/AnimatedGIF340_240/issues/1#issuecomment-2508712286, or unsubscribe https://github.com/notifications/unsubscribe-auth/A6NRM6MFG6Q3PQHJVBBHGVT2DDTYDAVCNFSM6AAAAABSWB3NJ2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKMBYG4YTEMRYGY . You are receiving this because you were assigned.Message ID: @.***>