Christmas tree 2019 sketch

Christmas tree 2019 sketch è la parte del progetto natalizio dedicata al programma che puoi caricare sull’esp8266.Christmas tree 2019 sketch

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:

  1. crea uno sketch vuoto in cui inserirai il codice che leggi nel paragrafo successivo;
  2. salva lo sketch tra i tuoi progetti personali;
  3. accedi al path in cui hai salvato lo sketch ( solitamente sotto Documenti\Arduino\…. );
  4. crea una cartella chiamata data in questa posizione;
  5.  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

 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.

Prima di inserire un commento, per favore, leggi il regolamento

Permanent link to this article: https://www.mauroalfieri.it/elettronica/christmas-tree-2019-sketch.html

Lascia un commento

Your email address will not be published.

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