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