Перейти к содержимому

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

28 марта 2025 г. от
Dimmer controller – ESP32/8266 web server with slider Arduino code.
Administrator
| Комментариев пока нет


В этом проекте управления диммером с помощью веб-сервера мы рассмотрим, как создать на основе ESP8266 и ESP32 веб-сервер с ползунком для управления уровнем напряжения диммера, подключённого к GPIO-выводу ESP8266 / ESP32.

Для этого мы добавим на страницу веб-сервера HTML-ползунок. Перемещая ползунок, вы задаёте его значение, которое в свою очередь устанавливает уровень диммирования.

Кроме того, мы используем библиотеку WiFiManager, которая позволяет подключать проект диммера на базе ESP8266/ESP32 к различным точкам доступа (AP) без необходимости жёстко прописывать и загружать новый код на плату. Также с помощью библиотеки WiFiManager можно добавлять пользовательские параметры (переменные или адрес/порт MQTT-сервера) и управлять подключением к нескольким SSID.

Ниже приведены 2 примера кода. Первый — для одноканального диммера, второй — для 4-канального диммера с 4 ползунками на веб-странице.


Код для 1-канального ДИММЕРА

  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 // назначение выводов
  5. dimmerLamp dimmer(outputPin, zerocross); //инициализация порта для диммера для плат ESP8266, ESP32, Arduino Due
  6. #if defined(ESP8266)
  7. #include <ESP8266WiFi.h> //https://github.com/esp8266/Arduino
  8. #else
  9. #include <WiFi.h> //Для ESP32
  10. #endif
  11. #include <ESPAsyncWebServer.h>
  12. #include <ESPAsyncWiFiManager.h> //https://github.com/knolleary/pubsubclient
  13. //вызывается при переходе WiFiManager в режим конфигурации
  14. void configModeCallback (AsyncWiFiManager *myWiFiManager) {
  15. Serial.println("Entered config mode");
  16. Serial.println(WiFi.softAPIP());
  17. //если использовался автоматически сгенерированный SSID, вывести его
  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. // Заменяет заполнитель на секцию с кнопкой на веб-странице
  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. // поместите ваш код инициализации здесь, выполняется один раз:
  70. Serial.begin(115200);
  71. dimmer.begin(NORMAL_MODE, OND);
  72. //WiFiManager. Локальная инициализация. После завершения работы нет необходимости хранить объект
  73. AsyncWiFiManager wifiManager(&server,&dns);
  74. //сброс настроек — для тестирования
  75. //wifiManager.resetSettings();
  76. //установка колбэка, который вызывается при неудачном подключении к предыдущему WiFi и переходе в режим точки доступа
  77. //wifiManager.setAPCallback(configModeCallback);
  78. //получает ssid и пароль, пытается подключиться
  79. //и входит в блокирующий цикл ожидания конфигурации
  80. if (!wifiManager.autoConnect("WiFi-Dimmer")) {
  81. Serial.println("failed to connect and hit timeout");
  82. //сбросить и попробовать снова, или перевести в глубокий сон
  83. //ESP.resetSettings();
  84. //ESP.reset();
  85. //ESP.restart();
  86. delay(1000);
  87. }
  88. //если вы дошли до этой строки, подключение к WiFi выполнено
  89. Serial.println("connected!");
  90. // Маршрут для корневой / веб-страницы
  91. server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
  92. request->send_P(200, "text/html", index_html, processor);
  93. });
  94. // Отправка GET-запроса на <ESP_IP>/slider?value=<inputMessage>
  95. server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) {
  96. String inputMessage;
  97. // Получение значения input1 по адресу <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()); //ДИММИРОВАНИЕ
  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. // Запуск сервера
  111. server.begin();
  112. }
  113. void loop() {
  114. // поместите ваш основной код здесь, выполняется циклически:
  115. }


