ESP8266 и Arduino IDE. Websockets.

Перевод статьи Мартина Карри (Martyn Currey), Опубликовано 24 .

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

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

Websockets

Websockets — это способ для сервера и клиента (сервер и веб-страница) свободно общаться друг с другом, и любая из сторон может отправлять данные в любое время (асинхронно), без запроса противоположной стороны. Они делают это, сохраняя открытое соединение в отличие от HTML и AJAX, которые создают новое соединение каждый раз, когда им что-то нужно. Websockets являются частью HTML 5, имеют Javascript API и работают во всех современных браузерах.

Websocket — это протокол, такой же, как HTML, и так же, как HTML, он находится поверх TCP. Попытка реализовать веб-сокеты самостоятельно может быть не благодарной, но благодаря работе Маркуса Саттлера, он же Links2004 ( Markus Sattler AKA Links2004), есть библиотека как раз для этого случая. Библиотека называется arduinoWebSockets и доступна с сайта Github: arduinoWebSockets или через менеджер библиотек Arduino.

менеджер библиотек

Обратите внимание на то, что для ESP используется версия библиотеки начиная с 2.х.х, а для AVR библиотека версии 1.3.

Использование библиотеки WebSockets

Как и в большинстве случаев, вам нужно сообщить компилятору, что вы хотите использовать библиотеку оператором include. Библиотека должна быть установлена первой, иначе вы получите ошибку “мы не знаем, чего вы хотите” (или что-то в этом роде).
#include "WebSocketsServer.h"
Затем вам нужно создать экземпляр/инициализировать его. Здесь мы используем сервер websocket на порту 81 (есть также клиент websocket, это другое).
WebSocketsServer WebSocket = WebSocketsServer(81);
В рамках функции setup() запустите сервер websocket.
WebSocket.begin();
WebSocket.onEvent(webSocketEvent);
и мы также должны настроить функцию onEvent.
WebSocket.onEvent(webSocketEvent);
WebSocket.onEvent() срабатывает всякий раз, когда что-то происходит с сервером websocket. Событие может быть одним из многих, таких как соединение, разъединение, ошибка или получение данных (есть еще несколько). В приведенных ниже примерах onEvent вызывает другую функцию webSocketEvent (вы можете использовать любое имя функции, которое пожелаете). Конечно, вам также будет нужна функция webSocketEvent ().
void webSocketEvent(byte num, WStype_t type, uint8_t * payload, size_t length)
{
  if(type == WStype_TEXT)
  {
      if (payload[0] == '0')
      {
          digitalWrite(pin_led, LOW);
          Serial.println("LED=off");        
      }
      else if (payload[0] == '1')
      {
          digitalWrite(pin_led, HIGH);
          Serial.println("LED=on");        
      }
  }
 
  else  // событие не является ТЕКСТОМ. Отображаем сведений только в последовательном мониторе
  {
    Serial.print("WStype = ");   Serial.println(type);  
    Serial.print("WS payload = ");
// поскольку payload является указателем, нам нужно ввести cast to char
    for(int i = 0; i < length; i++) { Serial.print((char) payload[i]); }
    Serial.println();
  }
}

В приведенных ниже примерах я использую ascii в качестве управляющих кодов; “1” для включения и “0” для выключения. Это означает, что мы используем текст, а ТЕКСТ-это один из типов событий. Если “type == WStype_TEXT”, то мы знаем, что получили некоторые текстовые данные. Ниже приводится краткое объяснение WStype_t. Когда есть какие-либо данные, их можно найти в полезной нагрузке.

Предупреждение: payload не является массивом символов. Это указатель на данные.

Если событие не является ТЕКСТОМ, то я отображаю детали на мониторе COM порта. Это на самом деле не требуется, но позволяет увидеть, что еще происходит (например, событие подключения или отключения).

num
num-текущий клиент/номер подключения/ID. Библиотека arduinoWebsocket позволяет одновременно использовать не более 5 файлов.

type
тип ответа:
0 – WStype_ERROR
1 – WStype_DISCONNECTED
2 – WStype_CONNECTED
3 – WStype_TEXT
4 – WStype_BIN
5 – WStype_FRAGMENT_TEXT_START
6 – WStype_FRAGMENT_BIN_START
7 – WStype_FRAGMENT
8 – WStype_FRAGMENT_FIN
9 – WStype_PING
10 — WStype_PONG

