Поддержка UDP в новой Easy HMI 0.1.2.

Работа по беспроводной сети планировалась при старте разработки Easy HMI и дисплеев AT HMI. В первых версиях также была заложена работа по беспроводной сети с использованием собственного протокола. Однако обучение новому протоколу оказалось гораздо сложнее, чем предоставление возможности работать с уже знакомым протоколом передачи данных. Поэтому было принято решение сделать реализацию общения по протоколу UDP. Также в новой версии программы добавлены некоторые настройки для дисплеев, что расширяет возможности и спектр их применения в различных проектах, начиная от простых панелей для управления светом или подсветкой и заканчивая интеграцией в систему умного дома.

Что такое UDP?

UDP – это один из ключевых протоколов транспортного уровня в стеке TCP/IP, работающий параллельно с более известным TCP. Его главная отличительная черта – работа без установки соединения. В отличие от TCP, который сначала устанавливает надежное соединение (выполняет "рукопожатие"), гарантирует доставку каждого пакета и сохраняет их порядок, UDP действует по принципу "отправил и забыл".

Он просто формирует пакет данных (датаграмму) и отправляет его по указанному адресу и порту, не требуя подтверждения о доставке. Это делает UDP значительно быстрее и легче TCP, так как управляющей информации передается гораздо меньше.

Поддержка UDP в Easy HMI.


Поддержка UDP в Easy HMI.

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

Плюсы:

  1. Высокая скорость загрузки интерфейса дисплея.
  2. Возможность создать скрытую точку подключения.
  3. Автовосстановление соединения.

Минусы:

  1. Максимальное количество подключаемых устройств — 6 (ограничил программно).
  2. Меньший радиус действия сети, чем у Wi-Fi-роутера.
  3. Ниже уровень безопасности (над этим моментом работаю).

По поводу безопасности. Для данной версии прошивки и программы Easy HMI не предусмотрена смена пароля и порта сети. Но так как сеть скрытая, о данной точке подключения знаете только вы. (Надеюсь, что ваши соседи не планируют сделать систему управления, используя Easy HMI. В противном случае при пересечении адресов кнопок вы будете управлять их устройствами, а они — вашими! Но это маловероятно!). Дополнительные настройки точки доступа будут реализованы в следующей версии ПО. Также планирую сделать возможность работать и через ваш Wi-Fi-роутер. Но для этого нужно продумать несколько моментов, над чем сейчас и работаю.

Как устроена работа по UDP?

Всё достаточно просто. Вам нужно обновить прошивку для вашего AT HMI дисплея (доступна в закрытой группе для владельцев AT HMI). И в программе Easy HMI в Настройках активировать отправку по UDP. Всё, теперь ваше устройство выступает в качестве точки доступа, и можно отправлять команды подчиненным устройствам. Команды аналогичны командам управления по UART. Подробнее в статье: … . Для управления реле или светодиодом достаточно написать вот такой код:

/*
* Поддержка UDP в новой Easy HMI 0.1.2.
* https://arduino-tex.ru/news/215/podderzhka-udp-v-novoi-easy-hmi-012.html
*/
#if defined(ESP8266)
#include <ESP8266WiFi.h>
#endif
#if defined(ESP32)
#include "WiFi.h"
#endif
#include <WiFiUdp.h>
WiFiUDP udp;
// --- Настройка UDP  ---
const char* ssid = "ATHMI_AP";         // SSID
const char* password = "C3ej7769Kjh";  //пароль
const uint16_t receiverPort = 49356;   // Порт, который СЛУШАЕТ получатель
void setup() {
  Serial.begin(9600);
  pinMode(2, OUTPUT);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(600);
    Serial.println("Connecting to WiFi...");
  }
  Serial.print("Connected to WiFi with IP: ");
  Serial.println(WiFi.localIP());
  udp.begin(receiverPort);
}
void loop() {
  if (udp.parsePacket()) {
    char incomingPacket[16];
    int len = udp.read(incomingPacket, 16);
    if (len > 0) {
      incomingPacket[len] = '\0';
      //Serial.println(incomingPacket);  // вывести полученную команду в порт
      //--- Кнопка Вкл. --- //
      if (strstr(incomingPacket, "BtA0C=1") != NULL) {  // нажали на кнопку A0C
        Serial.println("Command: ON");
        //digitalWrite(2, HIGH);  // Включаем светодиод.
      }
      //--- Кнопка Выкл. --- //
      if (strstr(incomingPacket, "BtA0C=0") != NULL) {  // отпустили кнопку A0C
        Serial.println("Command: OFF");
        //digitalWrite(2, LOW);  // Включаем светодиод.
      }
      //--- Кнопка Вкл. --- //
      if (strstr(incomingPacket, "BtA09=1") != NULL) {  // нажали на кнопку A09
        // Serial.println("Command: ON");
        digitalWrite(2, HIGH);  // Включаем светодиод.
      }
      //--- Кнопка Выкл. --- //
      if (strstr(incomingPacket, "BtA09=0") != NULL) {  // отпустили кнопку A09
        //Serial.println("Command: OFF");
        digitalWrite(2, LOW);  // Выключаем светодиод.
      }
    }
  }
}

