ESP32/ESP8266 Веб-сервер: Управление выходами с кнопкой-моменталкой

В этом руководстве показано, как создать веб-сервер с кнопкой, которая работает как моменталка (momentary switch) для дистанционного управления выходами ESP32 или ESP8266. Состояние выхода будет HIGH до тех пор, пока вы удерживаете кнопку на веб-странице. Как только вы её отпустите, состояние изменится на LOW. В качестве примера мы будем управлять светодиодом, но вы можете управлять любым другим выходом.

ESP32 ESP8266 Веб-сервер управление выходами с кнопкой-моменталкой Arduino IDE

Платы ESP32/ESP8266 будут программироваться с помощью Arduino IDE. Убедитесь, что у вас установлены эти платы:

Обзор проекта

На следующей диаграмме показан простой обзор проекта, который мы создадим.

Обзор проекта веб-сервера с кнопкой-моменталкой ESP32 ESP8266
  • ESP32 или ESP8266 размещает веб-сервер, к которому вы можете обратиться для управления выходом;

  • Состояние выхода по умолчанию – LOW, но вы можете изменить его в зависимости от вашего проекта;

  • На странице есть кнопка, которая работает как моменталка:

    • если вы нажмёте кнопку, состояние выхода изменится на HIGH на всё время, пока вы удерживаете кнопку;

    • как только кнопка будет отпущена, состояние выхода вернётся в LOW.

Установка библиотек – Async Web Server

Для создания веб-сервера вам необходимо установить следующие библиотеки:

Вы можете установить эти библиотеки через Менеджер библиотек Arduino IDE. Перейдите в Sketch > Include Library > Manage Libraries и найдите библиотеки по названию.

Код

Скопируйте следующий код в Arduino IDE.

/*********
  Rui Santos & Sara Santos - Random Nerd Tutorials
  Complete project details at https://RandomNerdTutorials.com/esp32-esp8266-web-server-outputs-momentary-switch/
  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.
*********/

#ifdef ESP32
  #include <WiFi.h>
  #include <AsyncTCP.h>
#else
  #include <ESP8266WiFi.h>
  #include <ESPAsyncTCP.h>
#endif
#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;

// HTML web page
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
  <head>
    <title>ESP Pushbutton Web Server</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
      body { font-family: Arial; text-align: center; margin:0px auto; padding-top: 30px;}
      .button {
        padding: 10px 20px;
        font-size: 24px;
        text-align: center;
        outline: none;
        color: #fff;
        background-color: #2f4468;
        border: none;
        border-radius: 5px;
        box-shadow: 0 6px #999;
        cursor: pointer;
        -webkit-touch-callout: none;
        -webkit-user-select: none;
        -khtml-user-select: none;
        -moz-user-select: none;
        -ms-user-select: none;
        user-select: none;
        -webkit-tap-highlight-color: rgba(0,0,0,0);
      }
      .button:hover {background-color: #1f2e45}
      .button:active {
        background-color: #1f2e45;
        box-shadow: 0 4px #666;
        transform: translateY(2px);
      }
    </style>
  </head>
  <body>
    <h1>ESP Pushbutton Web Server</h1>
    <button class="button" onmousedown="toggleCheckbox('on');" ontouchstart="toggleCheckbox('on');" onmouseup="toggleCheckbox('off');" ontouchend="toggleCheckbox('off');">LED PUSHBUTTON</button>
   <script>
   function toggleCheckbox(x) {
     var xhr = new XMLHttpRequest();
     xhr.open("GET", "/" + x, true);
     xhr.send();
   }
  </script>
  </body>
</html>)rawliteral";

void notFound(AsyncWebServerRequest *request) {
  request->send(404, "text/plain", "Not found");
}

AsyncWebServer server(80);

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("WiFi Failed!");
    return;
  }
  Serial.println();
  Serial.print("ESP IP Address: http://");
  Serial.println(WiFi.localIP());

  pinMode(output, OUTPUT);
  digitalWrite(output, LOW);

  // Send web page to client
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(200, "text/html", index_html);
  });

  // Receive an HTTP GET request
  server.on("/on", HTTP_GET, [] (AsyncWebServerRequest *request) {
    digitalWrite(output, HIGH);
    request->send(200, "text/plain", "ok");
  });

  // Receive an HTTP GET request
  server.on("/off", HTTP_GET, [] (AsyncWebServerRequest *request) {
    digitalWrite(output, LOW);
    request->send(200, "text/plain", "ok");
  });

  server.onNotFound(notFound);
  server.begin();
}

void loop() {

}

Исходный код на GitHub

Вам нужно только ввести ваши сетевые данные (SSID и пароль), и веб-сервер заработает сразу. Код совместим с обеими платами – ESP32 и ESP8266 – и управляет встроенным светодиодом на GPIO 2. Вы можете изменить код для управления любым другим GPIO.

Как работает код

