
In questo progetto di controllo dimmer con server web, impareremo a creare con ESP8266 ed ESP32 un server web con slider che controllerà il livello di tensione di dimmerizzazione del dimmer collegato al pin GPIO dell'ESP8266 / ESP32.
Questo sarà realizzato tramite uno slider HTML che aggiungeremo alla pagina del server web. Lo slider verrà spostato per impostare il suo valore. In risposta, questo valore dello slider imposterà il valore del dimmer.
Inoltre, utilizziamo la libreria WiFiManager che consente di collegare il progetto dimmer basato su ESP8266/ESP32 a diversi punti di accesso (AP) senza dover codificare e caricare nuovo codice sulla scheda. In aggiunta, con la libreria WiFiManager è possibile aggiungere parametri personalizzati (variabili o indirizzo server/porta MQTT) e gestire più connessioni SSID.
Di seguito troverete 2 esempi di codice. Uno per un dimmer a 1 canale e il secondo per un dimmer a 4 canali con 4 slider sulla pagina web.
CODICE DIMMER 1 canale
- #include <AsyncTCP.h>
- #include <RBDdimmer.h> //https://rocketcontroller.com/dimmer-connection-to-microcontroller-and-arduino-library-examples/
- #define outputPin 16
- #define zerocross 5 // configurazione dei pin
- dimmerLamp dimmer(outputPin, zerocross); //inizializzazione della porta per il dimmer per schede ESP8266, ESP32, Arduino Due
- #if defined(ESP8266)
- #include <ESP8266WiFi.h> //https://github.com/esp8266/Arduino
- #else
- #include <WiFi.h> //Per ESP32
- #endif
- #include <ESPAsyncWebServer.h>
- #include <ESPAsyncWiFiManager.h> //https://github.com/knolleary/pubsubclient
- //viene chiamato quando WiFiManager entra in modalità configurazione
- void configModeCallback (AsyncWiFiManager *myWiFiManager) {
- Serial.println("Entered config mode");
- Serial.println(WiFi.softAPIP());
- //se è stato usato un SSID generato automaticamente, stamparlo
- Serial.println(myWiFiManager->getConfigPortalSSID());
- }
- AsyncWebServer server(80);
- DNSServer dns;
- String sliderValue = "0";
- const char* PARAM_INPUT = "value";
- const char index_html[] PROGMEM = R"rawliteral(
- <!DOCTYPE HTML><html>
- <head>
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <title>Dimmer ESP Controller</title>
- <style>
- html {font-family: Arial; display: inline-block; text-align: center;}
- h2 {font-size: 2.3rem;}
- p {font-size: 1.9rem;}
- body {max-width: 400px; margin:0px auto; padding-bottom: 25px;}
- .slider { -webkit-appearance: none; margin: 14px; width: 360px; height: 25px; background: #FFD65C;
- outline: none; -webkit-transition: .2s; transition: opacity .2s;}
- .slider::-webkit-slider-thumb {-webkit-appearance: none; appearance: none; width: 35px; height: 35px; background: #003249; cursor: pointer;}
- .slider::-moz-range-thumb { width: 35px; height: 35px; background: #003249; cursor: pointer; }
- .button { background-color: #003249; border: none; color: white; padding: 16px 40px;}
- </style>
- </head>
- <body>
- <h2>RocketController Dimmer</h2>
- <p><span id="textSliderValue">%SLIDERVALUE%</span></p>
- <p><input type="range" onchange="updateSliderPWM(this)" id="pwmSlider" min="0" max="100" value="%SLIDERVALUE%" step="1" class="slider"></p>
- </br>
- <p><a href=/output/on\><button class=\"button\">WiFi RST</button></a></p>
- <script>
- function updateSliderPWM(element) {
- var sliderValue = document.getElementById("pwmSlider").value;
- document.getElementById("textSliderValue").innerHTML = sliderValue;
- console.log(sliderValue);
- var xhr = new XMLHttpRequest();
- xhr.open("GET", "/slider?value="+sliderValue, true);
- xhr.send();
- }
- </script>
- </body>
- </html>
- )rawliteral";
- // Sostituisce il segnaposto con la sezione pulsante nella pagina web
- String processor(const String& var){
- //Serial.println(var);
- if (var == "SLIDERVALUE"){
- return sliderValue;
- }
- return String();
- }
- void setup() {
- // inserire il codice di inizializzazione qui, viene eseguito una sola volta:
- Serial.begin(115200);
- dimmer.begin(NORMAL_MODE, OND);
- //WiFiManager. Inizializzazione locale. Una volta completato il suo compito, non è necessario mantenerlo
- AsyncWiFiManager wifiManager(&server,&dns);
- //ripristinare le impostazioni - per test
- //wifiManager.resetSettings();
- //impostare il callback che viene chiamato quando la connessione al WiFi precedente fallisce e passa in modalità punto di accesso
- //wifiManager.setAPCallback(configModeCallback);
- //recupera SSID e password e tenta di connettersi
- //ed entra in un ciclo di blocco in attesa della configurazione
- if (!wifiManager.autoConnect("WiFi-Dimmer")) {
- Serial.println("failed to connect and hit timeout");
- //ripristinare e riprovare, o mettere in modalità deep sleep
- //ESP.resetSettings();
- //ESP.reset();
- //ESP.restart();
- delay(1000);
- }
- //se si arriva qui, ci si è connessi al WiFi
- Serial.println("connected!");
- // Percorso per la pagina web principale
- server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
- request->send_P(200, "text/html", index_html, processor);
- });
- // Inviare una richiesta GET a <ESP_IP>/slider?value=<inputMessage>
- server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) {
- String inputMessage;
- // Ottenere il valore input1 su <ESP_IP>/slider?value=<inputMessage>
- if (request->hasParam(PARAM_INPUT)) {
- inputMessage = request->getParam(PARAM_INPUT)->value();
- sliderValue = inputMessage;
- dimmer.setPower(sliderValue.toInt()); //DIMMERIZZAZIONE
- }
- else {
- inputMessage = "No message sent";
- }
- //Serial.println(inputMessage);
- Serial.println(sliderValue);
- request->send(200, "text/plain", "OK");
- });
- // Avviare il server
- server.begin();
- }
- void loop() {
- // inserire il codice principale qui, viene eseguito ripetutamente:
- }
CODICE DIMMER 4 canali
- #include <AsyncTCP.h>
- #include <RBDdimmer.h> //https://rocketcontroller.com/dimmer-connection-to-microcontroller-and-arduino-library-examples/
- #define outputPin 16
- #define zerocross 5 // configurazione dei pin
- dimmerLamp dimmer(outputPin, zerocross); //inizializzazione della porta per il dimmer per schede ESP8266, ESP32, Arduino Due
- #if defined(ESP8266)
- #include <ESP8266WiFi.h> //https://github.com/esp8266/Arduino
- #else
- #include <WiFi.h> //per ESP32
- #endif
- #include <ESPAsyncWebServer.h>
- #include <ESPAsyncWiFiManager.h> //https://github.com/knolleary/pubsubclient
- //viene chiamato quando WiFiManager entra in modalità configurazione
- void configModeCallback (AsyncWiFiManager *myWiFiManager) {
- Serial.println("Entered config mode");
- Serial.println(WiFi.softAPIP());
- //se è stato usato un SSID generato automaticamente, stamparlo
- Serial.println(myWiFiManager->getConfigPortalSSID());
- }
- AsyncWebServer server(80);
- DNSServer dns;
- //=====
- String sliderValue = "0";
- String sliderValue2 = "0";
- String sliderValue3 = "0";
- String sliderValue4 = "0";
- const char* PARAM_INPUT = "value";
- const char index_html[] PROGMEM = R"rawliteral(
- <!DOCTYPE HTML><html>
- <head>
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <title>Dimmer ESP Controller</title>
- <style>
- html {font-family: Arial; display: inline-block; text-align: center;}
- h2 {font-size: 2.3rem;}
- p {font-size: 1.9rem;}
- body {max-width: 400px; margin:0px auto; padding-bottom: 25px;}
- .slider { -webkit-appearance: none; margin: 14px; width: 360px; height: 25px; background: #FFD65C;
- outline: none; -webkit-transition: .2s; transition: opacity .2s;}
- .slider::-webkit-slider-thumb {-webkit-appearance: none; appearance: none; width: 35px; height: 35px; background: #003249; cursor: pointer;}
- .slider::-moz-range-thumb { width: 35px; height: 35px; background: #003249; cursor: pointer; }
- .button { background-color: #003249; border: none; color: white; padding: 16px 40px;}
- </style>
- </head>
- <body>
- <h2>Dimmer ESP Controller</h2>
- <p><span id="textSliderValue">%SLIDERVALUE%</span></p>
- <p><input type="range" onchange="updateSliderPWM(this)" id="pwmSlider" min="0" max="100" value="%SLIDERVALUE%" step="1" class="slider"></p>
- </br>
- <h2>Dimmer ESP Controller2</h2>
- <p><span id="textSliderValue2">%SLIDERVALUE2%</span></p>
- <p><input type="range" onchange="updateSliderPWM2(this)" id="pwmSlider" min="0" max="100" value2="%SLIDERVALUE2%" step="1" class="slider"></p>
- </br>
- <h2>Dimmer ESP Controller3</h2>
- <p><span id="textSliderValue3">%SLIDERVALUE3%</span></p>
- <p><input type="range" onchange="updateSliderPWM3(this)" id="pwmSlider" min="0" max="100" value3="%SLIDERVALUE3%" step="1" class="slider"></p>
- </br>
- <h2>Dimmer ESP Controller4</h2>
- <p><span id="textSliderValue4">%SLIDERVALUE4%</span></p>
- <p><input type="range" onchange="updateSliderPWM4(this)" id="pwmSlider" min="0" max="100" value4="%SLIDERVALUE4%" step="1" class="slider"></p>
- </br>
- <p><a href=/output/on\><button class=\"button\">WiFi RST</button></a></p>
- <script>
- function updateSliderPWM (element) {
- var sliderValue = document.getElementById("pwmSlider").value;
- document.getElementById("textSliderValue").innerHTML = sliderValue;
- console.log(sliderValue);
- var xhr = new XMLHttpRequest();
- xhr.open("GET", "/slider?value="+sliderValue, true);
- xhr.send();
- }
- function updateSliderPWM2 (element) {
- var sliderValue2 = document.getElementById("pwmSlider2").value2;
- document.getElementById("textSliderValue2").innerHTML = sliderValue2;
- console.log(sliderValue2);
- var xhr = new XMLHttpRequest();
- xhr.open("GET", "/slider?value="+sliderValue2, true);
- xhr.send();
- }
- function updateSliderPWM3 (element) {
- var sliderValue3 = document.getElementById("pwmSlider3").value3;
- document.getElementById("textSliderValue3").innerHTML = sliderValue3;
- console.log(sliderValue3);
- var xhr = new XMLHttpRequest();
- xhr.open("GET", "/slider?value="+sliderValue3, true);
- xhr.send();
- }
- function updateSliderPWM4 (element) {
- var sliderValue4 = document.getElementById("pwmSlider4").value4;
- document.getElementById("textSliderValue4").innerHTML = sliderValue4;
- console.log(sliderValue4);
- var xhr = new XMLHttpRequest();
- xhr.open("GET", "/slider?value="+sliderValue4, true);
- xhr.send();
- }
- </script>
- </body>
- </html>
- )rawliteral";
- // Sostituisce il segnaposto con la sezione pulsante nella pagina web
- String processor(const String& var){
- //Serial.println(var);
- if (var == "SLIDERVALUE"){
- return sliderValue;
- }
- if (var == "SLIDERVALUE2"){
- return sliderValue2;
- }
- if (var == "SLIDERVALUE3"){
- return sliderValue3;
- }
- if (var == "SLIDERVALUE4"){
- return sliderValue4;
- }
- return String();
- }
- void setup() {
- // inserire il codice di inizializzazione qui, viene eseguito una sola volta:
- Serial.begin(115200);
- dimmer.begin(NORMAL_MODE, OND);
- //WiFiManager
- //Inizializzazione locale. Una volta completato il suo compito, non è necessario mantenerlo
- AsyncWiFiManager wifiManager(&server,&dns);
- //ripristinare le impostazioni - per test
- //wifiManager.resetSettings();
- //impostare il callback che viene chiamato quando la connessione al WiFi precedente fallisce e passa in modalità punto di accesso
- //wifiManager.setAPCallback(configModeCallback);
- //recupera SSID e password e tenta di connettersi
- //ed entra in un ciclo di blocco in attesa della configurazione
- if (!wifiManager.autoConnect("WiFi-Dimmer")) {
- Serial.println("failed to connect and hit timeout");
- //ripristinare e riprovare, o mettere in modalità deep sleep
- //ESP.resetSettings();
- //ESP.reset();
- //ESP.restart();
- delay(1000);
- }
- //se si arriva qui, ci si è connessi al WiFi
- Serial.println("connected...yeey :)");
- // Percorso per la pagina web principale
- server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
- request->send_P(200, "text/html", index_html, processor);
- });
- // Inviare una richiesta GET a <ESP_IP>/slider?value=<inputMessage>
- server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) {
- String inputMessage;
- // Ottenere il valore input1 su <ESP_IP>/slider?value=<inputMessage>
- if (request->hasParam(PARAM_INPUT)) {
- inputMessage = request->getParam(PARAM_INPUT)->value();
- sliderValue = inputMessage;
- dimmer.setPower(sliderValue.toInt());
- }
- String inputMessage2;
- // Ottenere il valore input1 su <ESP_IP>/slider?value=<inputMessage>
- if (request->hasParam(PARAM_INPUT)) {
- inputMessage2 = request->getParam(PARAM_INPUT)->value();
- sliderValue2 = inputMessage2;
- }
- else {
- inputMessage = "No message sent";
- }
- //Serial.println(inputMessage);
- Serial.println(sliderValue);
- Serial.print("DIM2");
- Serial.println(sliderValue2);
- Serial.print("DIM3");
- Serial.println(sliderValue3);
- Serial.print("DIM4");
- Serial.println(sliderValue4);
- request->send(200, "text/plain", "OK");
- });
- // Avviare il server
- server.begin();
- }
- void loop() {
- // inserire il codice principale qui, viene eseguito ripetutamente:
- }
Passo 1. Configurazione dell'accesso Wi-Fi.
WiFiManager è un'eccellente libreria da aggiungere ai progetti ESP8266/ESP32, perché grazie ad essa non è più necessario codificare le credenziali di rete (SSID e password) direttamente nel codice. L'ESP si connetterà automaticamente a una rete conosciuta oppure creerà un punto di accesso che potrete utilizzare per configurare le credenziali di rete. Ecco come funziona questo processo:
- Quando l'ESP8266/ESP32 si avvia, viene configurato in modalità Stazione e tenta di connettersi a un punto di accesso precedentemente salvato (una combinazione nota di SSID e password);
- Se questo processo fallisce, l'ESP viene configurato in modalità punto di accesso;
- Utilizzando qualsiasi dispositivo abilitato al Wi-Fi con un browser, collegatevi al punto di accesso appena creato (WiFi-Dimmer);
- Dopo aver stabilito una connessione con "WiFi-Dimmer", potete accedere all'indirizzo IP predefinito 192.168.4.1 per aprire una pagina web che consente di configurare SSID e password;
- Una volta impostati un nuovo SSID e una nuova password, l'ESP si riavvia e tenta di connettersi;
Se stabilisce una connessione, il processo è completato con successo. In caso contrario, verrà configurato come punto di accesso.

Passo 2. Slider del server web e dimmerizzazione.
- L'ESP8266/ESP32 ospita un server web che visualizza una pagina web con uno slider;
- Quando si sposta lo slider, viene inviata una richiesta HTTP all'ESP8266/ESP32 con il nuovo valore dello slider;
- La richiesta HTTP ha il seguente formato: GET/slider?value=SLIDERVALUE, dove SLIDERVALUE è un numero compreso tra 0 e 100;
- Dalla richiesta HTTP, l'ESP8266/ESP32 ottiene il valore corrente dello slider;
- L'ESP8266 regola il valore del dimmer in base al valore dello slider: dimmer.setPower(sliderValue.toInt()); //DIMMERIZZAZIONE;
Per il dimmer a 4 canali, nella pagina web sono presenti 4 slider.
