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

Отправить данные на несколько esp

pvvx

Активный участник сообщества
Есть несколько NodeMCU, нужно на каждый из них отправить значение чтобы затем управлять PWM, причем отправлять хотя бы 300 раз в секунду.
300 раз мультикаст? :)
Код:
/* WiFi UDP Send and Receive String */
#include <WiFi.h>
#include <GTimer.h>
extern "C" {
#include "lwip/opt.h"
#include "lwip/api.h"
#include "lwip/sys.h"
} // extern "C"

#include <myAP.h>
#ifndef _MYAPCFG_H_
char ssid[] = "yourNetwork"; //  your network SSID (name)
char pass[] = "password";    // your network password (use for WPA, or use as key for WEP)
#endif //_MYAPCFG_H_

unsigned int localPort = 2390;    // local port to listen on
unsigned int OutPort = 2391;      // local port to send

volatile uint32_t PacketNum = 0;
volatile uint32_t OldPacketNum = 0;

void TimHandler(uint32_t data) {
  Serial.print("Packet per sec: ");
  Serial.println(PacketNum - OldPacketNum);
  OldPacketNum = PacketNum;
}

#if SEND_ECHO_ENA
char buffer[4096];
#endif
void my_udp_thread(void *arg)
{
  static struct netconn *conn;
  static struct netbuf *buf;
  err_t err;
  LWIP_UNUSED_ARG(arg);

  conn = netconn_new(NETCONN_UDP);
  if (conn != NULL)  {
    err = netconn_bind(conn, IP_ADDR_ANY, localPort);
    if (err != ERR_OK) Serial.println("Can create new UDP netconn!");
    else while (1) {
        err = netconn_recv(conn, &buf);
        if (err != ERR_OK) Serial.println("Can not bind netconn!");
        else {
          PacketNum++;
          ip_addr_t *addr = netbuf_fromaddr(buf);
#if SEND_ECHO_ENA
          unsigned short port = netbuf_fromport(buf);
          if (netbuf_copy(buf, buffer, sizeof(buffer)) != buf->p->tot_len)
            Serial.println("Netbuf_copy failed!");
          else {
            buffer[buf->p->tot_len] = '\0';
            if (netconn_send(conn, buf) != ERR_OK) Serial.println("netconn_send failed");
            Serial.println(buffer);
          }
#else
//          if (netconn_sendto(conn, buf, addr, OutPort) != ERR_OK) Serial.println("netconn_send failed");
#endif
          netbuf_delete(buf);
        }
      }
  }
}

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(38400);
  while (!Serial); // wait for serial port to connect. Needed for native USB port only
  // attempt to connect to Wifi network:
  while (WiFi.begin(ssid, pass) != WL_CONNECTED) delay(100);
  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);
  // timerid 0, period 1s, invoke myhander
  GTimer.begin(0, 1 * 1000 * 1000, TimHandler);
  sys_thread_new("my_udp", my_udp_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
}

void loop() {
  delay(1000);
}
Передаем прямо на IP модуля:
Снимок55.gif
(!) Программа передает в сотни раз больше пакетов, чем принимает модуль. Сеть у компа 1Gbit/s, а роутер c WiFi на 2.4G имеет скорость передачи меньше!
(!) Зависимость от передающей программы тоже очень большая. Драйвер сети в компе может сам скипать неуспевающие передаваться пакеты. Если в программе нет связи с этим делом, то она может передать и мульон UDP пакетов в сек :) из которых реально в линию уйдет только малая часть. Данная программа, используемая в качестве теста тоже кривая и сколько реально она передает при задержке межу передачами выставленной в 0 - неизвестно.

Принял модуль c RTL871x в сек:
Код:
...
Packet per sec: 1770
Packet per sec: 1360
Packet per sec: 1760
Packet per sec: 1618
Packet per sec: 1836
Packet per sec: 1876
Packet per sec: 1399
Packet per sec: 1471
Packet per sec: 1647
Packet per sec: 1410
Packet per sec: 1706
Packet per sec: 1576
Packet per sec: 1806
Packet per sec: 1719
...
Необработанных пакетов, переданных по WiFi нет. Иначе бы его драйвер орал об скипнутых приемником кол-ве пакетов за каждые 2 сек, которые не ушли (не обработаны) в LwIP.
В данном случае длина пакета UDP в 43 байт (1 байт данных), то получаем поток всего 77400 байт.
Если организовывать опрос в Loop(), то можно попасть на дискрет RTOS - обычно до 1000 итераций в сек, что меньше чем кол-во принятых пакетов.

Передаем на *.*.*.255:
Снимок56.gif
Код:
...
Packet per sec: 320
Packet per sec: 288
Packet per sec: 268
Packet per sec: 307
Packet per sec: 319
Packet per sec: 320
Packet per sec: 307
Packet per sec: 300
Packet per sec: 249
Packet per sec: 320
Packet per sec: 314
Packet per sec: 299
Packet per sec: 314
...
У роутера есть клиенты на WiFi 5GHz/s и ещё проводная сеть с клиентами на 1GB/s. Всем надо передать мультикаст. Кол-во пакетов в сек переданных в модуль падает...

(!) Через socket и либы UDP для Arduino часто не более 100 пакетов в сек, остальные будут скипнуты.

Прием 300 пакетов в сек для ESP8266 это близко к его пределу вообще, если он ещё передает echo по ним, и тем более в Arduino. У него всего-то HT20 и ему надо будет отработать несколько тысяч прерываний по приему и передаче пакетов, плюс их обработке, что он явно не успеет на своих 80 MHz.

Есть такая программа FBENCH - там задержки передачи пакетов устанавливаются в us.
 
Последнее редактирование:

kab

New member
Прием 300 пакетов в сек для ESP8266 это близко к его пределу вообще
@pvvx
Вы более глубоко обосновали мысль, которая уже была в обсуждении, что гонять каждый импульс PWN через сеть - это глупо!
Через сеть надо передавать значение PWN(среднее, а не мгновенное значение сигнала), а код PWN на пине генерить уже скетчем на ESP локально. И проблемы со скоростью снимаются сразу.
А так - ТС уже где-то близко к решению своей задачи - и не уводите его в сторону. Пожалуйста.
 

pvvx

Активный участник сообщества
@pvvx
Вы более глубоко обосновали мысль, которая уже была в обсуждении, что гонять каждый импульс PWN через сеть - это глупо!
Через сеть надо передавать значение PWN(среднее, а не мгновенное значение сигнала), а код PWN на пине генерить уже скетчем на ESP локально. И проблемы со скоростью снимаются сразу.
А так - ТС уже где-то близко к решению своей задачи - и не уводите его в сторону. Пожалуйста.
А где решение?
Пример в студию, с управлением хотя-бы пары устройств без задержки. :) Ну пусть задержка будет 2 мс. Больше - это уже что-то очередное кривое... ТС играет в обучение программированию с простыми примерами или хочет сделать что-то работающее?

Для того, чтобы работало синхронно пару модулей, тут ещё не хватает синхронизации.

@kab - а где у вас описание сколько тянет ESP8266 или ESP-32 пакетов в Arduino? Т.е. где можно глянуть базовые замеры, чтобы отталкиваться от них для выбора возможных алгоритмов?
Возможно задача ТС вообще не решается указанными тут путями на ESP8266, а вы хотите затянуть в дебри маяния с Arduino IDE ESP8266 без каких либо итогов в виде работающей вещи?
 
Последнее редактирование:

Dein

New member
Все заработало как я хотел когда поменял ip на 224, 255, 255, 0. Несколько esp одновременно принимают массив из байтов 300 раз в секунду, из массива берут нужный байт и применяют для pwm. То что работает - меня радует, но то что я совсем не понял что произошло - нет. Вопросов осталось много, что за адрес 192.168.0.255 , почему esp все таки принимает пакеты с этим адресом, почему доходит из ста всего семь?
 

Алексей.

