ESP32 Веб-сервер со слайдером: Управление яркостью светодиода (ШИМ)
Это руководство показывает, как создать веб-сервер ESP32 со слайдером для управления яркостью светодиода. Вы узнаете, как добавить слайдер в ваши проекты веб-серверов, получить его значение и сохранить в переменной, которую ESP32 может использовать. Мы будем использовать это значение для управления скважностью ШИМ-сигнала и изменения яркости светодиода. Вместо светодиода вы можете управлять, например, сервоприводом.
Кроме того, вы можете модифицировать код из этого руководства, чтобы добавить слайдер в ваши проекты для установки порогового значения или любого другого значения, которое вам нужно использовать в коде.
Обзор проекта
ESP32 размещает веб-сервер, который отображает веб-страницу со слайдером;
Когда вы перемещаете слайдер, вы отправляете HTTP-запрос к ESP32 с новым значением слайдера;
HTTP-запрос приходит в следующем формате: GET/slider?value=SLIDERVALUE, где SLIDERVALUE – число от 0 до 255. Вы можете изменить слайдер, чтобы включить любой другой диапазон;
Из HTTP-запроса ESP32 получает текущее значение слайдера;
ESP32 настраивает скважность ШИМ в соответствии со значением слайдера;
Это может быть полезно для управления яркостью светодиода (как мы сделаем в этом примере), сервопривода, установки порогового значения или других применений.
Предварительные требования
Перед началом работы над этим проектом убедитесь, что вы выполнили следующие предварительные требования.
Arduino IDE
Мы будем программировать платы ESP32 с помощью Arduino IDE, поэтому перед выполнением этого руководства убедитесь, что у вас установлена плата ESP32 в Arduino IDE.
Библиотеки асинхронного веб-сервера
Мы создадим веб-сервер с использованием следующих библиотек:
Вы можете установить эти библиотеки через менеджер библиотек Arduino. Откройте менеджер библиотек, нажав на значок библиотеки на левой боковой панели.
Найдите ESPAsyncWebServer и установите ESPAsyncWebServer от ESP32Async.
Затем установите библиотеку AsyncTCP. Найдите AsyncTCP и установите AsyncTCP от ESP32Async.
Код
Следующий код управляет яркостью встроенного светодиода ESP32 с помощью слайдера на веб-сервере. Другими словами, вы можете изменять скважность ШИМ с помощью слайдера. Это может быть полезно для управления яркостью светодиода или, например, для управления сервоприводом.
Скопируйте код в вашу Arduino IDE. Вставьте свои сетевые учётные данные, и код заработает сразу.
/*********
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/esp32-web-server-slider-pwm/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*********/
// Import required libraries
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
const int output = 2;
String sliderValue = "0";
// setting PWM properties
const int freq = 5000;
const int ledChannel = 0;
const int resolution = 8;
const char* PARAM_INPUT = "value";
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>ESP Web Server</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; }
</style>
</head>
<body>
<h2>ESP Web Server</h2>
<p><span id="textSliderValue">%SLIDERVALUE%</span></p>
<p><input type="range" onchange="updateSliderPWM(this)" id="pwmSlider" min="0" max="255" value="%SLIDERVALUE%" step="1" class="slider"></p>
<script>
function updateSliderPWM(element) {
var sliderValue = document.getElementById("pwmSlider").value;
document.getElementById("textSliderValue").textContent = sliderValue;
console.log(sliderValue);
var xhr = new XMLHttpRequest();
xhr.open("GET", "/slider?value="+sliderValue, true);
xhr.send();
}
</script>
</body>
</html>
)rawliteral";
// Replaces placeholder with button section in your web page
String processor(const String& var){
//Serial.println(var);
if (var == "SLIDERVALUE"){
return sliderValue;
}
return String();
}
void setup(){
// Serial port for debugging purposes
Serial.begin(115200);
// configure LED PWM functionalitites
ledcAttachChannel(output, freq, resolution, ledChannel);
ledcWrite(output, sliderValue.toInt());
// Connect to Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
// Print ESP Local IP Address
Serial.println(WiFi.localIP());
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/html", index_html, processor);
});
// Send a GET request to <ESP_IP>/slider?value=<inputMessage>
server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputMessage;
// GET input1 value on <ESP_IP>/slider?value=<inputMessage>
if (request->hasParam(PARAM_INPUT)) {
inputMessage = request->getParam(PARAM_INPUT)->value();
sliderValue = inputMessage;
ledcWrite(output, sliderValue.toInt());
}
else {
inputMessage = "No message sent";
}
Serial.println(inputMessage);
request->send(200, "text/plain", "OK");
});
// Start server
server.begin();
}
void loop() {
}
Как работает код
Продолжите чтение, чтобы узнать, как работает код, или перейдите к следующему разделу.
Импорт библиотек
Сначала импортируем необходимые библиотеки. Библиотеки WiFi, ESPAsyncWebServer и ESPAsyncTCP необходимы для создания веб-сервера.
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
Настройка сетевых учётных данных
Вставьте свои сетевые учётные данные в следующие переменные, чтобы ESP32 мог подключиться к вашей локальной сети.
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
Определение переменных
Мы будем управлять яркостью встроенного светодиода ESP32. Встроенный светодиод соответствует GPIO 2. Сохраните GPIO, которым вы хотите управлять, в переменной output.
Переменная sliderValue будет хранить значение слайдера. При запуске она установлена в ноль.
String sliderValue = "0";
Настройка свойств ШИМ
Следующие строки определяют свойства ШИМ для управления светодиодом.
// setting PWM properties
const int freq = 5000;
const int ledChannel = 0;
const int resolution = 8;
Мы будем использовать 8-битное разрешение, что означает, что вы можете управлять яркостью светодиода, используя значение от 0 до 255.
Чтобы узнать больше о свойствах ШИМ с ESP32, прочитайте наше руководство: ESP32 PWM с Arduino IDE (Аналоговый выход).
Входные параметры
Переменная PARAM_INPUT будет использоваться для «поиска» значения слайдера в запросе, полученном ESP32 при перемещении слайдера. (Помните: ESP32 получит запрос вида GET/slider?value=SLIDERVALUE)
const char* PARAM_INPUT = "value";
Она будет искать value в URL и получать присвоенное ему значение.
Создание веб-страницы
Теперь перейдём к странице веб-сервера.
Веб-страница для этого проекта довольно проста. Она содержит один заголовок, один абзац и один элемент ввода типа range.
Давайте посмотрим, как создаётся веб-страница.
Весь HTML-текст со стилями хранится в переменной index_html. Теперь мы рассмотрим HTML-текст и посмотрим, что делает каждая часть.
Следующий тег <meta> делает вашу веб-страницу адаптивной в любом браузере.
<meta name="viewport" content="width=device-width, initial-scale=1">
Между тегами <title> </title> размещается заголовок нашего веб-сервера. Заголовок – это текст, который отображается на вкладке веб-браузера.
Стили
Между тегами <style></style> мы добавляем CSS для стилизации веб-страницы.
<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; }
</style>
По сути, мы настраиваем HTML-страницу для отображения текста шрифтом Arial в блочном режиме без отступов и с выравниванием по центру.
html {font-family: Arial; display: inline-block; text-align: center;}
Следующие строки задают размер шрифта для заголовка (h2) и абзаца (p).
h2 {font-size: 2.3rem;}
p {font-size: 1.9rem;}
Установка свойств тела HTML-документа.
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; }
Тело HTML
Внутри тегов <body></body> мы добавляем содержимое веб-страницы.
Теги <h2></h2> добавляют заголовок на веб-страницу. В данном случае – текст «ESP Web Server», но вы можете добавить любой другой текст.
<h2>ESP Web Server</h2>
Первый абзац будет содержать текущее значение слайдера. Этому конкретному HTML-тегу присвоен id textSliderValue, чтобы мы могли ссылаться на него позже.
<p><span id="textSliderValue">%SLIDERVALUE%</span></p>
%SLIDERVALUE% – это заполнитель для значения слайдера. Он будет заменён ESP32 на фактическое значение при отправке его в браузер. Это полезно для отображения текущего значения при первом доступе к браузеру.
Создание слайдера
Для создания слайдера в HTML используется тег <input>. Тег <input> определяет поле, в которое пользователь может вводить данные.
Существует множество типов ввода. Для определения слайдера используйте атрибут «type» со значением «range». В слайдере также необходимо определить минимальный и максимальный диапазон с помощью атрибутов «min» и «max» (в данном случае 0 и 255 соответственно).
<p><input type="range" onchange="updateSliderPWM(this)" id="pwmSlider" min="0" max="255" value="%SLIDERVALUE%" step="1" class="slider"></p>
Вам также нужно определить другие атрибуты:
атрибут step определяет интервал между допустимыми числами. В нашем случае он установлен в 1;
class для стилизации слайдера (class=»slider»);
id для обновления текущей позиции, отображаемой на веб-странице;
атрибут onchange для вызова функции (updateSliderPWM(this)), которая отправляет HTTP-запрос к ESP32 при перемещении слайдера. Ключевое слово this ссылается на текущее значение слайдера.
Добавление JavaScript в HTML-файл
Далее вам нужно добавить JavaScript-код в ваш HTML-файл, используя теги <script> и </script>. Нужно добавить функцию updateSliderPWM(), которая будет отправлять запрос к ESP32 с текущим значением слайдера.
<script>
function updateSliderPWM(element) {
var sliderValue = document.getElementById("pwmSlider").value;
document.getElementById("textSliderValue").textContent = sliderValue;
console.log(sliderValue);
var xhr = new XMLHttpRequest();
xhr.open("GET", "/slider?value="+sliderValue, true);
xhr.send();
}
</script>
Следующая строка получает текущее значение слайдера по его id и сохраняет его в JavaScript-переменной sliderValue. Ранее мы присвоили слайдеру id pwmSlider. Поэтому мы получаем его следующим образом:
var sliderValue = document.getElementById("pwmSlider").value;
После этого мы устанавливаем метку слайдера (id которой textSliderValue) равной значению, сохранённому в переменной sliderValue.
Наконец, выполняем HTTP GET запрос.
var xhr = new XMLHttpRequest();
xhr.open("GET", "/slider?value="+sliderValue, true);
xhr.send();
Например, когда слайдер установлен на 0, выполняется HTTP GET запрос по следующему URL:
http://ESP-IP-ADDRESS/slider?value=0
А когда значение слайдера равно 200, запрос будет по следующему URL:
http://ESP-IP-ADDRESS/slider?value=200
Таким образом, когда ESP32 получает GET-запрос, он может извлечь параметр value из URL и соответствующим образом управлять ШИМ-сигналом, как мы увидим в следующих разделах.
Процессор
Теперь нам нужно создать функцию processor(), которая заменит заполнители в нашем HTML-тексте текущим значением слайдера при первом доступе к нему через браузер.
// Replaces placeholder with button section in your web page
String processor(const String& var){
//Serial.println(var);
if (var == "SLIDERVALUE"){
return sliderValue;
}
return String();
}
При запросе веб-страницы мы проверяем, содержит ли HTML какие-либо заполнители. Если находится заполнитель %SLIDERVALUE%, мы возвращаем значение, сохранённое в переменной sliderValue.
setup()
В setup() инициализируем Serial Monitor для отладки.
Serial.begin(115200);
Настраиваем LEDC-пин с ранее определёнными свойствами ШИМ.
// configure LED PWM functionalitites
ledcAttachChannel(output, freq, resolution, ledChannel);
Устанавливаем скважность ШИМ-сигнала равной значению, сохранённому в sliderValue (при запуске ESP32 оно установлено в 0).
ledcWrite(output, sliderValue.toInt());
Подключаемся к локальной сети и выводим IP-адрес ESP32.
// Connect to Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
// Print ESP Local IP Address
Serial.println(WiFi.localIP());
Обработка запросов
Наконец, добавьте следующие строки кода для обработки веб-сервером запросов.
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html, processor);
});
// Send a GET request to <ESP_IP>/slider?value=<inputMessage>
server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputMessage;
// GET input1 value on <ESP_IP>/slider?value=<inputMessage>
if (request->hasParam(PARAM_INPUT)) {
inputMessage = request->getParam(PARAM_INPUT)->value();
sliderValue = inputMessage;
ledcWrite(output, sliderValue.toInt());
}
else {
inputMessage = "No message sent";
}
Serial.println(inputMessage);
request->send(200, "text/plain", "OK");
});
Когда мы делаем запрос по корневому URL, мы отправляем HTML-текст, хранящийся в переменной index_html. Нам также нужно передать функцию processor, которая заменит все заполнители правильными значениями.
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html, processor);
});
Нам нужен ещё один обработчик, который сохранит текущее значение слайдера и установит яркость светодиода соответственно.
server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputMessage;
// GET input1 value on <ESP_IP>/slider?value=<inputMessage>
if (request->hasParam(PARAM_INPUT)) {
inputMessage = request->getParam(PARAM_INPUT)->value();
sliderValue = inputMessage;
ledcWrite(output, sliderValue.toInt());
}
else {
inputMessage = "No message sent";
}
Serial.println(inputMessage);
request->send(200, "text/plain", "OK");
});
По сути, мы получаем значение слайдера в следующих строках:
if (request->hasParam(PARAM_INPUT)) {
inputMessage = request->getParam(PARAM_INPUT)->value();
sliderValue = inputMessage;
Затем обновляем яркость светодиода (скважность ШИМ) с помощью функции ledcWrite(), которая принимает в качестве аргументов LEDC-пин, которым вы хотите управлять, и значение.
ledcWrite(output, sliderValue.toInt());
Наконец, запускаем сервер.
server.begin();
Поскольку это асинхронный веб-сервер, нам не нужно ничего писать в loop().
void loop(){
}
Вот так, в основном, работает код.
Загрузка кода
Теперь загрузите код на ваш ESP32. Убедитесь, что вы выбрали правильную плату и COM-порт.
После загрузки откройте Serial Monitor на скорости 115200 бод. Нажмите кнопку сброса ESP32. IP-адрес ESP32 должен отобразиться в Serial Monitor.
Демонстрация веб-сервера
Откройте браузер и введите IP-адрес ESP32. Ваш веб-сервер должен отобразить слайдер и его текущее значение.
Переместите слайдер и наблюдайте, как встроенный светодиод ESP32 увеличивает и уменьшает свою яркость.
Заключение
В этом руководстве вы узнали, как добавить слайдер в ваши проекты веб-серверов и получить и сохранить его значение в переменной, которую ESP32 может использовать. В качестве примера мы управляем ШИМ-сигналом для изменения яркости светодиода. Вместо светодиода вы можете управлять, например, сервоприводом.
Кроме того, слайдер может быть использован для установки порогового значения или любого другого значения, которое нужно настроить и затем использовать ESP32 для принятия решений.
Если вы используете плату ESP8266, прочитайте ESP8266 NodeMCU веб-сервер со слайдером для управления яркостью светодиода (ШИМ).
Надеемся, что этот проект оказался для вас полезным. Вам также могут понравиться следующие руководства:
Узнайте больше об ESP32 с нашими ресурсами:
Источник: ESP32 Web Server with Slider: Control LED Brightness (PWM)