pvvx
Активный участник сообщества
300 раз мультикаст?Есть несколько NodeMCU, нужно на каждый из них отправить значение чтобы затем управлять PWM, причем отправлять хотя бы 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);
}
(!) Программа передает в сотни раз больше пакетов, чем принимает модуль. Сеть у компа 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
...
В данном случае длина пакета UDP в 43 байт (1 байт данных), то получаем поток всего 77400 байт.
Если организовывать опрос в Loop(), то можно попасть на дискрет RTOS - обычно до 1000 итераций в сек, что меньше чем кол-во принятых пакетов.
Передаем на *.*.*.255:
Код:
...
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
...
(!) Через socket и либы UDP для Arduino часто не более 100 пакетов в сек, остальные будут скипнуты.
Прием 300 пакетов в сек для ESP8266 это близко к его пределу вообще, если он ещё передает echo по ним, и тем более в Arduino. У него всего-то HT20 и ему надо будет отработать несколько тысяч прерываний по приему и передаче пакетов, плюс их обработке, что он явно не успеет на своих 80 MHz.
Есть такая программа FBENCH - там задержки передачи пакетов устанавливаются в us.
Последнее редактирование: