• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе 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
угу, учитывая специфику сообщений, проблему заткнул дополнительным ифом
 
Сверху Снизу