• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

arDuino + ESP + Delphi (TCP/UDP Client/Server)

UFO 007

New member
Доброго всем времени суток!
Пред-пред-история короткая: год-другой назад изобрёл сортирный автомат управления освещением и вентиляторами (изначально - на Атмеге328) но совершенству предела нет и захотелось управлять всем этим делом с Andrюхи (до iOгрызка ход пока не дошёл) и чтобы было визуально понятно что происходит в эфире была написана (в Delphi) программа поддержки для РС которая медленно, но верно трансформировалась в вышеозвученную ипостась... И худо-бедно автомат был отлажен и про всё забыто...
А пред-история чуть подлинней: выписал с Китая датчик температуры и влажности: ну разве не соблазн родить грамоШный будильник? И на той же Атмеге328 будильник был реализован, но размер символов на LCD1602 оставлял желать лучшего и под руку попался LCD12864В и... О! Да! И время - для ОсобоСлепых, и будильник, и ДД/ММ/ГГГГ, и t', и влажность, и... В общем: всё - оГуенчик, но... Как оказалось печать на ЛСД через библиотИку U8g2lib "весит" аж 29 Кб + сам будильник 7 = итого: в 32 кб Атмеги - не помещается: "Скетч слишком большой..." И, незамедлительно, было решено снять с дистанции устаревшую Атмегу и к финишу пришла НодеМЦУв3.0... И худо-бедно будильник был отлажен без всяких ТЦП/УДП, но гудение "главбуха": - "А ты выключил(включил) свет в аквариуме(ах)" заставило задуматься: валяются же ещё 2 ЕСПхи... И был будильник переписан, и управляет он теперь освещением аквариумов... Но и в этот раз не обошлось без Клиент_Сервера... С УДП как-то не срослось (хотя с сортирным автоматом всё было откатано вродь как донельзя лучше) и теперь будильник (как ТЦПсервер) указывает аквариуму(каждые 5 мин. запрос) включиться (6:15) и выключиться (21:00)... И решил я "допилить" Клиент_Сервера до безобразия, но упёрся в то же УДП - вот скетч:

C++:
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <GyverButton.h>

#define Lamp_pin 16 // br_Lamp
#define wc_sens 5
#define br_sens 13

const char *ssid = "FX-4300";//UDP_Tester_007
const char *pass = "12345678";
//const char* host = "192.168.127.0";
const uint16_t localPort = 8086;
GButton WC(wc_sens, HIGH_PULL, NORM_CLOSE);
GButton BR(br_sens, HIGH_PULL, NORM_CLOSE);
WiFiUDP MyUdp;

void setup() {
  delay(1000);
  Serial.begin(115200);
  Serial.println();
//  Serial.println("Configuring access point...");
//  WiFi.softAP(ssid);
  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print('.');
    delay(500);
  }
  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(myIP);
  Serial.println("HTTP server started");

//  MyUdp.begin(localPort);
  if (MyUdp.begin(localPort)) Serial.println("UDP = started");
  pinMode(Lamp_pin, OUTPUT);
//  digitalWrite(Lamp_pin, 1);
//  WiFi.begin(ssid);//, password);
  Serial.print(F("server started on IP: "));
  Serial.println(WiFi.softAPIP());//localIP
  WC.setTickMode(AUTO);
  WC.setDebounce(150);
  WC.setTimeout(1500); // 7500 настройка таймаута на удержание (по умолчанию 500 мс)
  WC.setStepTimeout(3000);// 60000
  BR.setDebounce(150);
  BR.setTickMode(AUTO);
  BR.setTimeout(1500); // 7500 настройка таймаута на удержание (по умолчанию 500 мс)
  BR.setStepTimeout(3000);// 60000
}

void loop() {
  if (WC.isPress()){
    SendMsg("WC.isPress");
    digitalWrite(Lamp_pin, 1);
    Serial.print(F("softAPIP: "));
    Serial.println(WiFi.softAPIP());
    Serial.print(F("localIP: "));
    Serial.println(WiFi.localIP());
    Serial.print("localPort = ");
    Serial.println(MyUdp.localPort());
    Serial.print("remoteIP = ");
    Serial.println(MyUdp.remoteIP());
    Serial.print("remotePort = ");
    Serial.println(MyUdp.remotePort());
    Serial.print("destinationIP = ");
    Serial.println(MyUdp.destinationIP());
  }
  if (WC.isHold()){// проверка на удержание
    SendMsg("WC.isHold");
  }
  if (BR.isPress()){
    SendMsg("BR.isPress");
    digitalWrite(Lamp_pin, 0);
  }
  if (BR.isHold()){// проверка на удержание
    SendMsg("BR.isHold");
  }
//  String s = RecvMsg();
//  if (s.length() != 0) SendMsg("принято");
}

