
En este proyecto de control de dimmer con servidor web, aprenderemos a crear con ESP8266 y ESP32 un servidor web con slider que controlará el nivel de voltaje de atenuación del dimmer conectado al pin GPIO del ESP8266 / ESP32.
Esto se logrará mediante un slider HTML que agregaremos a la página del servidor web. El slider se moverá para establecer su valor. En respuesta, este valor del slider establecerá el valor del dimmer.
Además, utilizamos la biblioteca WiFiManager que le permite conectar su proyecto de dimmer basado en ESP8266/ESP32 a diferentes puntos de acceso (AP) sin necesidad de codificar y cargar nuevo código en su placa. Adicionalmente, con la biblioteca WiFiManager también puede agregar parámetros personalizados (variables o dirección de servidor/puerto MQTT) y gestionar múltiples conexiones SSID.
A continuación encontrará 2 ejemplos de código. Uno para un dimmer de 1 canal y el segundo código para un dimmer de 4 canales con 4 sliders en la página web.
CÓDIGO DIMMER de 1 canal
- #include <AsyncTCP.h>
- #include <RBDdimmer.h> //https://rocketcontroller.com/dimmer-connection-to-microcontroller-and-arduino-library-examples/
- #define outputPin 16
- #define zerocross 5 // configuración de pines
- dimmerLamp dimmer(outputPin, zerocross); //inicializar puerto para dimmer en placas ESP8266, ESP32, Arduino Due
- #if defined(ESP8266)
- #include <ESP8266WiFi.h> //https://github.com/esp8266/Arduino
- #else
- #include <WiFi.h> //Para ESP32
- #endif
- #include <ESPAsyncWebServer.h>
- #include <ESPAsyncWiFiManager.h> //https://github.com/knolleary/pubsubclient
- //se llama cuando WiFiManager entra en modo de configuración
- void configModeCallback (AsyncWiFiManager *myWiFiManager) {
- Serial.println("Entered config mode");
- Serial.println(WiFi.softAPIP());
- //si se usó un SSID generado automáticamente, mostrarlo
- 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";
- // Reemplaza el marcador de posición por la sección de botón en su página web
- String processor(const String& var){
- //Serial.println(var);
- if (var == "SLIDERVALUE"){
- return sliderValue;
- }
- return String();
- }
- void setup() {
- // inserte su código de inicialización aquí, se ejecuta una sola vez:
- Serial.begin(115200);
- dimmer.begin(NORMAL_MODE, OND);
- //WiFiManager. Inicialización local. Una vez que termina su tarea, no es necesario conservarlo
- AsyncWiFiManager wifiManager(&server,&dns);
- //restablecer configuración - para pruebas
- //wifiManager.resetSettings();
- //establecer callback que se llama cuando falla la conexión al WiFi anterior y entra en modo punto de acceso
- //wifiManager.setAPCallback(configModeCallback);
- //obtiene el SSID y la contraseña e intenta conectarse
- //y entra en un bucle de bloqueo esperando configuración
- if (!wifiManager.autoConnect("WiFi-Dimmer")) {
- Serial.println("failed to connect and hit timeout");
- //restablecer e intentar de nuevo, o poner en modo de suspensión profunda
- //ESP.resetSettings();
- //ESP.reset();
- //ESP.restart();
- delay(1000);
- }
- //si llega aquí, se ha conectado al WiFi
- Serial.println("connected!");
- // Ruta para la página web raíz
- server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
- request->send_P(200, "text/html", index_html, processor);
- });
- // Enviar una solicitud GET a <ESP_IP>/slider?value=<inputMessage>
- server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) {
- String inputMessage;
- // Obtener valor input1 en <ESP_IP>/slider?value=<inputMessage>
- if (request->hasParam(PARAM_INPUT)) {
- inputMessage = request->getParam(PARAM_INPUT)->value();
- sliderValue = inputMessage;
- dimmer.setPower(sliderValue.toInt()); //ATENUACIÓN
- }
- else {
- inputMessage = "No message sent";
- }
- //Serial.println(inputMessage);
- Serial.println(sliderValue);
- request->send(200, "text/plain", "OK");
- });
- // Iniciar servidor
- server.begin();
- }
- void loop() {
- // inserte su código principal aquí, se ejecuta repetidamente:
- }
CÓDIGO DIMMER de 4 canales
- #include <AsyncTCP.h>
- #include <RBDdimmer.h> //https://rocketcontroller.com/dimmer-connection-to-microcontroller-and-arduino-library-examples/
- #define outputPin 16
- #define zerocross 5 // configuración de pines
- dimmerLamp dimmer(outputPin, zerocross); //inicializar puerto para dimmer en placas ESP8266, ESP32, Arduino Due
- #if defined(ESP8266)
- #include <ESP8266WiFi.h> //https://github.com/esp8266/Arduino
- #else
- #include <WiFi.h> //para ESP32
- #endif
- #include <ESPAsyncWebServer.h>
- #include <ESPAsyncWiFiManager.h> //https://github.com/knolleary/pubsubclient
- //se llama cuando WiFiManager entra en modo de configuración
- void configModeCallback (AsyncWiFiManager *myWiFiManager) {
- Serial.println("Entered config mode");
- Serial.println(WiFi.softAPIP());
- //si se usó un SSID generado automáticamente, mostrarlo
- 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";
- // Reemplaza el marcador de posición por la sección de botón en su página 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() {
- // inserte su código de inicialización aquí, se ejecuta una sola vez:
- Serial.begin(115200);
- dimmer.begin(NORMAL_MODE, OND);
- //WiFiManager
- //Inicialización local. Una vez que termina su tarea, no es necesario conservarlo
- AsyncWiFiManager wifiManager(&server,&dns);
- //restablecer configuración - para pruebas
- //wifiManager.resetSettings();
- //establecer callback que se llama cuando falla la conexión al WiFi anterior y entra en modo punto de acceso
- //wifiManager.setAPCallback(configModeCallback);
- //obtiene el SSID y la contraseña e intenta conectarse
- //y entra en un bucle de bloqueo esperando configuración
- if (!wifiManager.autoConnect("WiFi-Dimmer")) {
- Serial.println("failed to connect and hit timeout");
- //restablecer e intentar de nuevo, o poner en modo de suspensión profunda
- //ESP.resetSettings();
- //ESP.reset();
- //ESP.restart();
- delay(1000);
- }
- //si llega aquí, se ha conectado al WiFi
- Serial.println("connected...yeey :)");
- // Ruta para la página web raíz
- server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
- request->send_P(200, "text/html", index_html, processor);
- });
- // Enviar una solicitud GET a <ESP_IP>/slider?value=<inputMessage>
- server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) {
- String inputMessage;
- // Obtener valor input1 en <ESP_IP>/slider?value=<inputMessage>
- if (request->hasParam(PARAM_INPUT)) {
- inputMessage = request->getParam(PARAM_INPUT)->value();
- sliderValue = inputMessage;
- dimmer.setPower(sliderValue.toInt());
- }
- String inputMessage2;
- // Obtener valor input1 en <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");
- });
- // Iniciar servidor
- server.begin();
- }
- void loop() {
- // inserte su código principal aquí, se ejecuta repetidamente:
- }
Paso 1. Configuración del acceso Wi-Fi.
WiFiManager es una excelente biblioteca para agregar a sus proyectos ESP8266/ESP32, ya que con ella no necesita codificar de forma fija sus credenciales de red (SSID y contraseña). Su ESP se conectará automáticamente a una red conocida o configurará un punto de acceso que podrá usar para configurar las credenciales de red. Así es como funciona este proceso:
- Cuando su ESP8266/ESP32 arranca, se configura en modo Estación e intenta conectarse a un punto de acceso previamente guardado (una combinación conocida de SSID y contraseña);
- Si este proceso falla, configura el ESP en modo punto de acceso;
- Usando cualquier dispositivo con Wi-Fi y navegador, conéctese al punto de acceso recién creado (WiFi-Dimmer);
- Después de establecer una conexión con "WiFi-Dimmer", puede ir a la dirección IP predeterminada 192.168.4.1 para abrir una página web que le permite configurar su SSID y contraseña;
- Una vez que se establecen un nuevo SSID y contraseña, el ESP se reinicia e intenta conectarse;
Si establece una conexión, el proceso se completa exitosamente. De lo contrario, se configurará como punto de acceso.

Paso 2. Slider del servidor web y atenuación.
- El ESP8266/ESP32 aloja un servidor web que muestra una página web con un slider;
- Cuando mueve el slider, envía una solicitud HTTP al ESP8266/ESP32 con el nuevo valor del slider;
- La solicitud HTTP tiene el siguiente formato: GET/slider?value=SLIDERVALUE, donde SLIDERVALUE es un número entre 0 y 100;
- A partir de la solicitud HTTP, el ESP8266/ESP32 obtiene el valor actual del slider;
- El ESP8266 ajusta el valor del dimmer de acuerdo con el valor del slider: dimmer.setPower(sliderValue.toInt()); //ATENUACIÓN;
Para el dimmer de 4 canales, en la página web se muestran 4 sliders.
