Ir al contenido

Dimmer controller – ESP32/8266 web server with slider Arduino code.

28 de marzo de 2025 por
Dimmer controller – ESP32/8266 web server with slider Arduino code.
Administrator
| Sin comentarios aún


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

  1. #include <AsyncTCP.h>
  2. #include <RBDdimmer.h> //https://rocketcontroller.com/dimmer-connection-to-microcontroller-and-arduino-library-examples/
  3. #define outputPin 16
  4. #define zerocross 5 // configuración de pines
  5. dimmerLamp dimmer(outputPin, zerocross); //inicializar puerto para dimmer en placas ESP8266, ESP32, Arduino Due
  6. #if defined(ESP8266)
  7. #include <ESP8266WiFi.h> //https://github.com/esp8266/Arduino
  8. #else
  9. #include <WiFi.h> //Para ESP32
  10. #endif
  11. #include <ESPAsyncWebServer.h>
  12. #include <ESPAsyncWiFiManager.h> //https://github.com/knolleary/pubsubclient
  13. //se llama cuando WiFiManager entra en modo de configuración
  14. void configModeCallback (AsyncWiFiManager *myWiFiManager) {
  15. Serial.println("Entered config mode");
  16. Serial.println(WiFi.softAPIP());
  17. //si se usó un SSID generado automáticamente, mostrarlo
  18. Serial.println(myWiFiManager->getConfigPortalSSID());
  19. }
  20. AsyncWebServer server(80);
  21. DNSServer dns;
  22. String sliderValue = "0";
  23. const char* PARAM_INPUT = "value";
  24. const char index_html[] PROGMEM = R"rawliteral(
  25. <!DOCTYPE HTML><html>
  26. <head>
  27. <meta name="viewport" content="width=device-width, initial-scale=1">
  28. <title>Dimmer ESP Controller</title>
  29. <style>
  30. html {font-family: Arial; display: inline-block; text-align: center;}
  31. h2 {font-size: 2.3rem;}
  32. p {font-size: 1.9rem;}
  33. body {max-width: 400px; margin:0px auto; padding-bottom: 25px;}
  34. .slider { -webkit-appearance: none; margin: 14px; width: 360px; height: 25px; background: #FFD65C;
  35. outline: none; -webkit-transition: .2s; transition: opacity .2s;}
  36. .slider::-webkit-slider-thumb {-webkit-appearance: none; appearance: none; width: 35px; height: 35px; background: #003249; cursor: pointer;}
  37. .slider::-moz-range-thumb { width: 35px; height: 35px; background: #003249; cursor: pointer; }
  38. .button { background-color: #003249; border: none; color: white; padding: 16px 40px;}
  39. </style>
  40. </head>
  41. <body>
  42. <h2>RocketController Dimmer</h2>
  43. <p><span id="textSliderValue">%SLIDERVALUE%</span></p>
  44. <p><input type="range" onchange="updateSliderPWM(this)" id="pwmSlider" min="0" max="100" value="%SLIDERVALUE%" step="1" class="slider"></p>
  45. </br>
  46. <p><a href=/output/on\><button class=\"button\">WiFi RST</button></a></p>
  47. <script>
  48. function updateSliderPWM(element) {
  49. var sliderValue = document.getElementById("pwmSlider").value;
  50. document.getElementById("textSliderValue").innerHTML = sliderValue;
  51. console.log(sliderValue);
  52. var xhr = new XMLHttpRequest();
  53. xhr.open("GET", "/slider?value="+sliderValue, true);
  54. xhr.send();
  55. }
  56. </script>
  57. </body>
  58. </html>
  59. )rawliteral";
  60. // Reemplaza el marcador de posición por la sección de botón en su página web
  61. String processor(const String& var){
  62. //Serial.println(var);
  63. if (var == "SLIDERVALUE"){
  64. return sliderValue;
  65. }
  66. return String();
  67. }
  68. void setup() {
  69. // inserte su código de inicialización aquí, se ejecuta una sola vez:
  70. Serial.begin(115200);
  71. dimmer.begin(NORMAL_MODE, OND);
  72. //WiFiManager. Inicialización local. Una vez que termina su tarea, no es necesario conservarlo
  73. AsyncWiFiManager wifiManager(&server,&dns);
  74. //restablecer configuración - para pruebas
  75. //wifiManager.resetSettings();
  76. //establecer callback que se llama cuando falla la conexión al WiFi anterior y entra en modo punto de acceso
  77. //wifiManager.setAPCallback(configModeCallback);
  78. //obtiene el SSID y la contraseña e intenta conectarse
  79. //y entra en un bucle de bloqueo esperando configuración
  80. if (!wifiManager.autoConnect("WiFi-Dimmer")) {
  81. Serial.println("failed to connect and hit timeout");
  82. //restablecer e intentar de nuevo, o poner en modo de suspensión profunda
  83. //ESP.resetSettings();
  84. //ESP.reset();
  85. //ESP.restart();
  86. delay(1000);
  87. }
  88. //si llega aquí, se ha conectado al WiFi
  89. Serial.println("connected!");
  90. // Ruta para la página web raíz
  91. server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
  92. request->send_P(200, "text/html", index_html, processor);
  93. });
  94. // Enviar una solicitud GET a <ESP_IP>/slider?value=<inputMessage>
  95. server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) {
  96. String inputMessage;
  97. // Obtener valor input1 en <ESP_IP>/slider?value=<inputMessage>
  98. if (request->hasParam(PARAM_INPUT)) {
  99. inputMessage = request->getParam(PARAM_INPUT)->value();
  100. sliderValue = inputMessage;
  101. dimmer.setPower(sliderValue.toInt()); //ATENUACIÓN
  102. }
  103. else {
  104. inputMessage = "No message sent";
  105. }
  106. //Serial.println(inputMessage);
  107. Serial.println(sliderValue);
  108. request->send(200, "text/plain", "OK");
  109. });
  110. // Iniciar servidor
  111. server.begin();
  112. }
  113. void loop() {
  114. // inserte su código principal aquí, se ejecuta repetidamente:
  115. }


