Skip to content

Instantly share code, notes, and snippets.

@apla
Created January 25, 2025 23:04
Show Gist options
  • Save apla/f61987ffe277573f4b6a483db03ac211 to your computer and use it in GitHub Desktop.
Save apla/f61987ffe277573f4b6a483db03ac211 to your computer and use it in GitHub Desktop.
animated-320x170
// adafruit_gfx_memory
//
// Example sketch which shows how to display an
// animated GIF image stored in FLASH memory
// using the Adafruit_GFX_TFT library
//
// written by Larry Bank
// [email protected]
//
// To display a GIF from memory, a single callback function
// must be provided - GIFDRAW
// This function is called after each scan line is decoded
// and is passed the 8-bit pixels, RGB565 palette and info
// about how and where to display the line. The palette entries
// can be in little-endian or big-endian order; this is specified
// in the begin() method.
//
// The AnimatedGIF class doesn't allocate or free any memory, but the
// instance data occupies about 22.5K of RAM.
//
#include <AnimatedGIF.h>
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SPI.h>
#include <LittleFS.h>
#include <HX711.h>
HX711 loadcell;
#include "badgers.h"
#if defined(ARDUINO_ARCH_RP2040)
#define TFT_CS 17
#define TFT_RST 20
#define TFT_DC 21
#define LOADCELL_DATA 28
#define LOADCELL_SCK 27
#else
#define TFT_CS 10
#define TFT_RST 8
#define TFT_DC 9
#define TFT_MOSI 11
#define TFT_CLK 13
#define TFT_MISO 12
#endif
#define DISPLAY_WIDTH 320
#define DISPLAY_HEIGHT 170
#define DISPLAY_ROTATION 3
#define DISPLAY_BLACK ST77XX_BLACK
// #define DISPLAY_BLACK ILI9341_BLACK
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
// Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);
AnimatedGIF gif;
long weight = 0;
String file_name = String("");
// 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() */
// typedef void (*FileCallback)(File &file);
// Function to recursively list files in a directory
void listFiles(const char *dirname) {
Dir root = LittleFS.openDir(dirname);
while (root.next()) {
if (root.isDirectory()) {
Serial.print("DIR : ");
Serial.println(root.fileName());
// listFiles(file.name()); // Recursive call for subdirectories
} else {
Serial.print("FILE: ");
Serial.print(root.fileName());
Serial.print("\tSIZE: ");
Serial.println(root.fileSize());
// only the last file
file_name = root.fileName();
//cb(file);
}
}
}
void onFile(File &file) {
// file_name = file.name();
}
void setup() {
Serial.begin(115200);
Serial.println("XXXX");
// put your setup code here, to run once:
// tft.begin(); // tft.begin only for ILI ?
tft.init(DISPLAY_HEIGHT, DISPLAY_WIDTH);
tft.setRotation(DISPLAY_ROTATION);
tft.fillScreen(DISPLAY_BLACK);
gif.begin(LITTLE_ENDIAN_PIXELS);
Serial.println("YYYYY");
if (!LittleFS.begin()) {
Serial.println("Failed to mount LittleFS!");
return;
}
Serial.println("ZZZZZ");
listFiles("/");
}
void loop() {
// put your main code here, to run repeatedly:
if (gif.open((uint8_t *)badgers, sizeof(badgers), GIFDraw))
{
//Serial.printf("Successfully opened GIF; Canvas size = %d x %d\n", gif.getCanvasWidth(), gif.getCanvasHeight());
while (gif.playFrame(true, NULL))
{
tft.setCursor(0, 140);
tft.setTextColor(ST77XX_GREEN);
tft.setTextSize(2);
tft.println(file_name);
// tft.println("Oh no, not you again...");
}
gif.close();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment