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

Нужна помощь Залипание модуля при использовании UDP

Sayori

New member
Добрый день, имеется проблема схожая с "Вешается" ESP при частых запросах..., но на сей раз речь идет о связке UDP & ArduinoJSON. Грешу на обе библиотеки так как выяснить кто больше виноват сложно. При нагрузочных тестах, которые заключались в отправке по 2 пакета с JSON строкой на борту в модуль, и 1 пакет в ответ, было выявлено что модуль падал где-то на 160-210 итерации цикла отправки.

Собствено в реальной жизни эта проблема возникает где-то раз в 6-12 часов(точно не скажу не удавалось точно заметить), при условии что подуль получает 1 пакет раз в минуту + 1 пакет раз в 5 минут, т.е. в час получается 72 пакета, причем односторонних(т.е. ESP отправляет ответ только по определенной команде которая в штатном режиме не шлется).

Используется ESP8266-07

Скетч:
Код:
#include <ArduinoJson.h>
#include <dummy.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

#define BUFFER_SIZE 256

const char* ssid      = "XXX";
const char* password  = "YYY";
unsigned int port = 5555;
char packetBuffer[BUFFER_SIZE];
char buff[BUFFER_SIZE];

DynamicJsonBuffer incomingJsonBuffer;
DynamicJsonBuffer outcomingJsonBuffer;

WiFiUDP Udp;
JsonObject& statusRoot = outcomingJsonBuffer.createObject();

const int ledPin = 4;
int duty = 0;

void setup()
{
  // set pin modes
  pinMode(ledPin, OUTPUT);

  digitalWrite(ledPin, HIGH);
  delay(300);
  digitalWrite(ledPin, LOW);

  // begin serial and connect to WiFi
  Serial.begin(115200);
  delay(100);

  Serial.println("");
  Serial.println("");
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  Udp.begin(port);
    statusRoot["chipID"] = ESP.getChipId();
    statusRoot["flashID"] = ESP.getFlashChipId();
}

void loop()
{
  int packetSize = Udp.parsePacket();
  if(packetSize) {

    // read the packet into packetBufffer
    int len = Udp.read(packetBuffer, BUFFER_SIZE);
    if (len > 0) {
      if (len > BUFFER_SIZE) { len = BUFFER_SIZE;}
      packetBuffer[len] = 0;
    }  
    Serial.println("Contents:");
    Serial.println(packetBuffer);
    Serial.println();

    JsonObject& root = incomingJsonBuffer.parseObject(packetBuffer);
    // TEMP parse data from packet
    if (root.success())
    {
        // Parsing success
        handler(root);
    }
    for (int i = 0; i < BUFFER_SIZE; i++) {
      packetBuffer[i] = 0x0;
    }

  }
}
void handler(JsonObject& root)
{
  if (root.containsKey("from") && strcmp((const char *)root["from"], "server") == 0) {
    const char * command = root["command"];
    Serial.println(command);
    if (strcmp(command, "status") == 0) {
      Serial.println("SEND STATUS");
      sendStatus();
    }
    if (strcmp(command, "set") == 0) {
      if (root.containsKey("duty")) {
        duty = root["duty"];
      }
      setDuty(duty);
    }
  }
}
// send a reply, to the IP address and port
// that sent us the packet we received
void sendStatus()
{
  
    statusRoot["rip"] = Udp.remoteIP().toString();
    statusRoot["duty"] = duty;
    statusRoot["heap"] = ESP.getFreeHeap();
    statusRoot.printTo(buff, sizeof(buff));
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(buff);
    Udp.endPacket();
    for (int i = 0; i < BUFFER_SIZE; i++) {
      buff[i] = 0x0;
    }
}

void setDuty(int d)
{
  if ( d > 1023 ) {
        d = 1023;
      }
      if (d < 0 ) {
        d = 0;
      }
      Serial.print("SET DUTY: ");
      Serial.println(d);
      analogWrite(ledPin, d);
}
P.S. Прошу ногами не бить)
 
Последнее редактирование:

CodeNameHawk

Moderator
Команда форума
Собствено в реальной жизни эта проблема возникает где-то раз в 6-12 часов
И что за это время WiFi не разу не собъесться?
Может делать проверку доступности сети, перед отсылкой данных?
Читаете
Код:
statusRoot["heap"] = ESP.getFreeHeap();
и как?

У меня ESP 12F каждые 20 секунд получает данные с Serial, разбираетArduino JSON и раз в минуту по HTML отсылает на сервер, работает неделями. Дополнительно работает WebServer.

Про UDP ничего не скажу.
 
Последнее редактирование:

Sayori

New member
CodeNameHawk написал(а):
И что за это время WiFi не разу не собъесться?
Может делать проверку доступности сети, перед отсылкой данных?
Не совсем вас понял, но вероятность того что модуль может терять конекшн я не исключаю, нужно будет копнуть в сторону проверки и реконекта... Но при нагрузочном тестировании он вешался за ~2-5 минут..

CodeNameHawk написал(а):
При нагрузочном тестировании явно видна утечка, лог в атаче.


Я не исключаю что мог где-то накособочить, посему и решил обратиться за помощью
 

Вложения

Сергей_Ф

Moderator
Команда форума
@Sayori ну и при чем тут UDP, когда явная утечка памяти? Смотрите где в json, память не отдаете.
 

CodeNameHawk

Moderator
Команда форума
int len = Udp.read(packetBuffer, BUFFER_SIZE);
if (len > 0) {
packetBuffer[len] = 0;
}
При условии, что len == BUFFER_SIZE==256, packetBuffer[len] выйдет за пределы массива.
Что мешает заняться отладкой? Получили данные отравили на сериал, высчитали длину и на сериал и.т.д.
 

Sayori

New member
@CodeNameHawk, похоже я слеп, не заметил этой "мелочи"... Добавил дополнительную проверку, нагрузочными тестами повесить не удалось... А насчет Serial'a, то зелель я зеленая, совсем про этот инструмент отладки не подумал...:(
 

Sayori

New member
угу, учитывая специфику сообщений, проблему заткнул дополнительным ифом
 
Сверху Снизу