Вы можете видеть, что существует также тип данных BIN.

Если вы посмотрите на картинку последовательного монитора ниже, то увидите:
WStype = 2 – это событие подключения
WStype = 10 – PONG, ответ от ПИНГА
и не отображаемый будет WStype = 3 для ТЕКСТА. Поскольку мы используем символы ascii в качестве управляющих кодов, мы используем ТЕКСТ.

payload
payload — это полученные данные (когда есть полученные данные). Это указатель, а не массив char или char.

length — это размер данных.

Внутри функции main loop() нам нужно вызвать WebSocket.loop();

webSocket.loop();
В Примере 1 имеется только связь веб-страницы на сервер (ESP8266). Это означает, что серверу нужно только обработать управляющие коды на ESP8266. В Примере 2 мы добавляем локальное управление (переключатель на EPS8266), которое требует двусторонней связи и означает, что веб-страница (клиент) должна получать и обрабатывать данные Websocket. Это делается в Javascript в фоновом режиме. В Примере 2, используя Javascript websocket api, в функции Javascript init() событие onmessage настраивается для вызова функции processReceivedCommand (). Событие onmessage срабатывает всякий раз, когда поступают какие-либо данные.
function init() 
{
  Socket = new WebSocket('ws://' + window.location.hostname + ':81/');
  Socket.onmessage = function(event) { processReceivedCommand(event); };
}
function processReceivedCommand(evt) event и evt — это объекты javascript (evt-это копия event), которые, помимо прочего, содержат полученные данные. Данные извлекаются с помощью evt.data (oop). Когда данные получены, мы знаем, что переключатель кнопок на ESP8266 был использован (см. Пример 2), и поэтому метки и текст кнопок на веб-странице обновляются, чтобы отразить новое состояние светодиода.
{
    document.getElementById('rd').innerHTML = evt.data;
    if (evt.data ==='0') 
    {  
        document.getElementById('BTN_LED').innerHTML = 'Turn on the LED';  
        document.getElementById('LED_status').innerHTML = 'LED is off';  
    }
    if (evt.data ==='1') 
    {  
        document.getElementById('BTN_LED').innerHTML = 'Turn off the LED'; 
        document.getElementById('LED_status').innerHTML = 'LED is on';   
    }
}

Если получено “0”, это означает, что светодиод выключен. ” 1 » означает, что светодиод включен.

Подводя итог. Чтобы использовать websockets на ESP8266, вам нужно
– включить библиотеки
– инициализировать websocket
– запустить сервер
– отправить данные
– дождаться какого – то события, а затем обработать его. Это событие может быть связано с получением новых данных.

Вам нужно сделать в основном то же самое на веб – странице, но с помощью Javascript websockets api.
– создать новый объект websocket
– прикрепить функцию прослушивателя к событию сообщения websocket, чтобы вы могли что – то сделать с полученными данными
-отправить данные

Дополнительные сведения об API Javascript:
MDN Web Doc: Websocket
Tutorialspoint: HTML5 – WebSockets
linode: Введение в WebSockets

Более подробную информацию о библиотеке arduinoWebSockets можно найти на сайте github.

Пример 1: LED Control Basic

Первый пример пересматривает управление светодиодами и использует довольно простую реализацию websockets. У нас есть один светодиод и простой веб-интерфейс для его включения и выключения. Это почти то же самое, что и тогда, когда мы начали много постов назад. Разница теперь, конечно, в том, что мы управляем светодиодом с помощью websockets.

Для этого упражнения я использую плату Lolin NodeMCU V3, но любая плата ESP8266 должна работать так же.

Скриншот

Схема

Очень простая схема. Светодиод и резистор подключены к контакту D3 (не к контакту 3).

Скетч

