В этом уроке показано, как создать веб-сервер на ESP32 с ползунком для управления яркостью светодиода. Вы узнаете, как добавить ползунок в свои проекты веб-сервера, получить его значение и сохранить его в переменной, которую сможет использовать ESP32. Мы будем использовать это значение для управления коэффициентом заполнения ШИМ-сигнала и изменения яркости светодиода. Вместо светодиода вы можете управлять, например, сервоприводом.
ESP32 Веб-сервер с ползунком для управления яркостью светодиода (ШИМ) с использованием Arduino IDE Обновлено 11 июня 2024
Кроме того, вы можете изменить код в этом уроке, чтобы добавить ползунок в свои проекты для установки порогового значения или любого другого значения, которое вам нужно использовать в коде.
Обзор проекта

- ESP32 размещает веб-сервер, который отображает веб-страницу с ползунком.
- Когда вы перемещаете ползунок, вы отправляете HTTP-запрос на ESP32 с новым значением ползунка.
- HTTP-запрос имеет следующий формат: GET/slider?value=SLIDERVALUE, где SLIDERVALUE — это число от 0 до 255. Вы можете изменить ползунок, чтобы включить любой другой диапазон.
- Из HTTP-запроса ESP32 получает текущее значение ползунка.
- ESP32 настраивает коэффициент заполнения ШИМ в соответствии с значением ползунка.
- Это может быть полезно для управления яркостью светодиода (как в этом примере), сервопривода, настройки порогового значения или других приложений.
Необходимые компоненты
Перед началом работы с проектом убедитесь, что у вас установлены следующие компоненты.
Arduino IDE
Мы будем программировать платы ESP32 с использованием Arduino IDE, поэтому перед началом урока убедитесь, что плата ESP32 установлена в вашем Arduino IDE.
Библиотеки для асинхронного веб-сервера
Мы создадим веб-сервер с использованием следующих библиотек:
- ESPAsyncWebServer
- AsyncTCP
Эти библиотеки недоступны для установки через диспетчер библиотек Arduino, поэтому вам нужно скопировать файлы библиотек в папку Libraries вашей установки Arduino. Альтернативно, в Arduino IDE вы можете перейти в Sketch > Include Library > Add .zip Library и выбрать только что загруженные библиотеки.
Код
Следующий код управляет яркостью встроенного светодиода ESP32 с помощью ползунка на веб-сервере. Другими словами, вы можете изменять коэффициент заполнения ШИМ с помощью ползунка. Это может быть полезно для управления яркостью светодиода или сервоприводом, например.
Скопируйте код в ваш Arduino IDE. Вставьте свои сетевые учетные данные, и код сразу заработает.
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
// Замените на ваши сетевые учетные данные
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
const int output = 2;
String sliderValue = "0";
// Настройка параметров ШИМ
const int freq = 5000;
const int ledChannel = 0;
const int resolution = 8;
const char* PARAM_INPUT = "value";
// Создание объекта AsyncWebServer на порту 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").innerHTML = sliderValue;
console.log(sliderValue);
var xhr = new XMLHttpRequest();
xhr.open("GET", "/slider?value="+sliderValue, true);
xhr.send();
}
</script>
</body>
</html>
)rawliteral;
// Заменяет заполнители на странице вашего веб-сервера
String processor(const String& var) {
if (var == "SLIDERVALUE") {
return sliderValue;
}
return String();
}
void setup() {
// Последовательный порт для отладки
Serial.begin(115200);
// Настройка функций ШИМ светодиода
ledcAttachChannel(output, freq, resolution, ledChannel);
ledcWrite(output, sliderValue.toInt());
// Подключение к Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Подключение к WiFi..");
}
// Печать локального IP-адреса ESP
Serial.println(WiFi.localIP());
// Маршрут для корневой / веб-страницы
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request-send_P(200, "text/html", index_html, processor);
});
// Отправить GET-запрос на /slider?value=
server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputMessage;
if (request-hasParam(PARAM_INPUT)) {
inputMessage = request-getParam(PARAM_INPUT)-value();
sliderValue = inputMessage;
ledcWrite(output, sliderValue.toInt());
} else {
inputMessage = "Сообщение не отправлено";
}
Serial.println(inputMessage);
request-send(200, "text/plain", "OK");
});
// Запуск сервера
server.begin();
}
void loop() {
}
Как работает код
Продолжайте чтение, чтобы узнать, как работает код.
Импорт библиотек
Сначала импортируйте необходимые библиотеки. Библиотеки WiFi, ESPAsyncWebServer и AsyncTCP необходимы для создания веб-сервера.
#include <WiFi.h>
#include <AsyncTCP.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";
Настройка свойств ШИМ
Следующие строки определяют свойства ШИМ для управления светодиодом.
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 name="viewport" content="width=device-width, initial-scale=1">
Вам также нужно определить другие атрибуты, такие как:
- Атрибут
step
указывает интервал между допустимыми числами. В нашем случае он установлен на 1. - Класс для стилизации ползунка (class="slider").
- Идентификатор для обновления текущей позиции, отображаемой на веб-странице.
- Атрибут
onchange
для вызова функции (updateSliderPWM(this)
), которая отправляет HTTP-запрос на ESP32 при перемещении ползунка. Ключевое словоthis
ссылается на текущее значение ползунка.
Добавление JavaScript в HTML-файл
Далее, вам нужно добавить немного JavaScript-кода в ваш HTML-файл с использованием тегов <script>
и </script>
. Вам нужно добавить функцию updateSliderPWM()
, которая будет отправлять запрос на ESP32 с текущим значением ползунка.
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;}
Основное, что мы делаем, это устанавливаем, чтобы текст на 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-тег имеет назначенный ему идентификатор 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="slider").
- Идентификатор для обновления текущей позиции, отображаемой на веб-странице.
- Атрибут
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").innerHTML = sliderValue;
console.log(sliderValue);
var xhr = new XMLHttpRequest();
xhr.open("GET", "/slider?value=" + sliderValue, true);
xhr.send();
}
</script>
Эта строка получает текущее значение ползунка по его идентификатору и сохраняет его в переменной JavaScript sliderValue
. Ранее мы присвоили ползунку идентификатор pwmSlider
. Поэтому мы получаем его следующим образом:
var sliderValue = document.getElementById("pwmSlider").value;
Затем мы устанавливаем метку ползунка (чей идентификатор 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
Теперь нам нужно создать функцию processor()
, которая заменит заполнители в нашем HTML-тексте на текущее значение ползунка, когда вы впервые откроете его в браузере.
// Заменяет заполнители на странице вашего веб-сервера
String processor(const String& var){
if (var == "SLIDERVALUE"){
return sliderValue;
}
return String();
}
Когда веб-страница запрашивается, мы проверяем, есть ли в HTML заполнители. Если он находит заполнитель %SLIDERVALUE%
, мы возвращаем значение, сохраненное в переменной sliderValue
.
setup()
В функции setup()
инициализируем Серийный монитор для целей отладки.
Serial.begin(115200);
Настраиваем пин светодиода с функциями ШИМ, определенными ранее.
// Настройка функций ШИМ светодиода
ledcAttachChannel(output, freq, resolution, ledChannel);
Устанавливаем коэффициент заполнения ШИМ-сигнала на значение, сохраненное в переменной sliderValue
(при старте ESP32 установлено значение 0).
ledcWrite(output, sliderValue.toInt());
Подключаемся к локальной сети и печатаем IP-адрес ESP32.
// Подключение к Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Подключение к WiFi..");
}
// Печать локального IP-адреса ESP
Serial.println(WiFi.localIP());
Обработка запросов
Наконец, добавьте следующие строки кода для обработки веб-сервера.
// Маршрут для корневой / веб-страницы
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html, processor);
});
// Отправить GET-запрос на <ESP_IP>/slider?value=<inputMessage>
server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputMessage;
if (request->hasParam(PARAM_INPUT)) {
inputMessage = request->getParam(PARAM_INPUT)->value();
sliderValue = inputMessage;
ledcWrite(output, sliderValue.toInt());
}
else {
inputMessage = "Сообщение не отправлено";
}
Serial.println(inputMessage);
request->send(200, "text/plain", "OK");
});
Когда мы делаем запрос по корневому URL, мы отправляем HTML-текст, который хранится в переменной index_html
. Мы также должны передать функцию processor
, которая заменит все заполнители на правильные значения.
// Маршрут для корневой / веб-страницы
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html, processor);
});
Нам нужен еще один обработчик, который сохранит текущее значение ползунка и установит яркость светодиода соответственно.
server.on("/slider", HTTP_GET, [](AsyncWebServerRequest *request) {
String inputMessage;
if (request->hasParam(PARAM_INPUT)) {
inputMessage = request->getParam(PARAM_INPUT)->value();
sliderValue = inputMessage;
ledcWrite(output, sliderValue.toInt());
}
else {
inputMessage = "Сообщение не отправлено";
}
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-порт.
После загрузки откройте Серийный монитор на скорости 115200 бод. Нажмите кнопку сброса на ESP32. IP-адрес ESP32 должен быть напечатан в серийном мониторе.
Демонстрация веб-сервера
Откройте браузер и введите IP-адрес ESP32. Ваш веб-сервер должен отобразить ползунок и его текущее значение.
Перемещайте ползунок и наблюдайте, как яркость встроенного светодиода ESP32 увеличивается и уменьшается.
Заключение
В этом уроке вы научились добавлять ползунок в свои проекты веб-сервера и получать и сохранять его значение в переменной, которую сможет использовать ESP32. В качестве примера мы управляем ШИМ-сигналом для управления яркостью светодиода. Вместо светодиода вы можете управлять, например, сервоприводом.
Кроме того, ползунок может использоваться для установки порогового значения или любого другого значения, которое вам нужно установить, а затем использовать ESP32 для принятия решения.