Здравствуйте! В наличии 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: Код (C++): #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); }
Скетч для ESP-12E: Код (C++): #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); }
Вот тут ошибка. Длину буфера в данном случае нужно передать явно. Функция не знает размера буфера, определенного извне