ESP8266 SPIFF image code

ESP8266 SPIFF image code segue il precedente articolo dedicato all’argomento nel quale hai letto come caricare un file, immagine jpg, nell’area spiff del micro controllore.

ESP8266 immagine web SPIFF web page result

Se non sei riuscito a leggere l’articolo passo-passo all’upload delle immagini nella memoria flash dell’esp8266 puoi leggerlo qui.

In questo articolo leggerai come ho scritto il codice ed in particolare come usare l’immagine caricata nella SPIFF per servirla con un web server esp8266 ed una rete AP generata dalla wemos.

Lo sketch ESP8266 SPIFF image code

già nel precedente articolo era presente lo sketch da utilizzare per i test; in quella occasione non hai letto la descrizione dello sketch, in stile blog mauroalfieri.it, come consueto.

In questo articolo potrai approfondire questo aspetto.

Ecco lo sketch che analizzerai linea per linea:

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <FS.h> 


const char *wifi_ssid = "TestImage";
const char *wifi_password = "test1234";

ESP8266WebServer server(80);

IPAddress apIP(192, 168, 4, 1);       // NEW
IPAddress netMsk(255, 255, 255, 0);   // NEW

WiFiClient espClient;


void startWebServer() {
  server.on("/", handleRoot);
  server.on("/tech.jpg", []() { getSpiffImg("/tech.jpg", "image/jpg"); } );
  server.onNotFound(handleNotFound);
  server.begin();
  Serial.println("#################### Server BEGIN!! ####################");
}

void handleRoot() { 

  server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
  server.sendHeader("Pragma", "no-cache");
  server.sendHeader("Expires", "-1");

  String rootWebPage = "<!DOCTYPE html><html><head><title>:: TEST :: </title>";
  rootWebPage += "</head><body\"><h1>Test Load Image from SPIFF</h1>";
  rootWebPage += "<img src=\"/tech.jpg\" alt=\"\" width=400 /><br/>";
  rootWebPage += "<a href=\"https://www.mauroalfieri.it\" target=_blank>mauroalfieri.it</a></br>CC licence";
  rootWebPage += "</body></html>";
  
  server.send(200, "text/html", rootWebPage);
}

void handleNotFound() {
  
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET) ? "GET" : "POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";

  for (uint8_t i = 0; i < server.args(); i++) {
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }

  server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
  server.sendHeader("Pragma", "no-cache");
  server.sendHeader("Expires", "-1");
  server.send(404, "text/plain", message);
}

void getSpiffImg(String path, String TyPe) { 
 if(SPIFFS.exists(path)){ 
    File file = SPIFFS.open(path, "r");
    server.streamFile(file, TyPe);
    file.close();
  }
}

void setup() {
  Serial.begin(115200);
  while (!Serial) { delay(1); }

  WiFi.mode(WIFI_AP);           //Only Access point
  WiFi.softAPConfig(apIP, apIP, netMsk);  // NEW
  WiFi.softAP(wifi_ssid, wifi_password);  //Start HOTspot removing password will disable security

  SPIFFS.begin();
  Serial.println("----- Web Server Start ------");
  startWebServer();
}

void loop() {
  server.handleClient(); 

}

iniziamo dalle prime linee ed in particolare:

linea 01: includi la libreria ESP8266WiFi che ti serve per attivare la parte WiFI della WeMos e di ogni altro controllore basato su questo integrato;

linee 02-03: includi le librerie per gestire la connessione dei client e per generarer un web server a cui affiderai il compito di “servire” la pagina web e l’immagine recuperata dalla spiff;

linea 04: includi la libreria di gestione della memoria SPIFF, la FS ( FileSystem ) il cui compito è trattare l’accesso alla spiff dell’esp8266 come ad un filesystem;

linee 07-08: imposta un SSID ed una password per la rete wifi che creerai con la WeMos;

linea 10: in inizializza un’istanza server in ascolto sulla porta 80 ( default http );

linee 12-13: definisci due istanze della classe IPAddress rispettivamente relative all’IP da assegnare alla wemos, e quindi al tuo web server, e la corrispondente netmask;

linea 15: definisci una istanza espClient della WiFiClient.

Start del web server

Passiamo alla funzione che genera il webserver:

void startWebServer() {
  server.on("/", handleRoot);
  server.on("/tech.jpg", []() { getSpiffImg("/tech.jpg", "image/jpg"); } );
  server.onNotFound(handleNotFound);
  server.begin();
  Serial.println("#################### Server BEGIN!! ####################");
}

alla linea 18: definisci la funzione startWebServer();

linee 19-20: usnado il metodo “on” dell’istanza server imposti i due contesti di risposta, il primo relativo alla chiamata alla root ( / ) ed il secondo quando il client, browser, richiederà l’immagine “/tech.jpg”. Nota che alla linea 19 richiami la funzione handleRoot ed alla richiesta di servire l’immagine tech.jpg invocherai la funzione getSpiffImg passandole sia il nome dell’immagine che desideri sia la tipologia di immagine secondo lo standard data del w3c ( leggi articolo precedente );

linea 21: indica quale funzione richiamare quando il browser ti richiederà una pagina o un contesto che non riconosci, in tal caso richiami la funzione handleNotFound;

linea 22: inizializzi il server con il metodo begin().

Funzione handleRoot

La funzione  handleRoot sarà richiamata ogni volta che il browser cercherà di raggiungere la “/” root del web server:

void handleRoot() { 

  server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
  server.sendHeader("Pragma", "no-cache");
  server.sendHeader("Expires", "-1");

  String rootWebPage = "<!DOCTYPE html><html><head><title>:: TEST :: </title>";
  rootWebPage += "</head><body\"><h1>Test Load Image from SPIFF</h1>";
  rootWebPage += "<img src=\"/tech.jpg\" alt=\"\" width=400 /><br/>";
  rootWebPage += "<a href=\"https://www.mauroalfieri.it\" target=_blank>mauroalfieri.it<a></br>CC licence";
  rootWebPage += "</body></html>";
  
  server.send(200, "text/html", rootWebPage);
}

linee 28-30: imposti come risposta al client gli header relativi alla cache lato browser in modo che non venga salvata la copia di cache dal browser;

linea 32: definisci la rootWebPage di tipo string in cui memorizzerai il testo html relativo alla pagina web da restituire al browser;

linee 33-36: appendi alla stringa di testo rootWebPage le altre linee relative al resto della pagina. Poni particolare attenzione alla linea 34 nella quale richiedi l’immagine salvata in SPIFF al web server.

In primo luogo ricordati di sostituire il nome dell’immagine con il medesimo che hai dato al tuo file salvato e che hai inserito alla linea 20;

in secondo luogo avrai capito che il browser al momento in cui incontra il tag “<img>” con l’attributo “scr=” provvede ad eseguire una nuova richiesta al server chiedendogli la risorsa definita con il path indicato “/tech.jpg” ed entra in funzione la linea 20 vista sopra;

linea 38: serve la pagina, al client che l’ha richiesta, in formato “txt/html”.

Funzione handleNotFound

la funzione handleNotFound è richiamata in automatico dalla classe server quando gli arriva da un browser una richiesta che non può essere servita in quanto appartenente ad una path inesistente.

Nello sketch tale evento è definito come segue:

void handleNotFound() {
   
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET) ? "GET" : "POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
 
  for (uint8_t i = 0; i < server.args(); i++) {
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }
 
  server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
  server.sendHeader("Pragma", "no-cache");
  server.sendHeader("Expires", "-1");
  server.send(404, "text/plain", message);
}

linee 43-50: servono a definire il message che restituirai al browser, il tipo di messaggio puoi comporlo come preferisci, io ho usato una formula standard adottata da numerosi esempi che trovi sul web;

linea 52: componi un ciclo for sul numero di argomenti che il browser ha passato al server;

linea 53: per ciascun argomento trovato continua la composizione della stringa message aggiungendo l’argomento nella formula:

argName:valore
e facendolo seguire da un carattere di newline ( \n ) che il browser interpreta come ritorno a capo o nuova linea;

linee 56-58: imposta i consueti parametri di cache giò incontrati nella funzione handleRoot;

linea 59: invia al browser la risposta 404 ( page not fpound ), risorsa non trovata, ed il message appena composto.

Funzione getSpiffImg

Sei giunto alla funzione core di questo articolo, quella con cui recuperi l’immagine:

ESP8266 immagine web SPIFF

dalla memoria spiff dell’esp8266:

void getSpiffImg(String path, String TyPe) {
 if(SPIFFS.exists(path)){
    File file = SPIFFS.open(path, "r");
    server.streamFile(file, TyPe);
    file.close();
  }
}

la linea 62 definisce la funzione ed i due parametri attesi:

  • il path in cui cercare l’immagine, ricorda che nella SPIFF non esistono sottocartelle ma tutti il file lo hai posizionato sotto / ( root );
  • il TyPe in formato stringa relativo alla tipologia di file che restituirai, in questo caso “image/jpg”;

linea 63: verifica che nalle spiff il file richiesto esista;

linee 64-66: apre il file in modalità read ( r ), invia al server i dati come streaming di dati e chiude il file. In questo modo avrai evitato di caricare l’immagine anche come semplice file stringa, visto per altri esempi e utile solo in caso di piccoli file da restituire;

Le funzioni setup() e loop() sono identiche a tante altre descritte negli articoli passati e non necessitano di particolari spiegazioni o descrizioni.

Ti basta porre attenzione sulla sola linea 80: in cui richiami la funzione startWebServer che hai già analizzato sopra.

  • Questo sito ed i suoi contenuti è fornito "così com'è" e Mauro Alfieri non rilascia alcuna dichiarazione o garanzia di alcun tipo, esplicita o implicita, riguardo alla completezza, accuratezza, affidabilità, idoneità o disponibilità del sito o delle informazioni, prodotti, servizi o grafiche correlate contenute sul sito per qualsiasi scopo.
  • Ti chiedo di leggere e rispettare il regolamento del sito prima di utilizzarlo
  • Ti chiedo di leggere i Termini e Condizioni d'uso del sito prima di utilizzarlo
  • In qualità di Affiliato Amazon io ricevo un guadagno dagli acquisti idonei qualora siano presenti link al suddetto sito.

Permalink link a questo articolo: https://www.mauroalfieri.it/elettronica/esp8266-spiff-image-code.html

2 commenti

    • Roberto il 21 Febbraio 2021 alle 23:45
    • Rispondi

    Ti devo un grande GRAZIE per avermi illuminato sia sulla gestione del webserver che sull’utilizzo dello SPIFFS e poi di devo fare i miei COMPLIMENTI per l’ottima, semplice ma completa e chiarissima spiegazione.
    Ho subito inserito il tuo sito tra i miei preferiti e passerò spesso a dargli una occhiata.

    1. Ottimo Roberto, sono sempre contento di dare un aiuto ad altri appassionati condividendo idee e scoperte.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.