/*
 * Sketch: ESP8266_Part9_01_Websocket_LED 
* Предназначен для запуска на ESP8266 */   String header = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";   String html_1 = R"=====( <!DOCTYPE html> <html> <head> <meta name='viewport' content='width=device-width, initial-scale=1.0'/> <meta charset='utf-8'> <style> body { font-size:120%;} #main { display: table; width: 300px; margin: auto; padding: 10px 10px 10px 10px; border: 3px solid blue; border-radius: 10px; text-align:center;} .button { width:200px; height:40px; font-size: 110%; } </style> <title>Websockets</title> </head> <body> <div id='main'> <h3>LED CONTROL</h3> <div id='content'> <p id='LED_status'>LED is off</p> <button id='BTN_LED'class="button">Turn on the LED</button> </div> <br /> </div> </body>   <script> var Socket; function init() { Socket = new WebSocket('ws://' + window.location.hostname + ':81/'); }   document.getElementById('BTN_LED').addEventListener('click', buttonClicked); function buttonClicked() { var btn = document.getElementById('BTN_LED') var btnText = btn.textContent || btn.innerText; if (btnText ==='Turn on the LED') { btn.innerHTML = "Turn off the LED"; document.getElementById('LED_status').innerHTML = 'LED is on'; sendText('1'); } else { btn.innerHTML = "Turn on the LED"; document.getElementById('LED_status').innerHTML = 'LED is off'; sendText('0'); } }   function sendText(data) { Socket.send(data); }   window.onload = function(e) { init(); } </script> </html> )=====";   #include <ESP8266WiFi.h> #include <WebSocketsServer.h>   WiFiServer server(80); WebSocketsServer webSocket = WebSocketsServer(81);   byte pin_led = D3;   char ssid[] = "ssid"; // use your own network ssid and password char pass[] = "pass";   void setup() { pinMode(pin_led, OUTPUT); digitalWrite(pin_led,LOW);   Serial.begin(115200); Serial.println(); Serial.println("Serial запущен на 115200"); Serial.println();   // Соединение с WiFi сетью Serial.print(F("Connecting to ")); Serial.println(ssid); WiFi.begin(ssid,pass);   // соединение int count = 0; while ( (WiFi.status() != WL_CONNECTED) && count < 17) { Serial.print("."); delay(500); count++; }   if (WiFi.status() != WL_CONNECTED) { Serial.println(""); Serial.print("Failed to connect to "); Serial.println(ssid); while(1); }   Serial.println(""); Serial.println(F("[CONNECTED]")); Serial.print("[IP "); Serial.print(WiFi.localIP()); Serial.println("]");   // запуск сервера server.begin(); Serial.println("Сервер запущен");   webSocket.begin(); webSocket.onEvent(webSocketEvent); }   void loop() { webSocket.loop();   WiFiClient client = server.available(); // Проверяем подключен ли клиент if (!client) { return; } // Если нет выходим   client.flush(); client.print( header ); client.print( html_1 ); Serial.println("Новая страница запущена");   delay(5); }   void webSocketEvent(byte num, WStype_t type, uint8_t * payload, size_t length) { if(type == WStype_TEXT) { if (payload[0] == '0') { digitalWrite(pin_led, LOW); Serial.println("LED=off"); } else if (payload[0] == '1') { digitalWrite(pin_led, HIGH); Serial.println("LED=on"); } }   else { Serial.print("WStype = "); Serial.println(type); Serial.print("WS payload = "); for(int i = 0; i < length; i++) { Serial.print((char) payload[i]); } Serial.println();   } }

Разберём скетч

Как и в предыдущих примерах, весь код веб-страницы содержится в строковой переменной html_1.

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

client.print( header );
client.print( html_1 ); 
Serial.println("Новая страница загружена");
подключаем библиотеки и инициируем экземпляры.
#include <ESP8266WiFi.h>
#include <WebSocketsServer.h>

СерверWiFiServer (80);
WebSocketsServer WebSocket = WebSocketsServer(81);
Попробуйте подключиться к локальной сети. Если вы проверяли другие руководствами, вы можете использовать дополнительный код. Здесь я добавил тайм-аут. Если соединение не может быть установлено примерно за 8 секунд (16 * 500 мс), скетч просто ничего не делает. Если попытка подключения успешна, на последовательном мониторе печатается сообщение о подключении вместе с IP-адресом ESP8266.
// соединение с таймаутом
  int count = 0; 
  while ( (WiFi.status() != WL_CONNECTED) && count < 17) 
  {
      Serial.print(".");  delay(500);  count++;
  }
 
  if (WiFi.status() != WL_CONNECTED)
  { 
     Serial.println("");  Serial.print("Failed to connect to ");  Serial.println(ssid);
     while(1);
  }
 
  Serial.println("");
  Serial.println(F("[CONNECTED]"));   Serial.print("[IP ");  Serial.print(WiFi.localIP()); 
  Serial.println("]");
После установления соединения запускаются сервера.
// start a server
server.begin();
Serial.println("Server started");
webSocket.begin();
webSocket.onEvent(webSocketEvent);
Скриншот

C этого момента ESP8266 подключен к сети, и сервер работает в ожидании чьего-то визита. Поэтому в выбранном вами веб-браузере (я использую Chrome) перейдите по ip-адресу, указанному на мониторе последовательного порта. Для меня это 192.168.2.107

Скриншот

Теперь мы можем волшебным образом управлять светодиодом простым щелчком пальца. Не совсем на уровне Таноса, но достаточно близко.

Скриншот
Скриншот
Скриншот

Здесь первый пример заканчивается.

Пример 2: Управление светодиодом двустороннее

Первый пример работает хорошо, но ничем не отличается от того, что мы делали много лет назад. Так что же такого особенного? Следующий шаг. Далее мы вводим двустороннюю связь с помощью Websockets.

В этом примере мы добавим кнопочный переключатель к ESP8266, чтобы обеспечить локальное управление светодиодом. Это означает, что мы сможем управлять светодиодом либо с помощью аппаратного переключателя, либо с помощью программного переключателя на веб-странице. Так почему же для этого нужны веб-сокеты? Websockets используются для того, чтобы позволить ESP8266 отправлять данные на веб-страницу, сообщая ей об изменении состояния светодиода. Затем веб-страница может обновить текст метки и кнопки, чтобы отразить новый статус светодиода.

Схема

GNDS и VCC подключены. Ты просто не видишь проводов!

Скетч

/*
 * Sketch: ESP8266_Part9_02_Websocket_LED_2Way
 * Intended to be run on an ESP8266
 */
 
String header = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";
 
String html_1 = R"=====(
<!DOCTYPE html>
<html>
<head>
  <meta name='viewport' content='width=device-width, initial-scale=1.0'/>
  <meta charset='utf-8'>
  <style>
    body     { font-size:120%;} 
    #main    { display: table; width: 300px; margin: auto;  padding: 10px 10px 10px 10px; border: 3px solid blue; border-radius: 10px; text-align:center;} 
    #BTN_LED { width:200px; height:40px; font-size: 110%;  }
    p        { font-size: 75%; }
  </style>
 
  <title>Websockets</title>
</head>
<body>
  <div id='main'>
    <h3>LED CONTROL</h3>
    <div id='content'>
      <p id='LED_status'>LED is off</p>
      <button id='BTN_LED'class="button">Turn on the LED</button>
    </div>
    <p>Recieved data = <span id='rd'>---</span> </p>
    <br />
   </div>
</body>
 
<script>
  var Socket;
  function init() 
  {
    Socket = new WebSocket('ws://' + window.location.hostname + ':81/');
    Socket.onmessage = function(event) { processReceivedCommand(event); };
  }
 
 
function processReceivedCommand(evt) 
{
    document.getElementById('rd').innerHTML = evt.data;
    if (evt.data ==='0') 
    {  
        document.getElementById('BTN_LED').innerHTML = 'Turn on the LED';  
        document.getElementById('LED_status').innerHTML = 'LED is off';  
    }
    if (evt.data ==='1') 
    {  
        document.getElementById('BTN_LED').innerHTML = 'Turn off the LED'; 
        document.getElementById('LED_status').innerHTML = 'LED is on';   
    }
}
 
 
  document.getElementById('BTN_LED').addEventListener('click', buttonClicked);
  function buttonClicked()
  {   
    var btn = document.getElementById('BTN_LED')
    var btnText = btn.textContent || btn.innerText;
    if (btnText ==='Turn on the LED') { btn.innerHTML = 'Turn off the LED'; document.getElementById('LED_status').innerHTML = 'LED is on';  sendText('1'); }  
    else                              { btn.innerHTML = 'Turn on the LED';  document.getElementById('LED_status').innerHTML = 'LED is off'; sendText('0'); }
  }
 
  function sendText(data)
  {
    Socket.send(data);
  }
 
 
  window.onload = function(e)
  { 
    init();
  }
</script>
 
 
</html>
)=====";
 