Где A0C — ID кнопки в программе Easy HMI. Значение после знака равно показывает: 1 — кнопка нажата, 0кнопка отпущена. Для кнопок с фиксацией эти значения означают смену состояния при каждом нажатии. Подробнее в уроке про кнопки.

 Значение после знака равно показывает: 1 — кнопка нажата, 0 — кнопка отпущена.

Сейчас можно создать любое количество кнопок на дисплее и управлять до 6 устройствами с подключенными к ним реле. Если, например, взять ESP8266, то к ней можно подключить 8 реле. Мы можем управлять 6 подчиненными устройствами. В итоге получим возможность управлять до 48 реле в разных местах комнаты или помещения. Но это ещё не всё: обмен данными работает и в обратном направлении. Мы можем отправлять данные на дисплей, например, менять текст. Как в примере ниже:

/*
* Поддержка UDP в новой Easy HMI 0.1.2.
* https://arduino-tex.ru/news/215/podderzhka-udp-v-novoi-easy-hmi-012.html
*/
#if defined(ESP8266)
#include <ESP8266WiFi.h>
#endif
#if defined(ESP32)
#include "WiFi.h"
#endif
#include <WiFiUdp.h>
WiFiUDP udp;
// --- Настройки UDP получателя ---
const char* ssid = "ATHMI_AP";         // SSID
const char* password = "C3ej7769Kjh";  //пароль
IPAddress receiverIp(192, 168, 4, 1);  // IP адрес получателя
const uint16_t receiverPort = 49356;   // Порт, который СЛУШАЕТ получатель
void setup() {
  Serial.begin(9600);
  pinMode(2, OUTPUT);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(600);
    Serial.println("Connecting to WiFi...");
  }
  Serial.print("Connected to WiFi with IP: ");
  Serial.println(WiFi.localIP());
  udp.begin(receiverPort);
}
void loop() {
  if (udp.parsePacket()) {
    char incomingPacket[16];
    int len = udp.read(incomingPacket, 16);
    if (len > 0) {
      incomingPacket[len] = '\0';
      //Serial.println(incomingPacket); // вывести полученную команду в порт
      //--- Кнопка Вкл. --- //
      if (strstr(incomingPacket, "BtA0C=1") != NULL) { // нажали на кнопку A0C
        // Serial.println("Command: ON");
        digitalWrite(2, HIGH);  // Включаем светодиод.
        //--- UDP
        sendUdpTxt(0xA07, "Статус вкл. - 2"); 
      }
      //--- Кнопка Выкл. --- //
      if (strstr(incomingPacket, "BtA0C=0") != NULL) { // отпустили кнопку A0C
        //Serial.println("Command: OFF");
        digitalWrite(2, LOW);  // Включаем светодиод.
        sendUdpTxt(0xA07, "Статус выкл. - 2");
      }
      //--- Кнопка Вкл. --- //
      if (strstr(incomingPacket, "BtA09=1") != NULL) { // нажали на кнопку A09
        sendUdpTxt(0xA07, "Статус вкл. - 1");
        sendUdpBtSwich(0xA27, 1);
      }
      //--- Кнопка Выкл. --- //
      if (strstr(incomingPacket, "BtA09=0") != NULL) {  // отпустили кнопку A09
        sendUdpTxt(0xA07, "Статус выкл. - 1");
        sendUdpBtSwich(0xA27, 0);
      }
    }
  }
}
// --== Функции для отправки данных на дисплей ==---//
//== изменяем состояние кнопки с фиксацией (не применимо для кнопки без фиксации)  num_element = id, data_swi = 0/1
void sendUdpBtSwich(uint16_t num_element, bool data_swi) {  //bt.A1F.swi=1
  if (WiFi.status() != WL_CONNECTED) {                      // Проверяем, есть ли WiFi соединение
    return;                                                 // Выходим, если нет сети
  }
  String data_to_send = "bt." + String(num_element, HEX) + ".swi=" + String(data_swi);
  udp.beginPacket(receiverIp, receiverPort);
  udp.print(data_to_send);
  udp.endPacket();  // просто отправка Прооверка ниже
}
//== отправка текста num_element = id, data_txt = "текст"
void sendUdpTxt(uint16_t num_element, String data_txt) {  // tx.A09.txt=Привет
  if (WiFi.status() != WL_CONNECTED) {  // Проверяем, есть ли WiFi соединение
    Serial.println("sendUdpTxt Error: WiFi not connected.");
    return;  // Выходим, если нет сети
  }
  // Формируем строку для отправки
  String data_to_send = "tx." + String(num_element, HEX) + ".txt=" + data_txt;
  // Используем глобальные receiverIp и receiverPort
  udp.beginPacket(receiverIp, receiverPort);
  // udp.print() отлично работает с объектами String
  udp.print(data_to_send);
  udp.endPacket();  // просто отправка Прооверка ниже
  // Отправляем пакет и проверяем результат
  /*if (udp.endPacket()) {
    // Успех на уровне отправки с ESP
    Serial.println("  UDP packet sent successfully.");
  } else {
    // Ошибка при отправке пакета (например, проблема с сетевым стеком)
    Serial.println("  Error sending UDP packet.");
  }*/
}

