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

UDP клиент. Нет отправки пакета перед ESP.deepSleep

p-a-h-a

Member
Здравствуйте, такая проблема - после отправки UDP пакета, если сразу уснуть, пакет не отправляется, если сделать задержку хотя бы 100 мс то иногда отправляется. Как убедится что пакет отправлен и только после этого спать?
Код:
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#define ssid  "ssid"
#define password  "pass"
WiFiUDP Udp;

void setup() {
  WiFi.mode(WIFI_STA);
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
}

void loop() {
  String buf = "Текст для отправки";
  IPAddress ip(192, 168, 1, 208); // Отправляю себе на ПК. Пк и ЕСП в одной сети на одном роутере
  Udp.beginPacket(ip, 8283);
  Udp.print(buf);
  Serial.println(Udp.endPacket());
//  delay(1000); // если раскоментировать и закоментировать следующую строку, то 100% пакетов принимаются
  ESP.deepSleep(1e6, RF_NO_CAL);// пакеты не принимаются если сразу идти в сон.
}
 

CodeNameHawk

Moderator
Команда форума
Что возвращает Udp.endPacket() ?

// Returns 1 if the packet was sent successfully, 0 if there was an error
int endPacket() override;

По идее надо ждать возвращения 1.
 

p-a-h-a

Member
Нет, не ушел. ESP еще необходимо какое-то время для отправки пакета, возможно пакет в каком-то буфере. Пока не пойму почему так происходит. Простая задержка перед спячкой спасает ситуацию. Без задержки пакеты совсем не отправляются. Цель была попробовать UDP для сокращения времени отправки. пока не вышло.
 

pvvx

Активный участник сообщества
В старых версиях самой SDK, что входит и в Arduino, функция запроса перехода в deep-sleep задавала задержку в 100 мс до закрытия драйвера WiFi и самого перехода в режим deep-sleep.
Теперь, видимо, это оставили на произвол пользователя.
 

pvvx

Активный участник сообщества
Кроме отправки пакетов, для завершения работы дровам WiFi по стандарту необходимо ещё согласовать отключение от AP с закрытиями всех буферов и отсылками последних пакетов. Но ESP не делает этого, а просто бросает роутер в недоумении и с открытыми ресурсами – пусть ищет и балдит. А т.к. закрытия соединения нет, то вся цепочка сети, включая роутеры и т.д. не закрывает буфера и ваш пакет может провисеть ещё долго где-то в кэшах, nat-ах и т.д. А так-же его могут скипнуть из-за непоняток.
 

pvvx

Активный участник сообщества
Не забудьте ещё о не разрешаемой ситуации конкуренции WiFi устройств к AP в старом варианте WiFi 4. Там даже если у соседа в данный момент в эфире работают какие WiFi, то ваша AP ждет и не обслуживает ваши устройства…
Beacon интервал имеет дискретность и по умолчанию на AP установлен в 102.4 мс, и задержки в 100 мс может не хватить.
 

pvvx

Активный участник сообщества
Когда ваше устройство находится в непосредственной близости с AP, то его сигнал перебивает по уровню все окружающие и "отладка на столе" может работать, но когда отнесете устройство на место работы потерь UDP пакетов от такого подхода (пауза в 100 мс) будет в сотни раз больше…

Для Arduino покатит :)
 

nikolz

Well-known member
поставьте колбек на отправку пакета
и в этом колбеке отправляйте спать.
пример см в док SDK.
 

pvvx

Активный участник сообщества
поставьте колбек на отправку пакета
и в этом колбеке отправляйте спать.
пример см в док SDK.
"колбек" не поможет. Он говорит только о том, что данные переданы в Lwip. Даже не в буфер драйвера WiFi. :p
Перевод фантазий nikolz :
"Налепите десяток разнообразных callback - авось они сработают как задержка" :)
 

pvvx

Активный участник сообщества
Исполнение редко исполняемого кода (описываемых "колбек" от nikolz) у ESP равносильно скорости работы его CPU на 8..12 МГц из-за промаха кэша и медленной подгрузки кода по SPI из Flash...
 

pvvx

Активный участник сообщества
Ещё string-гов в callback-и в Arduino понапихать – string s = “Это отрабатывает ‘колбек’ от nikolz!!!”;… Serial.println(s); чтобы проц просканировал всю Heap на наличие свободного кусочка и дополнительно потормозил на 115200 при выводе в UART… :)
 
Сверху Снизу