#include <ESP8266WiFi.h>
#include <WebSocketsServer.h>
 
WiFiServer server(80);
WebSocketsServer webSocket = WebSocketsServer(81);
 
byte pin_led = D3;
byte pin_switch = D6;
 
boolean LEDstatus = LOW;
boolean oldSwitchState = LOW;
boolean newSwitchState1 = LOW;
boolean newSwitchState2 = LOW;
boolean newSwitchState3 = LOW;
 
 
char ssid[] = "ssid";
char pass[]= "password";
 
void setup()
{
  pinMode(pin_led, OUTPUT);
  digitalWrite(pin_led,LEDstatus);
 
  pinMode(pin_switch, INPUT);
 
  Serial.begin(115200);
  Serial.println();
  Serial.println("Serial started at 115200");
  Serial.println();
 
  // Connect to a WiFi network
  Serial.print(F("Connecting to "));  Serial.println("ssid");
  WiFi.begin(ssid,pass);
 
 
 
 
  // connection with timeout
  int count = 0; 
  while ( (WiFi.status() != WL_CONNECTED) && count < 17) 
  {
      Serial.print(".");  delay(500);  count++;
  }
 
  if (WiFi.status() != WL_CONNECTED)
  { 
     Serial.println("");  Serial.print("Failed to connect to ");  Serial.println(ssid);
     while(1);
  }
 
  Serial.println("");
  Serial.println(F("[CONNECTED]"));   Serial.print("[IP ");  Serial.print(WiFi.localIP()); 
  Serial.println("]");
 
  // start a server
  server.begin();
  Serial.println("Server started");
 
  webSocket.begin();
  webSocket.onEvent(webSocketEvent);
 
}
 
 
void loop()
{
    checkSwitch();
 
    webSocket.loop();
 
    WiFiClient client = server.available();     // Check if a client has connected
    if (!client)  {  return;  }
 
    client.flush();
    client.print( header );
    client.print( html_1 ); 
    Serial.println("New page served");
 
    delay(5);
}
 
 
void webSocketEvent(byte num, WStype_t type, uint8_t * payload, size_t length)
{
  if(type == WStype_TEXT)
  {
      if (payload[0] == '0')
      {
          digitalWrite(pin_led, LOW);
          LEDstatus = LOW;
          Serial.println("LED=off");        
      }
      else if (payload[0] == '1')
      {
          digitalWrite(pin_led, HIGH);
          LEDstatus = HIGH;
          Serial.println("LED=on");        
      }
  }
 
  else 
  {
    Serial.print("WStype = ");   Serial.println(type);  
    Serial.print("WS payload = ");
    for(int i = 0; i < length; i++) { Serial.print((char) payload[i]); }
    Serial.println();
 
  }
}
 