Указывая, какое реле включено и на каком устройстве. Или просто отправлять температуру. Можно сделать информер и отправлять температуру и влажность с датчика на улице, а также температуру с датчика в комнате. И это только самые простые примеры. Реализовать можно более сложный функционал. Также планирую сделать систему пересылки данных через мастера другим подчиненным устройствам, тем самым организовав своего рода систему управления. Например, вам нужно при достижении определенной температуры включать реле. Одно устройство измеряет температуру и при достижении заданного значения температуры отправляет значение на дисплей, а также значение для пересылки другому устройству, к которому подключено реле. И при получении значения реле включается.

Другие обновления и доработки

  1. Прошивка для моих дисплеев сейчас также универсальная. Изменять нужно только:
    • Для дисплея 2.8 с IPS-матрицей — инвертировать цвет.Для дисплея 2.8 с IPS-матрицей — инвертировать цвет.
    • Для дисплеев 3.5 — настроить разрешение (указать 320x480), ориентацию дисплея (4) и ориентацию сенсора (4 для горизонтального расположения, 6 для вертикального). Для дисплеев 3.5 — настроить разрешение (указать 320x480)
    (Стилистический вариант: Для дисплеев 3.5 нужно настроить разрешение, указав 320x480. Ориентация дисплея — 4, ориентация сенсора — 4 для горизонтального расположения и 6 для вертикального.)Стилистический вариант: Для дисплеев 3.5 нужно настроить разрешение, указав 320x480. Ориентация дисплея — 4, ориентация сенсора — 4 для горизонтального расположения и 6 для вертикального.
  2. Загрузка прошивки из программы Easy HMI.В программе EasyHMI 0.1.2
  3. Расширил выбор скорости работы по UART от 4800 до 921600 бод.Расширил выбор скорости работы по UART от 4800 до 921600 бод.
  4. Добавлена возможность включить и выключить отправку по UDP.Добавлена возможность включить и выключить отправку по UDP.
  5. Благодаря оптимальной настройке драйверов дисплея получилось повысить производительность и отзывчивость сенсора.


Важно! Easy HMI предназначена в первую очередь для дисплеев AT HMI, но также поддерживает и некоторые дисплеи сторонних производителей.

Вопросы:

  • Когда появится поддержка UDP для дисплеев ESP32-2432S028 и аналогичных моделей?

Ориентировочно через 1 месяц.

  • Когда появится поддержка UDP для кастомных HMI-дисплеев на ESP32 и TFT?

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

  • Как можно помочь ускорить процесс разработки?

Самый простой способ ускорить процесс — это поддержать разработку на Boosty или в группе ВК.


Поддержка и развитие функционала Easy HMI.

Так как проект разработан на голом энтузиазме, я не могу много времени тратить, отвечая на все вопросы. Поэтому сделал отдельную группу ВК, где буду выкладывать ответы на вопросы. Вы также можете предложить свой вопрос, на все актуальные вопросы будет ответ в данной группе.

 Вы также можете предложить свой вопрос

И не забывайте читать новости и комментарии в данной группе. Кроме этого, планирую проводить 1 раз в неделю онлайн-ответы на вопросы. Но это будет зависеть от того, насколько проект будет популярен, и как вы будете поддерживать его на Boosty.


Понравилась статья Поддержка UDP в новой Easy HMI 0.1.2? Не забудь поделиться с друзьями в соц. сетях.

А также подписаться на наш канал на YouTube, вступить в группу Вконтакте, в группу на Facebook.

Спасибо за внимание!

Технологии начинаются с простого!

Фотографии к статье

Файлы для скачивания

EasyHMI 0.1.2 EasyHMI 0.1.2.zip8151 Kb 73 Скачать
Код - Обработка нажатия на кнопку Код - Обработка нажатия на кнопку.ino2 Kb 52 Скачать
Код - Отправка текста для отображения на дисплее Код - Отправка текста для отображения на дисплее.ino4 Kb 51 Скачать

Комментарии

Ваше Имя*


Разработка проектов