Найти тему
Электроника, ESP32, Arduino

Как создать крутую WEB-морду (WebSocket Server)

Достоинства управления самоделками через WEB-интерфейс внутри локальной сети очевидны - подойдет любое устройство с WEB браузером, который находится в той-же сети. Единственная проблема - обновление WEB странички с элементами управления если она уже открыта, а этот момент поуправляли с другого устройства или вообще локально. Её решению и будет посвящена эта статья.

В среде Arduino IDE должна быть установлена поддержка плат ESP32.

Под версию 2.X.X. данный пример не "собирается". И две библиотеки вы (найдете их в примерах к этой статье).

AsyncTCP.h
ESPAsyncWebServer.h

Для примера из этой статьи потребуется плата ESP32 и 2 кнопки.

Схема прототипа
Схема прототипа

Управлять будем встроенным светодиодом (D2). Белая кнопка гасит светодиод, красная зажигает.

Прототип на макетной плате
Прототип на макетной плате

Да, можно было бы обойтись и одной кнопкой - но тогда пришлось бы добавить в код процедуру "антидребзга", а статья у нас про WEB интерфейс, а не про борьбу с дребезгом контактов. Для любого примера - чем он проще, тем легче разобраться.

Процедура управления светодиодом с помощью 2-х кнопок.
Процедура управления светодиодом с помощью 2-х кнопок.

Добавим сюда WEB интерфейс для возможности управления светодиодом через браузер. Смотрите скетч 02_WEB_SERVER

Управление светодиодом с помощью кнопок и WEB интерфейса
Управление светодиодом с помощью кнопок и WEB интерфейса

Сложного в этом коде ничего нет. Кнопками меняется состояние выхода (2) к которому подключен встроенный светодиод. Состояние переключателя в WEB-интерфейсе отображается при загрузке веб страницы в зависимости от состояния выхода (2)

buttons += "<h4>Output - GPIO 2</h4><label class=\"switch\"><input type=\"checkbox\" onchange=\"toggleCheckbox(this)\" id=\"2\" " + outputState(2) + "><span class=\"slider\"></span></label>";

Функция для отрисовки переключателя на WEB странице
Функция для отрисовки переключателя на WEB странице

Состояние светодиода можно также поменять нажав на переключатель на WEB странице - за это отвечает функция на языке JavaScript.

Функция отвечающая за изменение состояния светодиода.
Функция отвечающая за изменение состояния светодиода.

Код автор данной статьи "украл" (как любят писать мои комментаторы) из этой статьи видоизменив его для возможности работы параллельно с кнопками.

ESP32 Async Web Server – Control Outputs with Arduino IDE (ESPAsyncWebServer library)

Все тонкости его работы можно прочитать в ней, а всем, кто кроме слова украл знает еще какие то другие слова предлагаю механизм для исправления главного недостатка такого решения:

Если нажать кнопку для включения светодиода на макетке (или переключателе открытой копии WEB интерфейса на другом устройстве) то для управления со смартфона придется обновлять WEB страницу - прежде чем получится снова его выключить.

Светодиод был включен с помощью кнопки - состояние переключателя не изменилось.
Светодиод был включен с помощью кнопки - состояние переключателя не изменилось.

Самым простым решением для обновления состояния переключателя, будет включение в код WEB страницы функции которая например 1 раз в секунду будет обновлять её - но такое решение достаточно "топорное", так как мы будем постоянно гонять по сети лишний трафик.

Есть более изящное решение - использовать протокол связи WebSocket. В таком случае все клиенты могут быть уведомлены, когда происходят изменения, и соответствующим образом обновлять веб-страницу без необходимости каких-либо действий со стороны пользователя.

WebSocket — это постоянное соединение между клиентом и сервером, которое обеспечивает двунаправленную связь между обеими сторонами с использованием TCP-соединения. Вы можете отправлять данные с клиента на сервер и с сервера на клиент в любой момент времени.

Клиент устанавливает соединение WebSocket с сервером посредством процесса, известного как рукопожатие WebSocket. Рукопожатие начинается с HTTP-запроса/ответа, что позволяет серверам обрабатывать HTTP-соединения, а также соединения WebSocket на одном и том же порту. После установления соединения клиент и сервер могут отправлять данные WebSocket в полнодуплексном режиме.

Используя протокол WebSockets, сервер (плата ESP32) может отправлять информацию клиенту или всем клиентам без запроса. Это также позволяет нам отправлять информацию в веб-браузер, когда происходит изменение.

Пример с управлением одним выходом будет уж совсем простой, поэтому добавим еще один светодиод на выход 23. Встроенный светодиод будет переключаться и с кнопок и с WEB-интерфейса, светодиод на PIN23 только с помощью WEB интерфейса.

Принципиальная электрическая схема 2.
Принципиальная электрическая схема 2.

Работа кода показана на этих гиф-картинках - файл (07_WEB_WebSocket_Server_Final.ino) в архиве к статье.

Управление встроенным светодиодом с помощью кнопок
Управление встроенным светодиодом с помощью кнопок
Управление встроенным светодиодом с помощью WEB интерфейса
Управление встроенным светодиодом с помощью WEB интерфейса

Теперь любой клиент (2 смартфона) подключенный к WEB серверу (ESP32) знает, что произошло переключение состояния светодиода, и отображает это изменение изменяя состояние переключателей.

Как это все запрограммировано?

После подачи питания ESP32 подключается к домашней сети, IP адрес можно посмотреть в мониторе порта Arduino IDE.

Подключение к сети Wi-Fi
Подключение к сети Wi-Fi

Маршрут для корневой страницы:

index.html
index.html

После вбивания IP-шника в WEB браузер, переключатели будут отрисованы в том состоянии в котором последний раз находились переменные:

bool swStateA
bool
swStateB

с помощью функции processor()

фрагмент функции отрисовывающий состояние переключателей
фрагмент функции отрисовывающий состояние переключателей

Далее, загруженная WEB страница устанавливает соединение по протоколу WebSocket - с помощью JavaScript.

-15

При нажатии в WEB морде переключателя отрабатывает функция

-16

Сообщения от этой функции обрабатываются сервером следующими строками кода

Обработка сообщений от клиента
Обработка сообщений от клиента

При этом происходит переключение состояний логических переменных и отправка сообщений всем остальным подключенным в данный момент клиентам notifyClients("swStateA");

-18

Клиент (WEB-страница) на котором ничего не нажимали обрабатывает это сообщение, с помощью кода на JavaScript встроенного в WEB страницу:

Изменение состояния переключателей.
Изменение состояния переключателей.

Таким образом, у нас нет необходимости обновлять всю WEB страницу - мы обновляем только состояние переключателей. Любые изменения видно сразу, и при этом не расходуется трафик в пустую.

Код этого примера достаточно корявый (например состоянием кнопок можно передать одним байтом и усе такое в том же духе) - но, он писался, как пример работы протокола WebSocket в ESP32 и надеюсь поможет Вам написать свою крутую WEB морду к вашему самодельному кастомному девайсу.

Обложка статьи.
Обложка статьи.

Примеры из статьи качайте по этой ссылке (не забудьте внести ваши учетные данные для подключения к домашнему W-Fi).

WEB_WebSocket_Server.zip

Оглавление канала доступно тут:

Всем удачи!