GIF

Sfruttiamo il display integrato nella LILYGO TTGO T-Display per riprodurre GIF Animate

La LILYGO® TTGO T-Display ESP32 è una dev-board con integrato un display con chip ST7789V, molto pratico e semplice da gestire, andando però a modificare la libreria come abbiamo visto in precedenza [LINK]. Sfrutteremo le specifiche tecniche della scheda, dotata di un dual core a 240Mhz, per riprodurre sul display una GIF animata a tema Dragon Ball. Potete acquistare questa dev-board a questo LINK.

Preparazione della GIF

Per chi non le conoscesse, le GIF (sigla di Graphics Interchange Format) sono immagini digitali molto in voga negli anni ’90, soprattutto adoperate per abbellire i siti web. Di recente il loro utilizzo si è rafforzato, grazie anche alle App di messaggistica istantanea. Le GIF sono immagini in sequenza riprodotte in loop, quindi sono costituite da un numero predefinito di frame che, per necessità, dovremo scindere in tanti piccoli file. Per questa operazione non ci servirà un programma ad hoc, ma possiamo adoperare Google per trovare diversi siti web che fanno questa operazione gratuitamente; andiamo sul sito https://ezgif.com/split e clicchiamo su Scegli file per selezionare una GIF presente sul nostro PC, poi andiamo su Upload!.

GIF

Ora che abbiamo caricato la nostra GIF, muoviamoci su resize e impostiamo Width a 240 e Heigh a 135, in modo da adattare la GIF alle dimensioni del nostro display. Clicchiamo sul pulsante Resize image! e proseguiamo cliccando su split.

GIF

Prima di splittare l’immagine, selezioniamo la voce Output images in JPG format, dalla menu a tenda Split option. Dividiamo la nostra GIF cliccando su Split to frames! e poi scarichiamo il file zippato risultante e contente i singoli frame con il pulsante Download frames as ZIP.

GIF

Una volta scaricato il file zippato, scompattiamolo e selezioniamo solo i frame che ci interessano; nel nostro caso i primi 27. Rinominate i file in modo che tutti inizino con frame_ e proseguano con un numero in successione tra 0 e 26.

GIF



Implementare IDE Arduino

Andiamo ora a scaricare un plug-in che ci aiuterà a memorizzare i file appena creati sulla Flash memory della ESP32: si tratta dell’ESP32 Sketch Data Upload, da scarica al seguente LINK. Una volta scaricato, dobbiamo scompattarlo e copiarlo all’interno della IDE di Arduino e per farlo dobbiamo andare seguendo questo percorso: C:\Programmi(x86)\Arduino\tools

GIF

Avviamo la IDE a nella barra dei menu apriamo Strumenti e dovremmo vedere la voce ESP32 Sketch Data Upload. Non clicchiamola al momento.

GIF

Codice

Veniamo adesso alla parte più complessa: prima di iniziare andiamo su Sketch, dalla barra dei menu, poi #include libreria e apriamo il Gestore librerie e cerchiamo la libreria TJpg_Decoder per installarla.

GIF

Premettiamo che buona parte del codice adoperato è preso da uno degli esempi contenuti nella libreria appena installata e che il nostro solo lavoro si concentrerà su quanto vedremo nel Void Loop. Potete scaricare lo sketch da questo LINK. Iniziamo come sempre con le librerie che ci servono, ossia la libreria TFT_eSPI.h per il display, a cui seguiamo creando l’oggetto per gestirlo, la libreria SPIFFS.h (SPI Flash File System) con cui occuperemo parte della memoria Flash per memorizzare le immagini, infine la libreria TJpg_Decoder.h per decodificare i file Jpeg. Creiamo anche una variabile intera, denominata Img, che ci servirà come contatore per i file jpg.


#include "SPI.h"
#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();

#include "SPIFFS.h" // Libreria per caricare i files

#include <TJpg_Decoder.h> // decodifica dei file jpg

int Img;