CÓDIGO DIMMER de 4 canales

  1. #include <AsyncTCP.h>
  2. #include <RBDdimmer.h> //https://rocketcontroller.com/dimmer-connection-to-microcontroller-and-arduino-library-examples/
  3. #define outputPin 16
  4. #define zerocross 5 // configuración de pines
  5. dimmerLamp dimmer(outputPin, zerocross); //inicializar puerto para dimmer en placas ESP8266, ESP32, Arduino Due
  6. #if defined(ESP8266)
  7. #include <ESP8266WiFi.h> //https://github.com/esp8266/Arduino
  8. #else
  9. #include <WiFi.h> //para ESP32
  10. #endif
  11. #include <ESPAsyncWebServer.h>
  12. #include <ESPAsyncWiFiManager.h> //https://github.com/knolleary/pubsubclient
  13. //se llama cuando WiFiManager entra en modo de configuración
  14. void configModeCallback (AsyncWiFiManager *myWiFiManager) {
  15. Serial.println("Entered config mode");
  16. Serial.println(WiFi.softAPIP());
  17. //si se usó un SSID generado automáticamente, mostrarlo
  18. Serial.println(myWiFiManager->getConfigPortalSSID());
  19. }
  20. AsyncWebServer server(80);
  21. DNSServer dns;
  22. //=====
  23. String sliderValue = "0";
  24. String sliderValue2 = "0";
  25. String sliderValue3 = "0";
  26. String sliderValue4 = "0";
  27. const char* PARAM_INPUT = "value";
  28. const char index_html[] PROGMEM = R"rawliteral(
  29. <!DOCTYPE HTML><html>
  30. <head>
  31. <meta name="viewport" content="width=device-width, initial-scale=1">
  32. <title>Dimmer ESP Controller</title>
  33. <style>
  34. html {font-family: Arial; display: inline-block; text-align: center;}
  35. h2 {font-size: 2.3rem;}
  36. p {font-size: 1.9rem;}
  37. body {max-width: 400px; margin:0px auto; padding-bottom: 25px;}
  38. .slider { -webkit-appearance: none; margin: 14px; width: 360px; height: 25px; background: #FFD65C;
  39. outline: none; -webkit-transition: .2s; transition: opacity .2s;}
  40. .slider::-webkit-slider-thumb {-webkit-appearance: none; appearance: none; width: 35px; height: 35px; background: #003249; cursor: pointer;}
  41. .slider::-moz-range-thumb { width: 35px; height: 35px; background: #003249; cursor: pointer; }
  42. .button { background-color: #003249; border: none; color: white; padding: 16px 40px;}
  43. </style>
  44. </head>
  45. <body>
  46. <h2>Dimmer ESP Controller</h2>
  47. <p><span id="textSliderValue">%SLIDERVALUE%</span></p>
  48. <p><input type="range" onchange="updateSliderPWM(this)" id="pwmSlider" min="0" max="100" value="%SLIDERVALUE%" step="1" class="slider"></p>
  49. </br>
  50. <h2>Dimmer ESP Controller2</h2>
  51. <p><span id="textSliderValue2">%SLIDERVALUE2%</span></p>
  52. <p><input type="range" onchange="updateSliderPWM2(this)" id="pwmSlider" min="0" max="100" value2="%SLIDERVALUE2%" step="1" class="slider"></p>
  53. </br>
  54. <h2>Dimmer ESP Controller3</h2>
  55. <p><span id="textSliderValue3">%SLIDERVALUE3%</span></p>
  56. <p><input type="range" onchange="updateSliderPWM3(this)" id="pwmSlider" min="0" max="100" value3="%SLIDERVALUE3%" step="1" class="slider"></p>
  57. </br>
  58. <h2>Dimmer ESP Controller4</h2>
  59. <p><span id="textSliderValue4">%SLIDERVALUE4%</span></p>
  60. <p><input type="range" onchange="updateSliderPWM4(this)" id="pwmSlider" min="0" max="100" value4="%SLIDERVALUE4%" step="1" class="slider"></p>
  61. </br>
  62. <p><a href=/output/on\><button class=\"button\">WiFi RST</button></a></p>
  63. <script>
  64. function updateSliderPWM (element) {
  65. var sliderValue = document.getElementById("pwmSlider").value;
  66. document.getElementById("textSliderValue").innerHTML = sliderValue;
  67. console.log(sliderValue);
  68. var xhr = new XMLHttpRequest();
  69. xhr.open("GET", "/slider?value="+sliderValue, true);
  70. xhr.send();
  71. }
  72. function updateSliderPWM2 (element) {
  73. var sliderValue2 = document.getElementById("pwmSlider2").value2;
  74. document.getElementById("textSliderValue2").innerHTML = sliderValue2;
  75. console.log(sliderValue2);
  76. var xhr = new XMLHttpRequest();
  77. xhr.open("GET", "/slider?value="+sliderValue2, true);
  78. xhr.send();
  79. }
  80. function updateSliderPWM3 (element) {
  81. var sliderValue3 = document.getElementById("pwmSlider3").value3;
  82. document.getElementById("textSliderValue3").innerHTML = sliderValue3;
  83. console.log(sliderValue3);
  84. var xhr = new XMLHttpRequest();
  85. xhr.open("GET", "/slider?value="+sliderValue3, true);
  86. xhr.send();
  87. }
  88. function updateSliderPWM4 (element) {
  89. var sliderValue4 = document.getElementById("pwmSlider4").value4;
  90. document.getElementById("textSliderValue4").innerHTML = sliderValue4;
  91. console.log(sliderValue4);
  92. var xhr = new XMLHttpRequest();
  93. xhr.open("GET", "/slider?value="+sliderValue4, true);
  94. xhr.send();
  95. }
  96. </script>
  97. </body>
  98. </html>
  99. )rawliteral";
  100. // Reemplaza el marcador de posición por la sección de botón en su página web
  101. String processor(const String& var){
  102. //Serial.println(var);
  103. if (var == "SLIDERVALUE"){
  104. return sliderValue;
  105. }
  106. if (var == "SLIDERVALUE2"){
  107. return sliderValue2;
  108. }
  109. if (var == "SLIDERVALUE3"){
  110. return sliderValue3;
  111. }
  112. if (var == "SLIDERVALUE4"){
  113. return sliderValue4;
  114. }
  115. return String();
  116. }
  117. void setup() {
  118. // inserte su código de inicialización aquí, se ejecuta una sola vez:
  119. Serial.begin(115200);
  120. dimmer.begin(NORMAL_MODE, OND);
  121. //WiFiManager
  122. //Inicialización local. Una vez que termina su tarea, no es necesario conservarlo
  123. AsyncWiFiManager wifiManager(&server,&dns);
  124. //restablecer configuración - para pruebas
  125. //wifiManager.resetSettings();
  126. //establecer callback que se llama cuando falla la conexión al WiFi anterior y entra en modo punto de acceso
  127. //wifiManager.setAPCallback(configModeCallback);
  128. //obtiene el SSID y la contraseña e intenta conectarse
  129. //y entra en un bucle de bloqueo esperando configuración
  130. if (!wifiManager.autoConnect("WiFi-Dimmer")) {
  131. Serial.println("failed to connect and hit timeout");
  132. //restablecer e intentar de nuevo, o poner en modo de suspensión profunda
  133. //ESP.resetSettings();
  134. //ESP.reset();
  135. //ESP.restart();
  136. delay(1000);
  137. }
  138. //si llega aquí, se ha conectado al WiFi
  139. Serial.println("connected...yeey :)");
  140. // Ruta para la página web raíz
  141. server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
  142. request->send_P(200, "text/html", index_html, processor);
  143. });
  144. // Enviar una solicitud GET a <ESP_IP>/slider?value=<inputMessage>
  145. server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) {
  146. String inputMessage;
  147. // Obtener valor input1 en <ESP_IP>/slider?value=<inputMessage>
  148. if (request->hasParam(PARAM_INPUT)) {
  149. inputMessage = request->getParam(PARAM_INPUT)->value();
  150. sliderValue = inputMessage;
  151. dimmer.setPower(sliderValue.toInt());
  152. }
  153. String inputMessage2;
  154. // Obtener valor input1 en <ESP_IP>/slider?value=<inputMessage>
  155. if (request->hasParam(PARAM_INPUT)) {
  156. inputMessage2 = request->getParam(PARAM_INPUT)->value();
  157. sliderValue2 = inputMessage2;
  158. }
  159. else {
  160. inputMessage = "No message sent";
  161. }
  162. //Serial.println(inputMessage);
  163. Serial.println(sliderValue);
  164. Serial.print("DIM2");
  165. Serial.println(sliderValue2);
  166. Serial.print("DIM3");
  167. Serial.println(sliderValue3);
  168. Serial.print("DIM4");
  169. Serial.println(sliderValue4);
  170. request->send(200, "text/plain", "OK");
  171. });
  172. // Iniciar servidor
  173. server.begin();
  174. }
  175. void loop() {
  176. // inserte su código principal aquí, se ejecuta repetidamente:
  177. }


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.



Compartir esta publicación
Iniciar sesión para dejar un comentario