Каталог

ESP32 Веб-сервер с ползунком: управление яркостью светодиода (ШИМ)

В этом уроке показано, как создать веб-сервер на 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 для принятия решения.

Комментарии
Отзывов еще никто не оставлял
Предзаказ
Предзаказ успешно отправлен!
Имя *
Телефон *
Добавить в корзину
Название товара
100 тг
1 шт.
Перейти в корзину
Обратный звонок
Запрос успешно отправлен!
Имя *
Телефон *
Заказ в один клик
С помощью уведомлений о заказе можно не только получать актуальную информацию по заказу, но и иметь быстрый канал связи с магазином