Christmas tree 2019 sketch è la parte del progetto natalizio dedicata al programma che puoi caricare sull’esp8266.
Se hai letto i precedenti articoli dedicati a questo progetto sai già dove trovare il codice per realizzare una interfaccia grafica web e come verrà il progetto:
oggi procedi oltre nel progetto con il codice christmas tree 2019 sketch che potrai caricare nel tuo ESP8266 a cui collegarti con lo smartphone per visualizzare l’interfaccia web:
Prima di procedere con la descrizione del codice, ci sono alcuni passaggi preliminari da eseguire.
Ricorda che il progetto, completo di sketch e web interface modificabile, è condiviso sul mio gitHub ed in particolare nella cartella esp8266 trovi le parti relative allo sketch.
Passaggi preliminari del progetto
usando i tool per sfruttare la SPIFF della esp8266, leggi nel link come usarla e come caricare i tools.
Ora che sai come funziona la SPIFF e come caricarla ricorda di eseguire questi semplici passaggi:
- crea uno sketch vuoto in cui inserirai il codice che leggi nel paragrafo successivo;
- salva lo sketch tra i tuoi progetti personali;
- accedi al path in cui hai salvato lo sketch ( solitamente sotto Documenti\Arduino\…. );
- crea una cartella chiamata data in questa posizione;
- copia i file common.css e colorpicker.js nella dir data;
otterrai una situazione simile alla seguente:
in cui lo sketch lo puoi chiamare come desideri, l’importante è che la cartella data sia presente sotto il medesimo path del Christmas tree 2019 sketch.
Ricordati quindi di eseguire il passaggio di upload dei file tramite l’esptool:
Christmas tree 2019 sketch
Ecco finalmente il christmas tree 2019 sketch, ossia il programma che puoi caricare sulla tua esp8266 per visualizzare l’interfaccia web di controllo:
#include <FastLED.h>
FASTLED_USING_NAMESPACE
#include "ESP8266WiFi.h"
#include <ESP8266WebServer.h>
#include <DNSServer.h>
#include <WiFiClient.h>
#include <ESP8266mDNS.h> // NEW
#include <FS.h>
/****************************************************************************************/
const byte DNS_PORT = 53; // NEW
DNSServer dnsServer; // NEW
ESP8266WebServer server(80);
IPAddress apIP(192, 168, 4, 1); // NEW
IPAddress netMsk(255, 255, 255, 0); // NEW
WiFiClient espClient;
/****************************************************************************************/
const char* wifi_ssid = "christmas";
const char* wifi_password = "2019";
unsigned char red,green,blue;
/****************************************************************************************/
#if defined(FASTLED_VERSION) && (FASTLED_VERSION < 3001000)
#warning "Requires FastLED 3.1 or later; check github for latest code."
#endif
#define DATA_PIN 2
//#define CLK_PIN 4
#define LED_TYPE WS2811
#define COLOR_ORDER GRB
#define NUM_LEDS 40
CRGB leds[NUM_LEDS];
#define BRIGHTNESS 96
/****************************************************************************************/
void handle_root() {
Serial.println("Handle Root");
server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
server.sendHeader("Pragma", "no-cache");
server.sendHeader("Expires", "-1");
String html = "<!DOCTYPE html> <html lang=\"en\"> <head> <title>Color Picker</title> <meta charset=\"UTF-8\"/> <link href=\"common.css\" rel=\"stylesheet\" /> <script src=\"colorpicker.js\"></script> <style>.inputs-list {margin-top: 34px\; \n }</style> </head>\n";
html += "<body> <div class=\"example-wrap\"> <div class=\"inputs-list\"> ";
html += "<input type=\"hidden\" id=\"blackCode\" value=\"#000000\" /> ";
html += "<input type=\"hidden\" id=\"oldHexCode\" value=\"\" /> ";
html += "<input type=\"button\" onclick=\"sendData(getElementById('blackCode'))\" onchange=\"\" class=\"io-input\" style=\"background-color:#000\; border: 2px solid #fff\; color: #fff\; \" value=\"0\" /> ";
html += "<input type=\"button\" onclick=\"sendData(getElementById('oldHexCode'))\" onchange=\"\" class=\"io-input\" style=\"background-color:#fff\; border: 2px solid #fff\; color: #000\; \" value=\"1\" /> ";
html += "</div> <canvas id=\"canvas\"></canvas> <div class=\"inputs-list\"> ";
html += "<input type=\"button\" onclick=\"sendData(event.target)\" onchange=\"picker.editInput(event.target)\" class=\"multi-input input-quad\" value=\"#8825eb\" />";
html += "<input type=\"button\" onclick=\"sendData(event.target)\" onchange=\"picker.editInput(event.target)\" class=\"multi-input input-quad\" value=\"#2439eb\" />";
html += "<input type=\"button\" onclick=\"sendData(event.target)\" onchange=\"picker.editInput(event.target)\" class=\"multi-input input-quad\" value=\"#24e9eb\" />";
html += "<input type=\"button\" onclick=\"sendData(event.target)\" onchange=\"picker.editInput(event.target)\" class=\"multi-input input-quad\" value=\"#eb9524\" />";
html += "<input type=\"button\" onclick=\"sendData(event.target)\" onchange=\"picker.editInput(event.target)\" class=\"multi-input input-quad\" value=\"#eb2497\" />";
html += "</div> <div class=\"inputs-list\">";
html += "<input type=\"button\" onclick=\"sendData(event.target)\" onchange=\"picker.editInput(event.target)\" class=\"multi-input input-quad\" value=\"#ffffff\" />";
html += "<input type=\"button\" onclick=\"sendData(event.target)\" onchange=\"picker.editInput(event.target)\" class=\"multi-input input-quad\" value=\"#ffe83f\" />";
html += "<input type=\"button\" onclick=\"sendData(event.target)\" onchange=\"picker.editInput(event.target)\" class=\"multi-input input-quad\" value=\"#ff0000\" />";
html += "<input type=\"button\" onclick=\"sendData(event.target)\" onchange=\"picker.editInput(event.target)\" class=\"multi-input input-quad\" value=\"#00ff00\" />";
html += "<input type=\"button\" onclick=\"sendData(event.target)\" onchange=\"picker.editInput(event.target)\" class=\"multi-input input-quad\" value=\"#0000ff\" />";
html += "</div> </div> \n";
html += "<script> var picker = new KellyColorPicker({ place : 'canvas', size : 700, userEvents : { change : function(self) { if (!self.selectedInput) return\; \n if (self.getCurColorHsv().v < 0.5) { self.selectedInput.style.color = \"#FFFFFF\"\; \n } else { self.selectedInput.style.color = \"#000000\"\; \n } self.selectedInput.value = self.getCurColorHex()\; \n self.selectedInput.style.background = self.selectedInput.value\; \n } } })\; \n picker.editInput = function(target) { if (picker.selectedInput) picker.selectedInput.classList.remove('selected')\; \n if (target) picker.selectedInput = target\; \n if (!picker.selectedInput) return false\; \n picker.selectedInput.classList.add('selected')\; \n picker.setColor(picker.selectedInput.value)\; \n picker.selectedInput.style.color=picker.selectedInput.value\; \n } \n";
html += "var mInputs = document.getElementsByClassName('multi-input')\; \n for (var i = 0\; \n i < mInputs.length\; \n i++) { picker.editInput(mInputs[i])\; \n } \n";
html += "picker.getWheel().width += 60\; \n picker.getSvFigCursor().radius += 15\; \n picker.getWheelCursor().height += 15\; \n var alpha = picker.getAlphaFig()\; \n picker.updateView(true)\; \n \n";
html += "</script> </body> </html>";
server.send(200, "text/html", html);
delay(100);
}
void handle_outputs() {
Serial.print("Handle output");
// Strings to strore the client output
String RMsg;
String GMsg;
String BMsg;
// Parse client output
RMsg=server.arg("r");
GMsg=server.arg("g");
BMsg=server.arg("b");
Serial.print(" RMsg: "); Serial.print(RMsg);
Serial.print(" GMsg: "); Serial.print(GMsg);
Serial.print(" BMsg: "); Serial.print(BMsg);
Serial.print("\n");
// Convert to number to pass to Neopixel library
red=RMsg.toInt();
green=GMsg.toInt();
blue=BMsg.toInt();
String result = "<!DOCTYPE html> <html lang=\"en\"> <head> <title>Color Picker</title> </head> <body>message</body> </html>";
server.send(200, "text/html", result);
}
void getSpiffFile(String path, String TyPe) {
if(SPIFFS.exists(path)){
File file = SPIFFS.open(path, "r");
server.streamFile(file, TyPe);
file.close();
}
}
// Initialize WiFi, web server and handles
void setup() {
Serial.begin(115200);
Serial.println("Setup start execution");
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
dnsServer.setErrorReplyCode(DNSReplyCode::NoError); // NEW
dnsServer.start(DNS_PORT, "*", apIP); // NEW
red=127;
green=127;
blue=127;
FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(BRIGHTNESS);
server.on("/", handle_root);
server.on("/common.css", []() { getSpiffFile("/common.css", "text/css"); } );
server.on("/colorpicker.js", []() { getSpiffFile("/colorpicker.js", "application/javascript"); } );
server.on("/setcolor.html", handle_outputs);
//server.onNotFound( handle_root );
server.begin();
SPIFFS.begin();
setColorPixel();
Serial.println("Setup successfully executed");
}
void loop() {
server.handleClient();
dnsServer.processNextRequest();
setColorPixel();
FastLED.show();
}
void setColorPixel() {
Serial.print(" R: "); Serial.print(red);
Serial.print(" G: "); Serial.print(green);
Serial.print(" B: "); Serial.print(blue);
Serial.print("\n");
for(int i=0;i<NUM_LEDS;i++){
leds[i] = CRGB( red, green, blue);
FastLED.show();
FastLED.delay(1000/30);
}
}
il listato è molto lungo e ci concentreremo solo sulle parti fondamentali che ti consentono il cerretto funzionamento e l’eventuale modifica dello sketch.
Le parti non descritte sono già state analizzate in tanti altri articoli e non costituiscono parte fondamentale dello sketch.
Inizia dalla linea 001: includi la libreria FastLED.h che userai per gestire i led WS2812B ( vedi articoli dedicati a tale libreria in questo blog );
linee 005-009: includi le librerie necessarie alla connessione WiFi e la gestione del web server ( vedi articoli dedicati al wifi per esp8266 e relativo web server );
linea 010: includi la libreria FS.h che ti permette la gestione del FileSystem ( FS appunto ) SPIFF come descritto negli articoli citati al paragrafo precedente;
linee 013-021: definisci le istanzse per la prte WiFi e la generazione del WebServer;
linee 025-026: definisci SSID e Pass da passare alla libreria WiFi per collegarsi alla tua rete wifi, io hoscelto di usare la modalità AP ( Access Point ) facendogli generare un SSID alla ESP8266 a cui collegarti;
linea 027: definisci le tre variabili per i tre colori primari che userai per accendere i led;
linee 029-039: definisci alcune costanti necessarie al corretto funzionamento della FastLED;
linea 040: crea l’istanza leds che userai per comunicare con i led WS2812B;
linea 042: definisci una costante per la luminosità dei led fissa a 96;
linee 046-079: definisci la funzione handle_root() che sarà richiamata quando ti collegherai alla root “/” del web server e che compone ed espone la pagina visualizzata che hai già visto nel dettagli descritta nel precedente articolo;
linea 081: definisci la funzione handle_output() che ti permette la vera e propria interazione con i led, viene richiamata dal web server quando richiami la pagina setcolor.html e riceve in get i parametri che gli passi;
linee 090-092: usando il metodo arg della classe server recuperi i parametri in GET che desideri utilizzare;
linee 100-102: converti in intero il valore di ciascuno dei parametri ricevuti dalla climata get HTTP;
linea 104: definisci la stringa di risposta che invierai alla chiamata Ajax fatta dalla pagine Web;
linea 105: invia il risultato in risposta all’interfaccia web;
linee 108-114: imposta la funzione getSpiffFile() che richiamerai tutte le volte che ti serve recuperare un file dalla SPIFF precedentemente salvato ( vedi paragrafo “passaggi preliminari del progetto” ). Devi passarle il path ( percorso ) in cui trova il file, comprensivo di nome del file e la tipologia di file;
linee 117-133: definisci tutte le inizializzazioni relative al WiFi, FastLed e valori di default per le tre componenti colore come decsritto in tanti altri articoli dedicati alle singole definizioni;
linea 135: imposta la risposta quando il server riceve la chiamata per la pagina root “/”, come leggi, richiami la funzione handle_root vista prima;
linee 136-137: definisci due linee simili in cui definsci la funzione da chiamare quando ricevi la richiesta di servire una pagina presente nella SPIFF ( ad esempio: /common.css). Ricordi che le due pagine common.css e colopicker.js le hai salvate nella SPIFF, quindi è da quel path che dovrai andare a richiamarla. Tale funzione è la getSpiffFile();
linea 138: definisci che funzione chiamare quando ti arriva la richiesta per la pagina /setcolor.html, nota che si tratta della handle_outputs() vista sopra;
linee 141-144: usa i metodi begin per il webserver e la spiff e avvia la funzione setColorPixel() per inizializzare i led del colore di default impostato alle linee 128-130;
linee 149-154: nella funzione loop() avvia tutti i processi che devono essere eseguiti ciclicamente relativamente al server, dnsServer e FastLED;
linea 156: definisci la funzione setColorPixel() con cui imposti il colore dei led;
linee 163-167: con un ciclo for imposta il colore di ciascun led partendo dal primo all’ultimo;
Il video
Di seguito il video del christmas tree 2019 sketch
in cui puoi vedere come funziona lo sketch;
Buon anno.





Il blog mauroalfieri.it ed i suoi contenuti sono distribuiti con Licenza