void checkSwitch()
{
    newSwitchState1 = digitalRead(pin_switch);    delay(1);
    newSwitchState2 = digitalRead(pin_switch);    delay(1);
    newSwitchState3 = digitalRead(pin_switch);
 
    // if all 3 values are the same we can continue
    if (  (newSwitchState1==newSwitchState2) && (newSwitchState1==newSwitchState3) )
    {
        if ( newSwitchState1 != oldSwitchState )
        {
 
           // toggle the LED when the button switch is pressed rather than released
           if ( newSwitchState1 == HIGH )
           {
              LEDstatus = ! LEDstatus;
 
              if ( LEDstatus == HIGH ) { digitalWrite(pin_led, HIGH);  webSocket.broadcastTXT("1"); Serial.println("LED is ON"); }
              else                     { digitalWrite(pin_led, LOW);   webSocket.broadcastTXT("0"); Serial.println("LED is OFF"); }
           }
           oldSwitchState = newSwitchState1;
        }
   }
 
 
}

Что нового? Во-первых, я добавил дополнительный абзац в HTML. Это используется для отображения полученных данных. Это делается только в целях отладки.

<p>Recieved data = <span id='rd'>---</span> </p

«—» является шаблоном и заменяется любыми данными, полученными через Websocket.

Существует также дополнительный код Javascript. Поскольку мы сейчас получаем данные, нам нужно … получить их. Для этого мы используем «Socket.onmessage». Когда Javascript инициализируется, мы сообщаем событию received data вызвать функцию processReceivedCommand (). event — это объект Javascript, содержащий все атрибуты события, включая данные.