Мы уже подробно объясняли работу подобных веб-серверов в предыдущих руководствах (Веб-сервер с датчиком температуры DHT), поэтому рассмотрим только ключевые части для этого проекта.

Сетевые данные

Как уже упоминалось, вам нужно вставить ваши сетевые данные в следующие строки:

const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

Кнопка-моменталка (веб-сервер)

Следующая строка создаёт кнопку-моменталку.

<button class="button" onmousedown="toggleCheckbox('on');" ontouchstart="toggleCheckbox('on');" onmouseup="toggleCheckbox('off');" ontouchend="toggleCheckbox('off');">LED PUSHBUTTON</button>

Разберём это на составные части.

В HTML для создания кнопки используются теги <button></button>. Между ними вы пишете текст кнопки. Например:

<button>LED PUSHBUTTON</button>

Кнопка может иметь несколько атрибутов. В HTML атрибуты предоставляют дополнительную информацию об элементах HTML – в данном случае о кнопке.

Здесь мы используем следующие атрибуты:

class: предоставляет имя класса для кнопки. Это позволяет использовать его в CSS или JavaScript для выполнения определённых задач с кнопкой. В данном случае он используется для оформления кнопки через CSS. Атрибут class имеет значение «button», но вы могли бы назвать его как угодно.

<button class="button">LED PUSHBUTTON</button>

onmousedown: это атрибут события. Он выполняет функцию JavaScript при нажатии кнопки. В данном случае вызывается toggleCheckbox('on'). Эта функция отправляет запрос к ESP32/ESP8266 по определённому URL, чтобы сообщить о необходимости изменить состояние выхода на HIGH.

ontouchstart: это атрибут события, аналогичный предыдущему, но он работает для устройств с сенсорным экраном, таких как смартфон или планшет. Он вызывает ту же функцию JavaScript для изменения состояния выхода на HIGH.

onmouseup: это атрибут события, который выполняет функцию JavaScript при отпускании кнопки мыши над кнопкой. В данном случае вызывается toggleCheckbox('off'). Эта функция отправляет запрос к ESP32/ESP8266 по определённому URL, чтобы сообщить о необходимости изменить состояние выхода на LOW.

ontouchend: аналогичен предыдущему атрибуту, но для устройств с сенсорным экраном.

В итоге наша кнопка выглядит так:

<button class="button" onmousedown="toggleCheckbox('on');" ontouchstart="toggleCheckbox('on');" onmouseup="toggleCheckbox('off');" ontouchend="toggleCheckbox('off');">LED PUSHBUTTON</button>

HTTP GET-запрос для изменения состояния кнопки (JavaScript)

Ранее мы видели, что при нажатии или отпускании кнопки вызывается функция toggleCheckbox(). Вы передаёте аргумент «on» или «off» в зависимости от нужного состояния.

Эта функция отправляет HTTP-запрос к ESP32 по URL /on или /off:

function toggleCheckbox(x) {
  var xhr = new XMLHttpRequest();
  xhr.open("GET", "/" + x, true);
  xhr.send();
}

Обработка запросов

Далее нужно обработать, что происходит, когда ESP32 или ESP8266 получает запросы по этим URL.

Когда получен запрос по URL /on, мы включаем GPIO (HIGH), как показано ниже:

server.on("/on", HTTP_GET, [] (AsyncWebServerRequest *request) {
  digitalWrite(output, HIGH);
  request->send(200, "text/plain", "ok");
});

Когда получен запрос по URL /off, мы выключаем GPIO (LOW):

server.on("/off", HTTP_GET, [] (AsyncWebServerRequest *request) {
  digitalWrite(output, LOW);
  request->send(200, "text/plain", "ok");
});

Демонстрация

Загрузите код на плату ESP32 или ESP8266.

Затем откройте монитор порта со скоростью 115200 бод. Нажмите встроенную кнопку EN/RST, чтобы получить IP-адрес.

ESP32 ESP8266 демонстрация веб-сервера IP-адрес в мониторе порта Arduino IDE

Откройте браузер в вашей локальной сети и введите IP-адрес ESP. Вы должны увидеть веб-сервер, как показано ниже.

Веб-сервер с кнопкой-моменталкой ESP32 и ESP8266 демонстрация Arduino IDE

Встроенный светодиод горит до тех пор, пока вы удерживаете кнопку на веб-странице.

Примечание: для ESP8266 это работает наоборот, потому что встроенный светодиод работает с инвертированной логикой.

Встроенный светодиод ESP32 включён HIGH

Когда вы отпускаете кнопку, светодиод возвращается в состояние по умолчанию (LOW).

Встроенный светодиод ESP32 выключен LOW

Заключение

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

Другие проекты, которые могут вас заинтересовать:

Узнайте больше о ESP32 и ESP8266 из наших ресурсов:

Примечание

Данная статья является переводом оригинальной статьи с сайта Random Nerd Tutorials. Все права на оригинальный контент принадлежат авторам – Rui Santos и Sara Santos.