• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Нужна помощь Не могу наладить обмен UDP сообщениями между двумя ESP8266

Yasha

New member
Здравствуйте! В наличии ESP-12E и ESP-01S, как первый так и второй модуль должны как принимать так и отправлять UDP сообщения. ESP-01S постоянно подключен к общей точке доступа и имеет личный статически IP-адрес. ESP-12E не всегда может быть включен, так как питается от батарейки, которая садится время от времени. При каждом включении или переподключении к общей точке доступа ESP-12E отправляет UDP-сообщение длиной в 1 байт на ESP-01S, в свою очередь тот считывает сообщение и отправляет ответ в виде строки, записанной в символьном массиве, и ждёт ответа от ESP-12E. ESP-12E постоянно прослушивает порт и при каждом входящем сообщении считывает его. Таких сообщений всего должно быть 9. Если ESP-01S не дождался ответа в течении определенного периода, то отправляет повторно сообщение. Таких попыток всего 3.
Запрос размером в 1 байт ESP-01S считывает, отправляет ответ в виде строки на ESP-12E, но тот в свою очередь вообще не видит этого сообщения. Пробовал менять порты, IP-адреса, способ отправки ответа, создавал отдельный экземпляр типа WiFiUDP, но ничего не помогло. С помощью Packet Sender отправлял пакеты, ответы от обоих модулей приходили мгновенно. Для написания кода использовал Arduino IDE.

Скетч ESP-01S:
Код:
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <SoftwareSerial.h>

#define localPort   500

SoftwareSerial mySerial(2,3);       // RX, TX

uint8_t count, key = 0, timeAnswer = 0;
char ssid1[] = "STOP";
char ssid2[] = "BOBER-FM";
char pass1[] = "06640664";
char pass2[] = "99999999";
char Buffer[4] = {'0'};
char Packet[9][5];
char State_of_loom[9][5] = {{'1','7','1','0','\0'},   //Состояние станков
                        {'1','6','0','0','\0'},
                        {'1','5','1','0','\0'},                
                        {'0','1','0','0','\0'},
                        {'0','2','0','0','\0'},
                        {'0','3','0','0','\0'},
                        {'0','4','0','0','\0'},
                        {'0','5','0','0','\0'},
                        {'0','6','1','0','\0'}};

WiFiUDP Udp;

void Connect()
{
  while (WiFi.status()!= WL_CONNECTED)
  {
    WiFi.begin(ssid1, pass1);
    delay(5000);
    if (WiFi.status() != WL_CONNECTED)
    {
      WiFi.begin(ssid2, pass2);
      delay(5000);
      if (WiFi.status() != WL_CONNECTED)
        delay(30000);
    }
  }
  Serial.println(WiFi.SSID());
  Serial.println(WiFi.localIP());
}

void Send(char *str)
{
  Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
  Udp.write(str, sizeof(str));
  Udp.endPacket();
}

void UDP_Request()
{
  int packetSize = Udp.parsePacket();
  if (packetSize == 1)                        //если пришел один байт (запрос), отправить первую строку и ждать ответа
  {
    count = 0;
    Udp.read();
    Serial.println("Request from ESP-12E");
    Send(State_of_loom[count]);
    Serial.println(State_of_loom[count]);
    key = 1;
  }
  else if (packetSize > 1)                    //если пришло больше одного байта, то отправить следующую строку
  {                                           //или очистить Buffer
    Udp.read();
    Serial.println("Answer from ESP-12E");
    if (Buffer[0] != '0')
      memset(Buffer,'0',4);
    else if (count < 8)
    {
      count++;
      Send(State_of_loom[count]);
      Serial.println(State_of_loom[count]);
      timeAnswer = 0;
    }
    key = 0; 
  }
  else if (key > 0)
  {
    timeAnswer++;
    if (timeAnswer > 50)                    //после 50 циклов ожидания ответа отправляем сообщение снова
    {
      timeAnswer = 0;
      key++;
      Serial.print("key: ");
      Serial.println(key);
      if (Buffer[0] != '0')
        Send(Buffer);
      else
      {
        Send(State_of_loom[count]);
        Serial.println(State_of_loom[count]);
      }
      if (key == 4)                          //максимум 3 раза отправляем, если нет ответа
        key = 0;
    } 
  }
}

void setup()
{
  //mySerial.begin(57600);            // открываем программный серийный порт
  Serial.begin(115200);
  Connect();
 
  Udp.begin(localPort);             // Начинаем «слушать» клиентов:
}
void loop()
{
  if (WiFi.status() == WL_CONNECTED)
  {
    UDP_Request();

  /*
    if (mySerial.available())
    {
      for (uint8_t i = 0; i < 4; i++)  //Считываем оповещение
        Buffer[i] = mySerial.read();                
      Send(Buffer);                    //отправляем оповещение с ожиданием ответа
      timeAnswer = 0;
      key = 1;
    }
    */
  }
  else
    Connect();
  delay(100);
}
 