Active member
Dein, я же говорил
У Вас упоминается мультикаст, но почему то, адрес используете бродкастный, не понятно что хотели получить
Если Ваша подсеть 192.168.0.0/24 то тот адрес как раз и получается бродкастный. Роутеры такую лавину бродкастов фильтруют, я думаю, и Вы получаете из сотни всего семь. А мультикаст как раз и предназначен для уменьшения нагрузки на сеть, когда всем хостам подключенным к группе нужно передать одно и тоже, например видеопоток.
 

Алексей.

Active member
pvvx, а можно по подробнее про
Драйвер сети в компе может сам скипать неуспевающие передаваться пакеты
Я тоже так думал, когда отправил большое количество пакетов в сеть, wiresbark со стороны отправителя показал одно и тоже время, а на стороне приемника время прихода пакетов уже отличалось. При выполнении юникастов пакеты почему то не терялись, драйвер честно доставал их из стека и отправлял. Вот я и хочу понять когда драйвер принимает решение о пропуске пакета полученного из стека.
 

Алексей.

Active member
Прием 300 пакетов в сек для ESP8266 это близко к его пределу вообще, если он ещё передает echo по ним, и тем более в Arduino.
Неужели так всё хреново у есп8266?
Попробовал оценить время отклика, отправлял со стороны ПК udp пакеты на есп, а есп эхом их возвращал. Есп - точка доступа, ПК - клиент wifi.
В течении 10-ти секунд на ПК выполнял sendto recvfrom и подсчитывал количество выполненных тестов.
При длине пакета 1024 байта за 10 секунд выполнял 4800 - 5100 тестов, время отклика составило 1,96 - 2,08 мсек
При длине пакета 32 байта за 10 секунд выполнял 6800 - 7000 тестов, время отклика составило 1,43 - 1,47 мсек
Ардуиной к счастью я на пользовался, использовал только rtos_sdk
 

nikolz

Well-known member
Неужели так всё хреново у есп8266?
Попробовал оценить время отклика, отправлял со стороны ПК udp пакеты на есп, а есп эхом их возвращал. Есп - точка доступа, ПК - клиент wifi.
В течении 10-ти секунд на ПК выполнял sendto recvfrom и подсчитывал количество выполненных тестов.
При длине пакета 1024 байта за 10 секунд выполнял 4800 - 5100 тестов, время отклика составило 1,96 - 2,08 мсек
При длине пакета 32 байта за 10 секунд выполнял 6800 - 7000 тестов, время отклика составило 1,43 - 1,47 мсек
Ардуиной к счастью я на пользовался, использовал только rtos_sdk
Я оценивал эти времена по току потребления и задержкам колбеков на ESP и по времени пакетов в Wireshark
Получилось минимум импульса передатчика WIFI - 2 мс
ESP-комп-ESP до 6 мс.
Соответствует вашим измерениям.
Полагаю , что 300 это предел.
 

Алексей.

Active member
Я оценивал эти времена по току потребления и задержкам колбеков на ESP и по времени пакетов в Wireshark
Wireshark порой показывает отрицательное значение времени, доверие к нему подорвано.
Полагаю , что 300 это предел.
Если при длине пакета 1024 байта за 10 секунд я получил 5000 ответов, соответственно 500 за 1-ну секунду, не понятно значение предела 300, как оно получается?
На коротких пакетах ещё быстрее получается, откуда берется минимальное значение 2 мсек тоже не понял??

ЗЫ: На есп32 проксирую сип, в обеих направлениях голос и видео, на голос (g.711 не жатый) в каждом направлении ~50 кадров в секунду по ~160 байт и на видео (h.264) в каждом направлении ~10 кадров в секунду по ~1400 байт и предел как то не замечал, может я не правильно устройство использую и оно скоро сломается :)
 
Последнее редактирование:

nikolz

Well-known member
Wireshark порой показывает отрицательное значение времени, доверие к нему подорвано.

Если при длине пакета 1024 байта за 10 секунд я получил 5000 ответов, соответственно 500 за 1-ну секунду, не понятно значение предела 300, как оно получается?
На коротких пакетах ещё быстрее получается, откуда берется минимальное значение 2 мсек тоже не понял??
про Wireshark согласен, но у меня не отрицательные а много меньше
Но если делать так:
ESP8266 посылает UDP короткий и фиксирует время
комп принимает и отсылает эхо
колбек ESP8266 фиксирует время приема эхо.
То получается 6 мс
------------------
Если измерить время работы передатчика т е когда ток ESP8266 больше 70 ма, то у меня получается не менее 2 мс.
 
Последнее редактирование:

nikolz

Well-known member
ЗЫ: На есп32 проксирую сип, в обеих направлениях голос и видео, на голос (g.711 не жатый) в каждом направлении ~50 кадров в секунду по ~160 байт и на видео (h.264) в каждом направлении ~10 кадров в секунду по ~1400 байт и предел как то не замечал, может я не правильно устройство использую и оно скоро сломается :)
Вы же в этом случае в не разрываете соединения и не создаете вновь?
т е с одной стороны передатчик а с другой приемник
а попробуйте короткими перебежками с переключением режимов на стороне ESP.
 

Алексей.

Active member
nikolz, У меня задача обратная была :) Проверить реакцию есп.
Зачем тратить время на установление соединения?
Хотите получить статус устройства - отправьте запрос, нет ответа, запросите ещё раз.
Хотите управлять пином - отправьте команду, нет ответа на команду, отправьте ещё раз.
 

nikolz

Well-known member
nikolz, У меня задача обратная была :) Проверить реакцию есп.
Зачем тратить время на установление соединения?
Хотите получить статус устройства - отправьте запрос, нет ответа, запросите ещё раз.
Хотите управлять пином - отправьте команду, нет ответа на команду, отправьте ещё раз.
Понятно, что у всех разные задачи.
Меня интересовала задача максимального энергосбережения при работе с автономным источником.
При этом надо не только хорошо спать и мало кушать во сне но и быстро проснуться передать сообщение понять что его либо приняли либо нет
если нет то понять либо та сторона спит либо она уже другая и снова лечь спать.
-----------------------------
При этом надо еще решить задачу хватит ли энергии чтобы передать данные или надо ее накопить.
------------------------
Правда 300 посылок в секунду я не собирался посылать
 

Алексей.

Active member
быстро проснуться передать сообщение
Зачем тратить время на установление соединения если нужно быстро?
Посмотрите на tcp протокол, сначала отправляется запрос на установление соединения, затем в течении таймаута ожидается "ack" на этот запрос и если ack получен - соединение установлено, и только после этого Вы начинаете передачу. Разве это быстро?

На один запрос и ответ у Вас
1-на передача запроса на соединение
1-на передача данных
1-на передача ответа на fin полученный от удаленной стороны либо отправка своего fin при разрыве соединения
Разве это экономия энергии??
 

nikolz

Well-known member
Зачем тратить время на установление соединения если нужно быстро?
Посмотрите на tcp протокол, сначала отправляется запрос на установление соединения, затем в течении таймаута ожидается "ack" на этот запрос и если ack получен - соединение установлено, и только после этого Вы начинаете передачу. Разве это быстро?

На один запрос и ответ у Вас
1-на передача запроса на соединение
1-на передача данных
1-на передача ответа на fin полученный от удаленной стороны либо отправка своего fin при разрыве соединения
Разве это экономия энергии??
Согласен, поэтому я использую UDP
а основное время ESP8266 у меня после просыпания тратит на сканирование каналов.
Если его убрать так как канал я знаю, то минимальное время активности составит 150 мс.
Полагаю, что меньше этого на WIFI не получить.
---------------------------------
Как я понял Вы хорошо освоили ESP32
Возможно можете что-то рассказать о возможностях ESP32 в плане экономного питания (использование ULP) и скорости просыпания связи засыпания. Ну и другие ваши достижения были бы интересны. возможно в отдельную тему.
спасибо
 

pvvx

Активный участник сообщества
Неужели так всё хреново у есп8266?
Попробовал оценить время отклика, отправлял со стороны ПК udp пакеты на есп, а есп эхом их возвращал. Есп - точка доступа, ПК - клиент wifi.
В течении 10-ти секунд на ПК выполнял sendto recvfrom и подсчитывал количество выполненных тестов.
При длине пакета 1024 байта за 10 секунд выполнял 4800 - 5100 тестов, время отклика составило 1,96 - 2,08 мсек
При длине пакета 32 байта за 10 секунд выполнял 6800 - 7000 тестов, время отклика составило 1,43 - 1,47 мсек
Ардуиной к счастью я на пользовался, использовал только rtos_sdk
Ну не совсем чтобы :) Это в Arduino всё совсем плохо...
Обычный тест хотя-бы моего web-сервера-свалки показывает, что трансфер у нас файлов с него стремиться к 1.2 Мегабайта в сек и постоянный не менее 1 Мег. Это значит, что 1048576 байт/1460 байт в пакете = 718 полных пакетов в сек в одну сторону и 712/2 ответа ACK (TCP протокол) обратно. Каждые переданные 2 пакета ждут ACK -> 359 ожиданий в сек от момента передачи и приема.
Т.е. на 2 посланных и 1 принятого ACK уходит 2.7 мс. Только из этого следует, что пинг должен давать не более 1 мс в местной интрасети. Тест UDP (ipref) на ESP8266 имеет поток к 1.6 мегабайт/сек полезных данных...
Windows не показывает пинг менее 1 мс. На ESP8266 с приложением сделанном на SDK без ардуиновского Loop(), а работающего по событиям - всегда 1 мс.

В RTOS работает дискретизация переключения задач с его тиком. Он обычно 1 мс. По этому пинг на таких системах, построенных на socket, а не на калбаках LwIP и семафорах имеют пинг от 1 мс до 2 мс, т.к. бьет это дело с переключением задач. И даже чтобы добиться 1..2 мс, надо правильно установить приоритеты треда LwIP и других задач...
А в Arduino .... :) ... тупо иногда вызывается delay(20), чтобы, если накопились прерывания таймеров и системные таски, то они выполнились. А на них и работает LwIP и дрова WiFi. По этому там пинг зависит от задач в Loop() и кол-ва вызовов delay(), и в средней паршивости программе, мигающей одним светодиодом пинг будет ужасен - к 20 мс и более - более 1 сек при использовании SPIFS, т.к. пока он работает запрещены прерывания, а когда пишет - стрирание страницы Flash 0.2 сек и работать никто не может (программы то все в Flash, а она занята). :)
 
Последнее редактирование:

Алексей.

Active member
Как я понял Вы хорошо освоили ESP32
Нет, вовсе не так, я его просто использовал. Питание не экономил ни разу, экономить питание на сервере в моем случае не получится, да и не требуется, на гарантированном питании работает.
Ну и другие ваши достижения были бы интересны. возможно в отдельную тему.
Решений то и нет никаких (вру конечно, есть но за них з.п. получаю), есть в esp-idf примеры, при использовании их в мирных целях можно получить результаты.
Поскольку на этом форуме, imho, линукс предан анафеме а основная ОС на которой я тружусь линукс, делиться достижениями совсем тоскливо, да и с ардуино-иде (точнее с библиотеками) нет времени разбираться, код подглядываю иногда и только.
Сама ардуина-иде вовсе не иде, как ей пользоваться после эклипса и IntelliJ (и её клонов) вообще не понятно?
 

pvvx

Активный участник сообщества
Поскольку на этом форуме, imho, линукс предан анафеме а основная ОС на которой я тружусь линукс, делиться достижениями совсем тоскливо, да и с ардуино-иде (точнее с библиотеками) нет времени разбираться, код подглядываю иногда и только.
Тут всё, что кроме Arduino давно поросло, а с выходом её на ESP8266 форум превратился в тысячный придаток Ардуино форумов: "не работает скетч", "дайте готовый скетч" :)
Линукс для IoT не нужен, как и во многих MCU и других задачах контроля/управления исполнительными механизмами - нужен реал-тайме, а линукс в этом деле не очень.
В RTL-ках Ameba Realtek переделывает дрова и пакеты от Линукс на RTOS. Если у вас есть знания, то помогли бы доразобрать дрова USB2.0, UVC и WiFi в RTL8195... Они туда перекинуты из линукс, особенно WiFi, и всё общение у них через ioctl...
 
Последнее редактирование:
Сверху Снизу