function init() 
{
  Socket = new WebSocket('ws://' + window.location.hostname + ':81/');
  Socket.onmessage = function(event) { processReceivedCommand(event); };
}

Именно здесь мы обрабатываем поступающие данные, и в данном случае это управляющие коды для включения или выключения светодиода. «0” для выключения и “1” для включения.

function processReceivedCommand(evt) 
{
    document.getElementById('rd').innerHTML = evt.data;
    if (evt.data ==='0') 
    {  
        document.getElementById('BTN_LED').innerHTML = 'Turn on the LED';  
        document.getElementById('LED_status').innerHTML = 'LED is off';  
    }
    if (evt.data ==='1') 
    {  
        document.getElementById('BTN_LED').innerHTML = 'Turn off the LED'; 
        document.getElementById('LED_status').innerHTML = 'LED is on';   
    }
}

«document.getElementById(‘rd’).innerHTML = evt.data;» просто копирует полученные данные в новый абзац.

Если у нас есть “0”, мы знаем, что светодиод был выключен, и если у нас есть “1”, мы знаем, что светодиод был включен, поэтому мы устанавливаем текст метки и кнопки в соответствие.

Вы можете заметить, что теперь у нас есть дубликат кода; здесь в функции processReceivedCommand (), а также в функции buttonClicked (). Несколько дополнительных функций (таких как LEDon() и LEDoff() можно было бы написать, чтобы сделать код немного более правильным. Я оставляю это на ваше усмотрение.

Поскольку мы добавили переключатель кнопок, нам нужно сообщить ESP8266, где он находится. Это на D6. Дополнительные переменные были добавлены, чтобы заботиться о переключателе.

byte pin_switch = D6;
 
boolean LEDstatus = LOW;
boolean oldSwitchState = LOW;
boolean newSwitchState1 = LOW;
boolean newSwitchState2 = LOW;
boolean newSwitchState3 = LOW;

У нас также есть функция, которая проверяет переключатель кнопок.

void checkSwitch()
{
    newSwitchState1 = digitalRead(pin_switch);    delay(1);
    newSwitchState2 = digitalRead(pin_switch);    delay(1);
    newSwitchState3 = digitalRead(pin_switch);
 
    // if all 3 values are the same we can continue
    if (  (newSwitchState1==newSwitchState2) && (newSwitchState1==newSwitchState3) )
    {
        if ( newSwitchState1 != oldSwitchState )
        {
 
           // toggle the LED when the button switch is pressed rather than released
          // When the switch is closed the pin goes LOW to HIGH
           if ( newSwitchState1 == HIGH )
           {
              LEDstatus = ! LEDstatus;
              if ( LEDstatus == HIGH ) { digitalWrite(pin_led, HIGH);  webSocket.broadcastTXT("1"); Serial.println("LED is ON"); }
              else                     { digitalWrite(pin_led, LOW);   webSocket.broadcastTXT("0"); Serial.println("LED is OFF"); }
           }
           oldSwitchState = newSwitchState1;
        }
   }
 
}

Я не вдаваюсь в подробности о том, как здесь работает код коммутатора. Если вы хотите узнать больше, посмотрите, Switching Things On And Off With An Arduino. Посмотрите примеры 3 и 3а.

Теперь, когда мы можем управлять светодиодом на любом конце, нам нужно следить за ним, и мы делаем это с помощью переменной LEDstatus. Состояние светодиода НИЗКОЕ, когда он выключен, и ВЫСОКОЕ, когда он включен.

Теперь, когда есть контрольный код с веб-страницы, а также управление светодиодом, LEDstatus также обновляется.

  if(type == WStype_TEXT)
  {
      if (payload[0] == '0')
      {
          digitalWrite(pin_led, LOW);
          LEDstatus = LOW;
          Serial.println("LED=off");        
      }
      else if (payload[0] == '1')
      {
          digitalWrite(pin_led, HIGH);
          LEDstatus = HIGH;
          Serial.println("LED=on");        
      }
  }

И это все. Теперь у нас есть двустороннее управление с помощью Websockets.

(Просмотрено 55 раз, сегодня 1)                     Понравилась статья? Ставь 👍
0

Автор публикации

не в сети 11 часов

Николай М

3
Администратор
flagРоссия. Город: пгт Звездный
Комментарии: 52Публикации: 365Регистрация: 09-07-2019

оставить комментарий

Войти с помощью: