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

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

Dein

New member
Здравствуйте, посоветуйте пожалуйста.
Есть несколько NodeMCU, нужно на каждый из них отправить значение чтобы затем управлять PWM, причем отправлять хотя бы 300 раз в секунду. Картинку приложил.
На данный момент возникли такие вопросы
1. Сейчас использую Lua и ESPlorer, есть ли смысл для этой задачи применить Arduino IDE?
2. Не смог нагуглить как в режиме клиента отправить данные на ESP, везде говорится что нужно создать сервер и открыть порт, зачем тогда нужен режим клиента?
3. Какие подводные камни если нужно будет отправить данные на 10 штук ESP?
 

Вложения

kab

New member
Здравствуйте, посоветуйте пожалуйста.
Есть несколько NodeMCU, нужно на каждый из них отправить значение чтобы затем управлять PWM, причем отправлять хотя бы 300 раз в секунду. Картинку приложил.
На данный момент возникли такие вопросы
1. Сейчас использую Lua и ESPlorer, есть ли смысл для этой задачи применить Arduino IDE?
2. Не смог нагуглить как в режиме клиента отправить данные на ESP, везде говорится что нужно создать сервер и открыть порт, зачем тогда нужен режим клиента?
3. Какие подводные камни если нужно будет отправить данные на 10 штук ESP?
1. Могу кое-что представить по поводу Arduino IDE
2. По поводу клиента:
Управление ногами ESP <-> ESP
3. Если следовать вышеприведенной логике, то с каждой из 10 ESP надо переподключаться отдельно и передавать данные тоже по очереди. Можно попытаться использовать UDP - там можно отправить инфу всем сразу, но там негарантированная доставка. Придется функционал обратных подтверждений дописывать самостоятельно...
 

CodeNameHawk

Moderator
Команда форума
причем отправлять хотя бы 300 раз в секунду.
Алгоритм стоит поменять, пусть каждая есп сама решает какой PWM выдавать, иначе при обрыве связи, всем может показаться пушистый зверек.
Одновременно к есп (если не ошибаюсь) может быть подключено пять клиентов.

зачем тогда нужен режим клиента?
А кто к серверу будет подключаться?
 

view24

Member
Я бы порекомендовал WEBSOCKET, но для arduino ide websocket из имеющихся библиотек медленный. Может на LUA websocket попробовать?
 

Dein

New member
Спасибо большое за ответы.
Стал пользоваться Ardiono IDE, все стало намного веселей. Пока только попробовал передачу по UDP. Пакеты отправляются и принимаются.
Пробую решить проблему с pwm flickering.
 

nikolz

Well-known member
Здравствуйте, посоветуйте пожалуйста.
Есть несколько NodeMCU, нужно на каждый из них отправить значение чтобы затем управлять PWM, причем отправлять хотя бы 300 раз в секунду. Картинку приложил.
На данный момент возникли такие вопросы
1. Сейчас использую Lua и ESPlorer, есть ли смысл для этой задачи применить Arduino IDE?
2. Не смог нагуглить как в режиме клиента отправить данные на ESP, везде говорится что нужно создать сервер и открыть порт, зачем тогда нужен режим клиента?
3. Какие подводные камни если нужно будет отправить данные на 10 штук ESP?
1) Для Вашей задачи посмотрите ESP_NOW.
2) 10 ESP да еще 300 сообщений в секунду -это фантастика.
3) Можно посылать сообщение сразу всем . Для этого сообщения идентифицируются по порту а IP адрес приемника содержит 255 в последнем байте. Сообщение будет для всех в данной подсети.
 

rashn

New member
Еще вариант решения - установить локальный BLYNK сервер на распберри и использовать ТЭГи (объединение нескольких устройств). Многие "ручные" этапы делаются простыми настройками в приложении.
 

Dein

New member
Автор на связи, отправляю UDP пакеты на esp32 по ip адресу, все четко и быстро, 300 пакетов в секунду , но если отправляю на 192.168.0.255 то доходят только 7 пакетов в секунду. Проверил в Wireshark, в сети все пакеты присутствуют, получается esp не может их принять? Роутер D-Link 615. Много гуглил, ответа не нашел. В какую сторону копать понятия не имею.
 

nikolz

Well-known member
Автор на связи, отправляю UDP пакеты на esp32 по ip адресу, все четко и быстро, 300 пакетов в секунду , но если отправляю на 192.168.0.255 то доходят только 7 пакетов в секунду. Проверил в Wireshark, в сети все пакеты присутствуют, получается esp не может их принять? Роутер D-Link 615. Много гуглил, ответа не нашел. В какую сторону копать понятия не имею.
Чем отправляете пакеты и с каким интервалом.
Как подтверждаете прием пакетов и с каким интервалом.
 

Dein

New member
Чем отправляете пакеты и с каким интервалом.
Как подтверждаете прием пакетов и с каким интервалом.
Сразу предупрежу что уровень моих знаний околонулевой.
Пакеты отправляю с пк самописной простейшей программой использующей библиотеку для udp, отправка и прием делается на высоком уровне в одну строку, подводных камней не нашел.
Пакеты отправляются с равным интервалом 10мс(для примера беру 100 пакетов в секунду). Принимаю на esp32 в main loop’е либо без прерываний либо с прерыванием равным отправке, delay(10);, на результат не влияет.
Получение подтверждаю сообщением в Serial после подсчета количества пакетов. При отправке на конкретный ip все работает как предполагается, все считается правильно, количество отправленных и принятых пакетов совпадает. Проблема возникает при смене адреса на 192.168.0.255.
  1. Существуют ли другие отличия между unicast и multicast upd пакетами кроме как различные ip? Может пакет для отправки неправильно собираю?(я меняю только ip)
  2. Т.к. 100% уверенности в моей программе у меня нет попытался сделать отправку udp multicast из iperf2, но она мультикаст отправляет только из режима клиента, в режиме сервера только слушает, чем генерировать пакеты для отладки пока не знаю. Чем?
На данный момент:
a) отправка по адресу 192.168.0.12, отправлено 100 -> получено 100 (в секунду)
b) отправка по адресу 192.1680.255, отправлено 100 -> получено ~7 (в секунду)
Тут же на сервере принимаю пакеты: принято 200, хотя отправлено 100
Где то дублируются. Вот как выглядят принятые пакеты:
Код:
Packet Address:  [16, 2, 13, 9, 192, 168, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0]
Packet Data:  [0, 111, 0, 0]
is IPv4:  true
is IPv6:  false
address size:  16 bytes
host size:  Optional("192.168.0.14")
host:  Optional("192.168.0.14")
port:  3337
family:  2
data size:  4 bytes

Packet Address:  [28, 30, 13, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 192, 168, 0, 14, 0, 0, 0, 0]
Packet Data:  [0, 111, 0, 0]
is IPv4:  false
is IPv6:  true
address size:  28 bytes
host size:  Optional("::ffff:192.168.0.14")
host:  Optional("::ffff:192.168.0.14")
port:  3337
family:  30
data size:  4 bytes
 

nikolz

Well-known member
Сразу предупрежу что уровень моих знаний околонулевой.
Пакеты отправляю с пк самописной простейшей программой использующей библиотеку для udp, отправка и прием делается на высоком уровне в одну строку, подводных камней не нашел.
Пакеты отправляются с равным интервалом 10мс(для примера беру 100 пакетов в секунду). Принимаю на esp32 в main loop’е либо без прерываний либо с прерыванием равным отправке, delay(10);, на результат не влияет.
Получение подтверждаю сообщением в Serial после подсчета количества пакетов. При отправке на конкретный ip все работает как предполагается, все считается правильно, количество отправленных и принятых пакетов совпадает. Проблема возникает при смене адреса на 192.168.0.255.
  1. Существуют ли другие отличия между unicast и multicast upd пакетами кроме как различные ip? Может пакет для отправки неправильно собираю?(я меняю только ip)
  2. Т.к. 100% уверенности в моей программе у меня нет попытался сделать отправку udp multicast из iperf2, но она мультикаст отправляет только из режима клиента, в режиме сервера только слушает, чем генерировать пакеты для отладки пока не знаю. Чем?
На данный момент:
a) отправка по адресу 192.168.0.12, отправлено 100 -> получено 100 (в секунду)
b) отправка по адресу 192.1680.255, отправлено 100 -> получено ~7 (в секунду)
Тут же на сервере принимаю пакеты: принято 200, хотя отправлено 100
Где то дублируются. Вот как выглядят принятые пакеты:
Код:
Packet Address:  [16, 2, 13, 9, 192, 168, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0]
Packet Data:  [0, 111, 0, 0]
is IPv4:  true
is IPv6:  false
address size:  16 bytes
host size:  Optional("192.168.0.14")
host:  Optional("192.168.0.14")
port:  3337
family:  2
data size:  4 bytes

Packet Address:  [28, 30, 13, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 192, 168, 0, 14, 0, 0, 0, 0]
Packet Data:  [0, 111, 0, 0]
is IPv4:  false
is IPv6:  true
address size:  28 bytes
host size:  Optional("::ffff:192.168.0.14")
host:  Optional("::ffff:192.168.0.14")
port:  3337
family:  30
data size:  4 bytes
Предположу, что пакеты с компа посылаемые по фикс адресу уходят одновременно а не через 10 мс.
см Алгоритм Нейгла — Википедия
Поэтому сделайте для проверки прием ответа на каждый пакет а и также посмотрите с помощью Wireshsrk интервал между пакетами.
 

Dein

New member
Предположу, что пакеты с компа посылаемые по фикс адресу уходят одновременно а не через 10 мс.
см Алгоритм Нейгла — Википедия
Поэтому сделайте для проверки прием ответа на каждый пакет а и также посмотрите с помощью Wireshsrk интервал между пакетами.
Прикладываю скрин из Wireshark, и код esp для ясности.
Что значит прием ответа на каждый пакет? Дописать в esp код чтобы она отправляла обратно пакет при принятии или это опция какая-то?

Код:
#include <WiFi.h>
#include <WiFiMulti.h>
#include <WiFiUdp.h>

// WiFi network name and password:
const char * networkName = "DIR-615";
const char * networkPswd = "pass12345";
boolean connected = false;

//The udp library class
WiFiUDP udp;
const int udpPort = 3337;
const int packetBufferSize = 2048;
char packetBuffer[packetBufferSize];


void setup() {
  Serial.begin(9600);
  delay(50);
  //Connect to the WiFi network
  connectToWiFi(networkName, networkPswd);
}


void loop() {
  receiveUdpPacket();
}


void receiveUdpPacket() {
  if (connected) {
    udp.read(packetBuffer, packetBufferSize);
    int packetSize = udp.parsePacket();
    if (packetSize) {
      counterPerSecond();
      memset(packetBuffer, 0, packetBufferSize);
    }
  }
}

// packets per second
int counter = 0;
int currentSecond = 0;
int lastSecond = 0;
void counterPerSecond() {
   int currentSecond = millis() / 1000;
        if (currentSecond != lastSecond) {
          currentSecond = millis() / 1000;
          Serial.print("Packets per sec: ");
          Serial.print(counter);
          Serial.print("\n");
          counter = 0;
          lastSecond = millis() / 1000;
        } else {
          counter++;
        }
}

// MARK: wi-fi connection

void connectToWiFi(const char * ssid, const char * pwd){
  Serial.println("Connecting to WiFi network named: " + String(ssid));
  // delete old config
  WiFi.disconnect(true);
  //register event handler
  WiFi.onEvent(WiFiEvent);
  //Initiate connection
  WiFi.begin(ssid, pwd);
  Serial.println("Waiting for WIFI connection...");
}