Yasha

New member
Скетч ESP-12E:
Код:
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include "SH1106.h"
#include "Frame.h"

#define OLED_RESET  5   // RESET
#define OLED_DC     4   // Data/Command
#define OLED_CS     15  // Chip select
#define ReplyBuffer "OK"
#define localPort   5445
#define interruptPin 2
#define ASK         '?'
#define ESP01_port  500
#define sizeBuffer  9

SH1106 display(true, OLED_RESET, OLED_DC, OLED_CS);

IPAddress IP_ESP01(192,168,0,105);
char ssid1[] = "STOP";
char ssid2[] = "BOBER-FM";
char pass1[] = "06640664";
char pass2[] = "99999999";

char Buffer[5] = {'0'};
//char Messege[50];
char packetBuffer[9][5]; //buffer to hold incoming packet

WiFiUDP Udp;

uint8_t i = 1, timeON = 0, Reply = 0;     //счётчик обычный, счётчик работы дисплея включенным
uint16_t time1 = 0;            //счётчик до оповещенния разряда аккумулятора
long vcc = 0, rssi, averageVCC;
volatile byte ON = 0;          //переменная прерываний
bool On = true;               //переменная обычного цикла
bool FirstRequest = false;


void Draw()                                                                 //функция отрисовки таблицы
{
  display.drawXbm(0,14,Frame_width,Frame_height,(const char*)Frame_bits);
  for (uint8_t j = 0, k1 = 0; j < sizeBuffer; j++, k1 = 0)
  {
    if (j!=0)
    {
      if ((j%2 == 0)&&(j!=0))
        k1=1;
      display.drawString(((j+1)/2)*26, 15+(k1*25), String(packetBuffer[j]));
    }
    else
    {
      display.drawString(1, 15, String(packetBuffer[0]));
    }
    display.display(); 
  }
}

void Signal(long rssi_1 = rssi)                //функция отрисовки батарейки
{
  display.setColor(BLACK);
  display.drawRect(115, 2, 10, 8);
  display.fillRect(115, 2, 10, 8);
  display.setColor(WHITE);
  Serial.println(rssi_1);
  if (rssi_1 < (-70))
      display.drawXbm(115, 2, W2_width,W2_height,(const char*)W2_bits);
    else if ((rssi_1 >= (-70)) && (rssi_1 < (-60)))
      display.drawXbm(115, 2, W3_width,W3_height,(const char*)W3_bits);
      else if ((rssi_1 >= (-60)) && (rssi_1 < (-50)))
        display.drawXbm(115, 2, W4_width,W4_height,(const char*)W4_bits);
        else if (rssi_1 >= (-50))
          display.drawXbm(115, 2, W5_width,W5_height,(const char*)W5_bits);
  display.display();
}

void Battery(long vcc_1 = averageVCC)                       //функция отрисовки уровня сигнала Wi-Fi
{
  Serial.println(vcc_1);
  if (On)
  {
    display.setColor(BLACK);
    display.drawRect(0, 2, 16, 8);
    display.fillRect(0, 2, 16, 8);
    display.setColor(WHITE);
    if (vcc_1 >= 800)
      display.drawXbm(0, 2, Img_Battery_3_width, Img_Battery_3_height, (const char*)Img_Battery_3);
      else if ((vcc_1 >= 600) && (vcc_1 < 800))
        display.drawXbm(0, 2, Img_Battery_2_width, Img_Battery_2_height, (const char*)Img_Battery_2);
        else if ((vcc_1 >= 400) && (vcc_1 < 600))
          display.drawXbm(0, 2, Img_Battery_1_width, Img_Battery_1_height, (const char*)Img_Battery_1);
          else if (vcc_1 < 400)
            display.drawXbm(0, 2, Img_Battery_0_width, Img_Battery_0_height, (const char*)Img_Battery_0);        
    display.display();
  }
  else if (vcc_1 < 400)
  {
    time1++;
    if (time1 == 60000)
    {
      time1 = 0;
      display.clear();
      display.displayOn();
      display.drawXbm(20, 20, Img_BigBattery_low_width, Img_BigBattery_low_height, (const char*)Img_BigBattery_low);
      display.display();
      delay(2000);
      display.displayOff();
     }     
  }
  i = 1;
}