Nel VOID SETUP avviamo il monitor seriale e inizializziamo la SPIFFS. Un messaggio su monitor seriale ci avviserà se la SPIFFS è inizializzata oppure no. Richiamiamo una funzione chiamata listSPIFFS(), che analizzeremo a breve, poi avviamo il display, ruotandolo e impostando uno sfondo nero.


Serial.begin(115200);
Serial.println("\n\n Testing TJpg_Decoder library");

// Inizializza SPIFFS
if (!SPIFFS.begin()) {
Serial.println("SPIFFS inizializzazione finita!");
while (1) yield(); // Attendi
}
Serial.println("\r\nInizializzazione conclusa.");

listSPIFFS();

tft.begin();
tft.setRotation(1);
tft.fillScreen(TFT_BLACK);

Concludiamo il VOID SETUP definendo alcuni settaggi per la decodifica dei file jpeg, come il ridimensionamento e la funziona di rendering.


TJpgDec.setJpgScale(1);

TJpgDec.setSwapBytes(true);

TJpgDec.setCallback(tft_output);

Andiamo a vedere velocemente la funzione listSPIFFS(). Andiamo a creare una lista dei file da leggere e decodificare, dichiarando il percorso da cui leggerli.


void listSPIFFS(void) {
Serial.println(F("\r\nLista SPIFFS files:"));
static const char line[] PROGMEM = "=================================================";

Serial.println(FPSTR(line));
Serial.println(F(" File name Size"));
Serial.println(FPSTR(line));

fs::File root = SPIFFS.open("/");
if (!root) {
Serial.println(F("Impossibile aprire la directory"));
return;
}
if (!root.isDirectory()) {
Serial.println(F("Non è una directory"));
return;
}

fs::File file = root.openNextFile();
while (file) {

if (file.isDirectory()) {
Serial.print("DIR : ");
String fileName = file.name();
Serial.print(fileName);
} else {
String fileName = file.name();
Serial.print(" " + fileName);
// Il file path può essere di 31 ccaratteri al massimo in SPIFFS
int spaces = 33 - fileName.length(); // tabulare bene
if (spaces < 1) spaces = 1;
while (spaces--) Serial.print(" ");
String fileSize = (String) file.size();
spaces = 10 - fileSize.length(); // tabulare bene
if (spaces < 1) spaces = 1;
while (spaces--) Serial.print(" ");
Serial.println(fileSize + " bytes");
}

file = root.openNextFile();
}

Serial.println(FPSTR(line));
Serial.println();
delay(1000);

Concludiamo l’analisi del codice nel VOID LOOP. Ogni volta che la variabile raggiunge il valore di 27 viene riportata a 0, mentre per ogni valore compreso tra 0 e 27 viene creata una stringa che contiene l’iniziale comune di ogni file (frame_) il numero che incrementiamo e l’estensione del file .jpg. Stampiamo poi sul display ogni file.


if (Img > 27){ // la variabile raggiunto il massimo si azzera
Img = 0;
}

String imgPath = "/frame_"; //I file iniziano con questa dicitura...
imgPath += Img++; // incremento il numero...
imgPath += ".jpg"; // pongo l'estensione al file

TJpgDec.drawFsJpg(0, 0, imgPath); // stampo sul display i file così letti



Caricare i file sulla Memory Flash

Adesso che il codice è pronto, prima di caricarlo, dobbiamo memorizzare i file sulla memoria flash della ESP32. L’operazione richiede come prerequisito che i file siano nella stessa cartella che contiene lo sketch; creiamo una cartella di nome data e spostiamo i file dei frame al suo interno. Apriamo lo sketch che abbiamo appena finito di scrivere, andiamo sulla barra dei menu e selezioniamo Strumenti, poi clicchiamo su ESP32 Sketch Data Upload.

GIF

Attendiamo che finisca, la ESP32 si riavvierà e poi carichiamo lo sketch. Se tutto andrà a buon fine vedremo sul display la nostra GIF animata.