//wifi event handler
void WiFiEvent(WiFiEvent_t event) {
    switch(event) {
      case SYSTEM_EVENT_STA_GOT_IP:
          //When connected set
          Serial.print("WiFi connected! IP address: ");
          Serial.println(WiFi.localIP()); 
          //initializes the UDP state
          //This initializes the transfer buffer
          udp.begin(WiFi.localIP(), udpPort);
          connected = true;
          break;
      case SYSTEM_EVENT_STA_DISCONNECTED:
          Serial.println("WiFi lost connection");
          connected = false;
          break;
    }
}
 

Вложения

nikolz

Well-known member
Прикладываю скрин из Wireshark, и код esp для ясности.
Что значит прием ответа на каждый пакет? Дописать в esp код чтобы она отправляла обратно пакет при принятии или это опция какая-то?

[/code]
1) допишите код ответа ESP и прием ответа на компе с выводом на дисплей
2) покажите Wireshark c Ответом для фиксированного адреса и для оповещения. При оповещении адрес надо задавать так
IP вашей сети кроме последнего байта - в нем 255
 

Dein

New member
Вероятно вместо udp.begin(WiFi.localIP(), udpPort); нужно использовать udp.beginMulticast(WiFi.localIP(), udpPort);
Но не могу заставить работать, serial monitor выдает
Код:
Waiting for WIFI connection...
WiFi connected! IP address: 192.168.0.12
igmp_joingroup: attempt to join non-multicast address
igmp_leavegroup: attempt to leave non-multicast address
Код библиотеки WIFiUdp на гитхабе
arduino-esp32/WiFiUdp.cpp at master · espressif/arduino-esp32 · GitHub
Код:
uint8_t WiFiUDP::beginMulticast(IPAddress a, uint16_t p){
  if(begin(IPAddress(INADDR_ANY), p)){
    if(a != 0){
      struct ip_mreq mreq;
      mreq.imr_multiaddr.s_addr = (in_addr_t)a;
      mreq.imr_interface.s_addr = INADDR_ANY;
      if (setsockopt(udp_server, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
          log_e("could not join igmp: %d", errno);
          stop();
          return 0;
      }
      multicast_ip = a;
    }
    return 1;
  }
  return 0;
}
 

Алексей.

Active member
Мне приходилось сталкиваться с "негарантированным" получением бродкаст пакетов на сетях wifi и отказ от использования бродкаста в пользу мультикаста решал проблему.
У Вас упоминается мультикаст, но почему то, адрес используете бродкастный, не понятно что хотели получить. Судя по коду приемника никакого мультикаста и не собирались получать. Что конкретно хотели получить? Гарантированный прием юникаста уже Вы получили, т.е. производительности достаточно чтоб на esp было
все четко и быстро, 300 пакетов в секунду
Существуют ли другие отличия между unicast и multicast upd пакетами кроме как различные ip?
Принципиальное отличие ;)
юникаст - отправка от одного хоста (от одного ip адреса) к другому хосту (к другому ip адресу), мультикаст - отправка от одного хоста к групповому ip адресу, т.е. получатели - те хосты, которые подключены к группе. Ну и бродкаст - отправка от одного всем без разбора.
Пример мультикаста для esp32 в esp-idf/examples/protocols/udp_multicast

udp.beginMulticast(WiFi.localIP(), udpPort)
Как то не так, локальный ip Вы хотите использовать для получения мультикастов??
Им же отдельная сеть выделена 224.x.x.x - 239.x.x.x
 
Последнее редактирование:

pvvx

Активный участник сообщества
Тут же на сервере принимаю пакеты: принято 200, хотя отправлено 100
Где то дублируются.
Вы же отправляете 100 пакетов мультикаст, соответственно принимаете этот пакет и на компе (он же тоже в том сегменте, куда и отправляете пакет) + переданный echo от внешнего порта на модуле.
Как то не так, локальный ip Вы хотите использовать для получения мультикастов??
Им же отдельная сеть выделена 224.x.x.x - 239.x.x.x
Это кто им такое выделил? :)
 
Сверху Снизу