void SendMsg(String Messg){
  char sendchars[Messg.length()+1];// буфер для строки
  Messg.toCharArray(sendchars, Messg.length()+1);//преобразовываем в буфер
  MyUdp.beginPacket(MyUdp.remoteIP(), MyUdp.remotePort());
  MyUdp.write(sendchars);
  MyUdp.endPacket();
/* Ввиду того, что в UDP доставка пакета НЕ гарантирована клиент отправляет
 * только что принятое сообщение и отправитель сравнивает переданное с
 * возвращённым   */
/*  String tmp;
  do tmp = RecvMsg();
  while (Messg != tmp);// коню понятно - чревато переполнением стека
*/
}

String RecvMsg(){
  char packetBuffer[UDP_TX_PACKET_MAX_SIZE + 1]; //buffer to hold incoming packet,
  // if there's data available, read a packet
  int packetSize = MyUdp.parsePacket();
  if (packetSize) {
/*Serial.printf("Received packet of size %d from %s:%d\n    (to %s:%d, free heap = %d B)\n",
              packetSize,
              MyUdp.remoteIP().toString().c_str(), MyUdp.remotePort(),
              MyUdp.destinationIP().toString().c_str(), MyUdp.localPort(),
              ESP.getFreeHeap());
*/
    // read the packet into packetBufffer
    int n = MyUdp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
    packetBuffer[n] = 0;
    SendMsg(String(packetBuffer));//подтверждаем приём - принято именно то, что передано
    return String(packetBuffer);
  }
}
Процедура SendMsg() вААщпе нИ работает никак...
А вот и Клиент_Сервер...

З.Ы. Изначально подумал: "Ну наконец-то форум где можно выложить файл (а не ссылку на какой-нить Я-диск)"... но файл не может превышать FDD3,5 поэтому пришлось 1.744 резать, а вам чтобы собрать ВинКомандёром надо удалить из имени файлов ".zip"

P.P.S. Предлагаю "всем миром" отладить Клиент_Сервера
 

Вложения

UFO 007

New member
// String s = RecvMsg();
// if (s.length() != 0) SendMsg("принято");
Если это дело разREMировать(удалить "//") - то происходит циклический (пару-тройку секунд) перезапуск (безумная гипотеза: может Aquarium_007.2 "шорох" наводит? - хотя он-то пашет через ТЦП)...
 

UFO 007

New member
Пардон, ежели кого-нить обидел, но в сфере ТЦП Клиент_Сервер выдаёт такое:Сервер - на связи.jpg
 

UFO 007

New member
Да, к стати: вот скетч, который эти результаты выдал:
Код:
#include <ESP8266WiFi.h>
#include <GyverButton.h>

#ifndef STASSID
#define STASSID "Tester_007"
#endif
//#define Lamp_pin 16 // br_Lamp
#define wc_sens 5
#define br_sens 13
#define Lamp_pin 16 // br_Lamp

const char *ssid = "FX-4300";//UDP_Tester_007
const char *pass = "12345678";
const char* host = "192.168.127.0";
const uint16_t port = 8086;
GButton WC(wc_sens, HIGH_PULL, NORM_CLOSE);
GButton BR(br_sens, HIGH_PULL, NORM_CLOSE);

// Create an instance of the server
// specify the port to listen on as an argument
WiFiServer server(port);

void setup() {
  pinMode(Lamp_pin, OUTPUT);
  Serial.begin(115200);
//  WiFi.mode(WIFI_STA);//_AP
//  WiFi.softAP(ssid);
  WiFi.begin(ssid, pass);//, word);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  server.begin();
  Serial.print(F("Server started on IP: "));
  Serial.println(WiFi.localIP());
  WC.setTickMode(AUTO);
  WC.setDebounce(150);
  WC.setTimeout(1500); // 7500 настройка таймаута на удержание (по умолчанию 500 мс)
  WC.setStepTimeout(3000);// 60000
  BR.setDebounce(150);
  BR.setTickMode(AUTO);
  BR.setTimeout(1500); // 7500 настройка таймаута на удержание (по умолчанию 500 мс)
  BR.setStepTimeout(3000);// 60000
}

void loop() {
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
  String req = client.readStringUntil('\r');
  Serial.println(req);
  client.flush();
  if (req.indexOf("Get_Status") != -1) {
    client.print("Get_Status is = OK");
    client.print("Сервер - на связи");
  }
}
З.Ы.
FX-4300 - это мой комп (через ХотСпот ВайВай-свистка)
 
Сверху Снизу