Код для 4-канального ДИММЕРА

  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 // назначение выводов
  5. dimmerLamp dimmer(outputPin, zerocross); //инициализация порта для диммера для плат ESP8266, ESP32, Arduino Due
  6. #if defined(ESP8266)
  7. #include <ESP8266WiFi.h> //https://github.com/esp8266/Arduino
  8. #else
  9. #include <WiFi.h> //для ESP32
  10. #endif
  11. #include <ESPAsyncWebServer.h>
  12. #include <ESPAsyncWiFiManager.h> //https://github.com/knolleary/pubsubclient
  13. //вызывается при переходе WiFiManager в режим конфигурации
  14. void configModeCallback (AsyncWiFiManager *myWiFiManager) {
  15. Serial.println("Entered config mode");
  16. Serial.println(WiFi.softAPIP());
  17. //если использовался автоматически сгенерированный SSID, вывести его
  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. // Заменяет заполнитель на секцию с кнопкой на веб-странице
  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. // поместите ваш код инициализации здесь, выполняется один раз:
  119. Serial.begin(115200);
  120. dimmer.begin(NORMAL_MODE, OND);
  121. //WiFiManager
  122. //Локальная инициализация. После завершения работы нет необходимости хранить объект
  123. AsyncWiFiManager wifiManager(&server,&dns);
  124. //сброс настроек — для тестирования
  125. //wifiManager.resetSettings();
  126. //установка колбэка, который вызывается при неудачном подключении к предыдущему WiFi и переходе в режим точки доступа
  127. //wifiManager.setAPCallback(configModeCallback);
  128. //получает ssid и пароль, пытается подключиться
  129. //и входит в блокирующий цикл ожидания конфигурации
  130. if (!wifiManager.autoConnect("WiFi-Dimmer")) {
  131. Serial.println("failed to connect and hit timeout");
  132. //сбросить и попробовать снова, или перевести в глубокий сон
  133. //ESP.resetSettings();
  134. //ESP.reset();
  135. //ESP.restart();
  136. delay(1000);
  137. }
  138. //если вы дошли до этой строки, подключение к WiFi выполнено
  139. Serial.println("connected...yeey :)");
  140. // Маршрут для корневой / веб-страницы
  141. server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
  142. request->send_P(200, "text/html", index_html, processor);
  143. });
  144. // Отправка GET-запроса на <ESP_IP>/slider?value=<inputMessage>
  145. server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) {
  146. String inputMessage;
  147. // Получение значения input1 по адресу <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. // Получение значения input1 по адресу <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. // Запуск сервера
  173. server.begin();
  174. }
  175. void loop() {
  176. // поместите ваш основной код здесь, выполняется циклически:
  177. }


Шаг 1. Настройка доступа к Wi-Fi.

WiFiManager — отличная библиотека для использования в проектах на ESP8266/ESP32, поскольку с ней вам больше не нужно жёстко прописывать сетевые учётные данные (SSID и пароль). ESP автоматически подключится к известной сети или создаст точку доступа, которую можно использовать для настройки сетевых параметров. Вот как работает этот процесс:

  • Когда ESP8266/ESP32 загружается, он переходит в режим станции (Station mode) и пытается подключиться к ранее сохранённой точке доступа (известная комбинация SSID и пароля);
  • Если подключение не удаётся, ESP переходит в режим точки доступа;
  • С помощью любого устройства с Wi-Fi и браузером подключитесь к созданной точке доступа (WiFi-Dimmer);
  • После подключения к «WiFi-Dimmer» откройте IP-адрес по умолчанию 192.168.4.1, чтобы открыть веб-страницу для настройки SSID и пароля;
  • После задания нового SSID и пароля ESP перезагружается и пытается подключиться;

Если подключение установлено, процесс завершён успешно. В противном случае ESP снова перейдёт в режим точки доступа.


Шаг 2. Веб-сервер с ползунком и диммирование.

  • ESP8266/ESP32 размещает веб-сервер с веб-страницей, содержащей ползунок;
  • Когда вы перемещаете ползунок, на ESP8266/ESP32 отправляется HTTP-запрос с новым значением ползунка;
  • HTTP-запрос имеет следующий формат: GET/slider?value=SLIDERVALUE, где SLIDERVALUE — число от 0 до 100;
  • Из HTTP-запроса ESP8266/ESP32 получает текущее значение ползунка;
  • ESP8266 устанавливает уровень диммера в соответствии со значением ползунка: dimmer.setPower(sliderValue.toInt()); //ДИММИРОВАНИЕ;

Для 4-канального диммера на веб-странице отображаются 4 ползунка.



Поделиться этой записью
Войти оставить комментарий