void UDP_chat()
{
  int packetSize = Udp.parsePacket();
  if (packetSize > 0)
  {
    Serial.println(packetSize);
    int len = Udp.read(Buffer, 4);         //считывание пакета в Buffer
  
    if (len > 0)
    {
      Serial.println(len);
      Buffer[len] = '0';
    }

    Buffer[4] = '\0';           // записываем в конец признак конца строки для удобной работы с массивом как со строкой
    Udp.read();
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); //Отправляем ответ на IP и порт отправителя
    Udp.write(ReplyBuffer);
    Udp.endPacket();
    Serial.print("Contents: ");
    Serial.println(Buffer);
    if (!On)
    {
      display.displayOn();
      On = true;
      Serial.println("ON");
    }
    timeON = 0;
    if (!FirstRequest)                          // если был отправлен запрос на получение данных, то не выводить на дисплей
    {
      display.clear();
      display.setFont(ArialMT_Plain_24);
      display.drawString(30, 20, String(Buffer));
      display.display();
      delay(2000);
      display.clear();
    }
    else
    {
      Reply++;                                   //счётчик для запроса
      if (Reply == 9)                            // если считалось последнее запрошеное сообщение
      {
        Reply == 0;
        FirstRequest = false;
      }
    }
    Signal();
    Battery();
  }
}

void Attach()
{
  static unsigned long millis_prev;
  if (millis() - 100 > millis_prev)               
      ON = 1;                        // меняем значение на противоположное
  millis_prev = millis();
  Serial.println (ON);
}

void Connect()
{
   do
  {
    WiFi.begin(ssid1, pass1);
    delay(10000);
    if (WiFi.status() == WL_CONNECTED)
    {
      display.clear();
      display.drawString(0, 25, "Connect to \"" + String(ssid1) + "\"");
    }
    else
    {
      WiFi.begin(ssid2, pass2);
      delay(10000);
      if (WiFi.status() == WL_CONNECTED)
      {
         display.clear();
         display.drawString(0, 25, "Connect to \"" + String(ssid2) + "\"");
         break;
      }
      display.clear();
      display.drawString(20, 25, "No connection");
      display.display();
      Serial.println("No connection");
      delay(30000);
    }
  }
  while (WiFi.status()!= WL_CONNECTED);
  display.display();
  Request();
}

void Request()
{
  Udp.beginPacket(IP_ESP01, ESP01_port);
  Udp.write(ASK);
  Udp.endPacket();
  FirstRequest = true;
}

void setup()
{
  Serial.begin(115200);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), Attach, FALLING);
  Serial.println("");
  display.init();
  display.clear();
  display.setFont(ArialMT_Plain_24);
  display.drawString(17, 20, "SERVER");
  display.display();

  display.setFont(ArialMT_Plain_10);
  Connect();
 
  Serial.println(WiFi.SSID());
  Serial.println(WiFi.localIP());
  delay(2000);
  display.clear();
  Draw();
  Battery();
  Signal();
  
  Udp.begin(localPort); // Начинаем «слушать» клиентов:
}

void loop()
{
  if (WiFi.status() == WL_CONNECTED)
  {
    if (ON == 1)
    {
      if (On)
      {
        Serial.println("OFF");
        display.displayOff();
        On = false;
      }
      else
      {
        Serial.println("ON");
        display.displayOn();
        On = true;
      }
      ON = 0;
      timeON = 0;
    }
 
    UDP_chat();
 
    i++;
    vcc += analogRead(A0);             //считывание напряжения аккумулятора
    if (i%20==0)
    {
      averageVCC = vcc/20;
      Battery();
      vcc = 0;
    }
    if (On)
    {
      timeON++;
      if (i%19 == 0)
      {
        rssi = WiFi.RSSI();
        Signal();
      }
      if (Buffer[1] != '0')               //если буфер не пуст, то скопировать его содержимое в массив по первой цифре
      {
        int number = atoi(Buffer);
        switch (number/100)
        {
          case 17:
          {
            strcpy(packetBuffer[0],Buffer);
            break;
          }
          case 16:
          {
            strcpy(packetBuffer[1],Buffer);
            break;
          }
          case 15:
          {
            strcpy(packetBuffer[2],Buffer);
            break;
          }
          default:
          {
          
            strcpy(packetBuffer[number+2],Buffer);
          }
        }
        memset(Buffer, '0', 4);
        display.setFont(ArialMT_Plain_10);
        Draw();                                    //вызов функции рисования таблицы и содержимого массива
      }
      if (timeON >= 150)                           //отключение дисплея после 150 циклов loop()
      {
        Serial.println("OFF");
        On = false;
        display.displayOff();  
      }
    }
  }
  else
  {
    Connect();
  }
  delay(50);
}
 
Сверху Снизу