aboutsummaryrefslogtreecommitdiff
path: root/examples/AnimatedGIFPanel_LittleFS
diff options
context:
space:
mode:
authormrcodetastic <12006953+mrcodetastic@users.noreply.github.com>2024-07-28 22:00:45 +0100
committermrcodetastic <12006953+mrcodetastic@users.noreply.github.com>2024-07-28 22:00:45 +0100
commitf2634319ab7ebfe22fc6d2ebabcdd27879f3667e (patch)
treed8834f64f0dc4349bf34cf29a6831a12063b1435 /examples/AnimatedGIFPanel_LittleFS
parentaa28e2a93baaf90083b2d556c0ac80602d9940aa (diff)
Clean-up and fix some examples
Diffstat (limited to 'examples/AnimatedGIFPanel_LittleFS')
-rw-r--r--examples/AnimatedGIFPanel_LittleFS/AnimatedGIFPanel_LittleFS.ino276
-rw-r--r--examples/AnimatedGIFPanel_LittleFS/README.md13
-rw-r--r--examples/AnimatedGIFPanel_LittleFS/data/gifs/cartoon.gifbin0 -> 29727 bytes
-rw-r--r--examples/AnimatedGIFPanel_LittleFS/data/gifs/ezgif.com-pacmn.gifbin0 -> 44831 bytes
-rw-r--r--examples/AnimatedGIFPanel_LittleFS/data/gifs/loading.io-64x32px.gifbin0 -> 39645 bytes
-rw-r--r--examples/AnimatedGIFPanel_LittleFS/data/gifs/matrix-spin.gifbin0 -> 174779 bytes
-rw-r--r--examples/AnimatedGIFPanel_LittleFS/data/gifs/parasite1.gifbin0 -> 58970 bytes
-rw-r--r--examples/AnimatedGIFPanel_LittleFS/data/gifs/parasite2.gifbin0 -> 32135 bytes
-rw-r--r--examples/AnimatedGIFPanel_LittleFS/data/gifs/shock-gs.gifbin0 -> 34454 bytes
9 files changed, 289 insertions, 0 deletions
diff --git a/examples/AnimatedGIFPanel_LittleFS/AnimatedGIFPanel_LittleFS.ino b/examples/AnimatedGIFPanel_LittleFS/AnimatedGIFPanel_LittleFS.ino
new file mode 100644
index 0000000..f8637b0
--- /dev/null
+++ b/examples/AnimatedGIFPanel_LittleFS/AnimatedGIFPanel_LittleFS.ino
@@ -0,0 +1,276 @@
+// Example sketch which shows how to display a 64x32 animated GIF image stored in FLASH memory
+// on a 64x32 LED matrix
+//
+// Credits: https://github.com/bitbank2/AnimatedGIF/tree/master/examples/ESP32_LEDMatrix_I2S
+//
+
+/* INSTRUCTIONS
+ *
+ * 1. First Run the 'ESP32 Sketch Data Upload Tool' in Arduino from the 'Tools' Menu.
+ * - If you don't know what this is or see it as an option, then read this:
+ * https://github.com/me-no-dev/arduino-esp32fs-plugin
+ * - This tool will upload the contents of the data/ directory in the sketch folder onto
+ * the ESP32 itself.
+ *
+ * 2. You can drop any animated GIF you want in there, but keep it to the resolution of the
+ * MATRIX you're displaying to. To resize a gif, use this online website: https://ezgif.com/
+ *
+ * 3. Have fun.
+ */
+
+#include "FS.h"
+#include <LittleFS.h>
+#include <AnimatedGIF.h>
+#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>
+
+#define FILESYSTEM LittleFS
+#define FORMAT_LITTLEFS_IF_FAILED true
+
+#define PANEL_RES_X 64 // Number of pixels wide of each INDIVIDUAL panel module.
+#define PANEL_RES_Y 32 // Number of pixels tall of each INDIVIDUAL panel module.
+#define PANEL_CHAIN 1 // Total number of panels chained one to another horizontally only.
+
+//MatrixPanel_I2S_DMA dma_display;
+MatrixPanel_I2S_DMA *dma_display = nullptr;
+
+uint16_t myBLACK = dma_display->color565(0, 0, 0);
+uint16_t myWHITE = dma_display->color565(255, 255, 255);
+uint16_t myRED = dma_display->color565(255, 0, 0);
+uint16_t myGREEN = dma_display->color565(0, 255, 0);
+uint16_t myBLUE = dma_display->color565(0, 0, 255);
+
+AnimatedGIF gif;
+File f;
+int x_offset, y_offset;
+
+
+
+// Draw a line of image directly on the LED Matrix
+void GIFDraw(GIFDRAW *pDraw)
+{
+ uint8_t *s;
+ uint16_t *d, *usPalette, usTemp[320];
+ int x, y, iWidth;
+
+ iWidth = pDraw->iWidth;
+ if (iWidth > dma_display->width())
+ iWidth = dma_display->width();
+
+ usPalette = pDraw->pPalette;
+ y = pDraw->iY + pDraw->y; // current line
+
+ 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 + pDraw->iWidth;
+ x = 0;
+ iCount = 0; // count non-transparent pixels
+ while(x < pDraw->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?
+ {
+ for(int xOffset = 0; xOffset < iCount; xOffset++ ){
+ dma_display->drawPixel(x + xOffset, y, usTemp[xOffset]); // 565 Color Format
+ }
+ 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 // does not have transparency
+ {
+ s = pDraw->pPixels;
+ // Translate the 8-bit pixels through the RGB565 palette (already byte reversed)
+ for (x=0; x<pDraw->iWidth; x++)
+ {
+ dma_display->drawPixel(x, y, usPalette[*s++]); // color 565
+ }
+ }
+} /* GIFDraw() */
+
+
+void * GIFOpenFile(const char *fname, int32_t *pSize)
+{
+ Serial.print("Playing gif: ");
+ Serial.println(fname);
+ f = FILESYSTEM.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() */
+
+unsigned long start_tick = 0;
+
+void ShowGIF(char *name)
+{
+ start_tick = millis();
+
+ if (gif.open(name, GIFOpenFile, GIFCloseFile, GIFReadFile, GIFSeekFile, GIFDraw))
+ {
+ x_offset = (dma_display->width() - gif.getCanvasWidth())/2;
+ if (x_offset < 0) x_offset = 0;
+ y_offset = (dma_display->height() - gif.getCanvasHeight())/2;
+ if (y_offset < 0) y_offset = 0;
+ Serial.printf("Successfully opened GIF; Canvas size = %d x %d\n", gif.getCanvasWidth(), gif.getCanvasHeight());
+ Serial.flush();
+ while (gif.playFrame(true, NULL))
+ {
+ if ( (millis() - start_tick) > 8000) { // we'll get bored after about 8 seconds of the same looping gif
+ break;
+ }
+ }
+ gif.close();
+ }
+
+} /* ShowGIF() */
+
+
+
+/************************* Arduino Sketch Setup and Loop() *******************************/
+void setup() {
+ Serial.begin(115200);
+
+ if(!LittleFS.begin(FORMAT_LITTLEFS_IF_FAILED)){
+ Serial.println("LittleFS Mount Failed");
+ return;
+ }
+
+ HUB75_I2S_CFG mxconfig(
+ PANEL_RES_X, // module width
+ PANEL_RES_Y, // module height
+ PANEL_CHAIN // Chain of panels - Horizontal width only.
+ );
+
+ // mxconfig.gpio.e = 18;
+ // mxconfig.clkphase = false;
+ // mxconfig.driver = HUB75_I2S_CFG::FM6126A;
+
+ // Display Setup
+ dma_display = new MatrixPanel_I2S_DMA(mxconfig);
+ dma_display->begin();
+ dma_display->setBrightness8(128); //0-255
+ dma_display->clearScreen();
+ dma_display->fillScreen(myWHITE);
+
+ // Start going through GIFS
+ gif.begin(LITTLE_ENDIAN_PIXELS);
+
+}
+
+String gifDir = "/gifs"; // play all GIFs in this directory on the SD card
+char filePath[256] = { 0 };
+File root, gifFile;
+
+void loop()
+{
+ while (1) // run forever
+ {
+
+ root = FILESYSTEM.open(gifDir);
+ if (root)
+ {
+ gifFile = root.openNextFile();
+ while (gifFile)
+ {
+ if (!gifFile.isDirectory()) // play it
+ {
+
+ // C-strings... urghh...
+ memset(filePath, 0x0, sizeof(filePath));
+ strcpy(filePath, gifFile.path());
+
+ // Show it.
+ ShowGIF(filePath);
+
+ }
+ gifFile.close();
+ gifFile = root.openNextFile();
+ }
+ root.close();
+ } // root
+
+ delay(1000); // pause before restarting
+
+ } // while
+}
+
+// Other LittleFS filesystem function examples available at:
+// https://randomnerdtutorials.com/esp32-write-data-littlefs-arduino/ \ No newline at end of file
diff --git a/examples/AnimatedGIFPanel_LittleFS/README.md b/examples/AnimatedGIFPanel_LittleFS/README.md
new file mode 100644
index 0000000..acab3d2
--- /dev/null
+++ b/examples/AnimatedGIFPanel_LittleFS/README.md
@@ -0,0 +1,13 @@
+## Animated GIF Decoding Example
+
+### Prerequisites
+1. The excellent 'AnimatedGIF' library by Larry Bank needs to be installed: https://github.com/bitbank2/AnimatedGIF
+
+2. The files in the 'data' folder are written to the ESP32's SPIFFS file system. In order to be able to do this using the Arduino 2.0 IDE, you need to install the ESP32 LittleFS plugin: https://github.com/lorol/arduino-esp32littlefs-plugin
+
+Follow the instructions in the link to install the plugin: https://randomnerdtutorials.com/arduino-ide-2-install-esp32-littlefs/
+
+
+## Credits
+
+https://github.com/bitbank2/AnimatedGIF
diff --git a/examples/AnimatedGIFPanel_LittleFS/data/gifs/cartoon.gif b/examples/AnimatedGIFPanel_LittleFS/data/gifs/cartoon.gif
new file mode 100644
index 0000000..32a0e25
--- /dev/null
+++ b/examples/AnimatedGIFPanel_LittleFS/data/gifs/cartoon.gif
Binary files differ
diff --git a/examples/AnimatedGIFPanel_LittleFS/data/gifs/ezgif.com-pacmn.gif b/examples/AnimatedGIFPanel_LittleFS/data/gifs/ezgif.com-pacmn.gif
new file mode 100644
index 0000000..0a219a4
--- /dev/null
+++ b/examples/AnimatedGIFPanel_LittleFS/data/gifs/ezgif.com-pacmn.gif
Binary files differ
diff --git a/examples/AnimatedGIFPanel_LittleFS/data/gifs/loading.io-64x32px.gif b/examples/AnimatedGIFPanel_LittleFS/data/gifs/loading.io-64x32px.gif
new file mode 100644
index 0000000..342f8ae
--- /dev/null
+++ b/examples/AnimatedGIFPanel_LittleFS/data/gifs/loading.io-64x32px.gif
Binary files differ
diff --git a/examples/AnimatedGIFPanel_LittleFS/data/gifs/matrix-spin.gif b/examples/AnimatedGIFPanel_LittleFS/data/gifs/matrix-spin.gif
new file mode 100644
index 0000000..7925d68
--- /dev/null
+++ b/examples/AnimatedGIFPanel_LittleFS/data/gifs/matrix-spin.gif
Binary files differ
diff --git a/examples/AnimatedGIFPanel_LittleFS/data/gifs/parasite1.gif b/examples/AnimatedGIFPanel_LittleFS/data/gifs/parasite1.gif
new file mode 100644
index 0000000..8b8b67a
--- /dev/null
+++ b/examples/AnimatedGIFPanel_LittleFS/data/gifs/parasite1.gif
Binary files differ
diff --git a/examples/AnimatedGIFPanel_LittleFS/data/gifs/parasite2.gif b/examples/AnimatedGIFPanel_LittleFS/data/gifs/parasite2.gif
new file mode 100644
index 0000000..60d03c7
--- /dev/null
+++ b/examples/AnimatedGIFPanel_LittleFS/data/gifs/parasite2.gif
Binary files differ
diff --git a/examples/AnimatedGIFPanel_LittleFS/data/gifs/shock-gs.gif b/examples/AnimatedGIFPanel_LittleFS/data/gifs/shock-gs.gif
new file mode 100644
index 0000000..1d023d9
--- /dev/null
+++ b/examples/AnimatedGIFPanel_LittleFS/data/gifs/shock-gs.gif
Binary files differ