ESP32 transmit delay and cluster of packets

Hello, I'm trying to send a simple message every 70ms from an ESP32 device configured in softAP mode to move a servo. However, on the receiver side, 3 messages arrive together and then a 200ms delay. This is more noticeable when a second client connects to the softAP. I am able to verify this on wireshark, and also i can see my servo reacting in a jittery way. I have tried different versions of ESP32, from WROOM to the latest ESP32-S3 with different platforms and firmware available from both espressif (AT-commands) or Arduino. I have also tried the ESP in STA mode. I'm hoping someone can share a light on how to reduce the latency when sending UDP packets at a fast rate. My code:


#include <WebServer.h>
#include <WiFi.h>
#include <WiFiUdp.h>

// the IP of the machine to which you send msgs - this should be the correct IP in most cases (see note in python code)
#define HOST_IP "192.168.1.255"
#define REMOTE_PORT 3000

const char* ssid = "testESP32";
const char *password = "";
WiFiUDP Udp;
IPAddress local_ip(192, 168, 1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
WebServer server(2000);



char buf1[17]={0x7E,0x4C,0x45,0x08,0x00,0x00,0x0A,0x00,0x0B,0x00,0x0C,0x00,0x00,0x00,0xF9,0xF3,0xFE};


void setup()
{
  Serial.begin(115200);
 
  WiFi.softAP(ssid, password);
  WiFi.softAPConfig(local_ip, gateway, subnet);
 
  WiFi.setSleep(false);
  server.begin();
   Serial.println("I'm ready");
}

void loop()
{
  Udp.beginPacket(HOST_IP, REMOTE_PORT);
  // Just test touch pin - Touch0 is T0 which is on GPIO 4.
  Udp.printf(buf1);
  Udp.endPacket();
 delay(70);
}

you have defined an array of 17 bytes but you write the array using

Udp.printf(buf1);

which only appears to write the first 4 bytes (stopping at the first 0 byte)
if buf1 is 17 bytes in size why not use

Udp.write((uint8_t*)buf1, sizeof(buf1));

data received

Received: 17 bytes "~L"
   hex >>  0x7e 0x4c 0x45 0x8  0  0 0xa  0 0xb  0 0xc  0  0  0 0xfffffff9 0xfffffff3 0xfffffffe

getting sign extension on last thee bytes

got it.. fixed the buffer. But the issue is the transmission delay and clustering of packets. Wondering if anyone else has seen this using ESP32, sending packets at 70ms? Here is the log when connected to just my PC, and to a second client (another ESP32 or iPhone or iPad). Note the timing between packets on the picture. It should be something around 70 ms...

if I run your program on an ESP32 I get on my PC

Welcome to DrJava.  Working directory is F:\Programming\Ardunio\Networking\WiFi\ESP32\UDP\UDPtiming\UDPtiming
> run UDPserverTimer
UDP sevrer on IP address 192.168.1.2 port 3000
From IP /192.168.1.1 UDP received 'time 21 mSec average time 21 mSec errors 1
From IP /192.168.1.1 UDP received 'time 19 mSec average time 20 mSec errors 2
From IP /192.168.1.1 UDP received 'time 75 mSec average time 38 mSec errors 3
From IP /192.168.1.1 UDP received 'time 69 mSec average time 64 mSec errors 3
From IP /192.168.1.1 UDP received 'time 72 mSec average time 67 mSec errors 3
From IP /192.168.1.1 UDP received 'time 77 mSec average time 68 mSec errors 4
From IP /192.168.1.1 UDP received 'time 64 mSec average time 68 mSec errors 5
From IP /192.168.1.1 UDP received 'time 21 mSec average time 67 mSec errors 6
From IP /192.168.1.1 UDP received 'time 72 mSec average time 68 mSec errors 6
From IP /192.168.1.1 UDP received 'time 71 mSec average time 68 mSec errors 6
From IP /192.168.1.1 UDP received 'time 70 mSec average time 68 mSec errors 6
From IP /192.168.1.1 UDP received 'time 70 mSec average time 69 mSec errors 6
From IP /192.168.1.1 UDP received 'time 20 mSec average time 68 mSec errors 7
From IP /192.168.1.1 UDP received 'time 71 mSec average time 68 mSec errors 7
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 7
From IP /192.168.1.1 UDP received 'time 72 mSec average time 69 mSec errors 7
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 7
From IP /192.168.1.1 UDP received 'time 72 mSec average time 69 mSec errors 7
From IP /192.168.1.1 UDP received 'time 21 mSec average time 69 mSec errors 8
From IP /192.168.1.1 UDP received 'time 70 mSec average time 69 mSec errors 8
From IP /192.168.1.1 UDP received 'time 70 mSec average time 69 mSec errors 8
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 8
From IP /192.168.1.1 UDP received 'time 72 mSec average time 69 mSec errors 8
From IP /192.168.1.1 UDP received 'time 21 mSec average time 69 mSec errors 9
From IP /192.168.1.1 UDP received 'time 83 mSec average time 69 mSec errors 10
From IP /192.168.1.1 UDP received 'time 58 mSec average time 69 mSec errors 11
From IP /192.168.1.1 UDP received 'time 77 mSec average time 69 mSec errors 12
From IP /192.168.1.1 UDP received 'time 65 mSec average time 69 mSec errors 13
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 13
From IP /192.168.1.1 UDP received 'time 21 mSec average time 69 mSec errors 14
From IP /192.168.1.1 UDP received 'time 72 mSec average time 69 mSec errors 14
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 14
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 14
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 14
From IP /192.168.1.1 UDP received 'time 19 mSec average time 69 mSec errors 15
From IP /192.168.1.1 UDP received 'time 70 mSec average time 69 mSec errors 15
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 15
From IP /192.168.1.1 UDP received 'time 78 mSec average time 69 mSec errors 16
From IP /192.168.1.1 UDP received 'time 63 mSec average time 69 mSec errors 17
From IP /192.168.1.1 UDP received 'time 70 mSec average time 69 mSec errors 17
From IP /192.168.1.1 UDP received 'time 20 mSec average time 69 mSec errors 18
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 18
From IP /192.168.1.1 UDP received 'time 75 mSec average time 69 mSec errors 19
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 19
From IP /192.168.1.1 UDP received 'time 72 mSec average time 69 mSec errors 19
From IP /192.168.1.1 UDP received 'time 20 mSec average time 69 mSec errors 20
From IP /192.168.1.1 UDP received 'time 72 mSec average time 69 mSec errors 20
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 20
From IP /192.168.1.1 UDP received 'time 72 mSec average time 69 mSec errors 20
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 20
From IP /192.168.1.1 UDP received 'time 72 mSec average time 69 mSec errors 20
From IP /192.168.1.1 UDP received 'time 20 mSec average time 69 mSec errors 21
From IP /192.168.1.1 UDP received 'time 70 mSec average time 69 mSec errors 21
From IP /192.168.1.1 UDP received 'time 70 mSec average time 69 mSec errors 21
From IP /192.168.1.1 UDP received 'time 70 mSec average time 69 mSec errors 21
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 21
From IP /192.168.1.1 UDP received 'time 19 mSec average time 69 mSec errors 22
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 22
From IP /192.168.1.1 UDP received 'time 85 mSec average time 69 mSec errors 23
From IP /192.168.1.1 UDP received 'time 55 mSec average time 69 mSec errors 24
From IP /192.168.1.1 UDP received 'time 72 mSec average time 69 mSec errors 24
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 24
From IP /192.168.1.1 UDP received 'time 19 mSec average time 69 mSec errors 25
From IP /192.168.1.1 UDP received 'time 72 mSec average time 69 mSec errors 25
From IP /192.168.1.1 UDP received 'time 76 mSec average time 69 mSec errors 26
From IP /192.168.1.1 UDP received 'time 65 mSec average time 69 mSec errors 27
From IP /192.168.1.1 UDP received 'time 70 mSec average time 69 mSec errors 27
From IP /192.168.1.1 UDP received 'time 21 mSec average time 69 mSec errors 28
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 28
From IP /192.168.1.1 UDP received 'time 72 mSec average time 69 mSec errors 28
From IP /192.168.1.1 UDP received 'time 79 mSec average time 69 mSec errors 29
From IP /192.168.1.1 UDP received 'time 64 mSec average time 69 mSec errors 30
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 30
From IP /192.168.1.1 UDP received 'time 20 mSec average time 69 mSec errors 31
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 31
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 31
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 31
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 31
From IP /192.168.1.1 UDP received 'time 20 mSec average time 69 mSec errors 32
From IP /192.168.1.1 UDP received 'time 70 mSec average time 69 mSec errors 32
From IP /192.168.1.1 UDP received 'time 69 mSec average time 69 mSec errors 32
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 32
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 32
From IP /192.168.1.1 UDP received 'time 72 mSec average time 69 mSec errors 32
From IP /192.168.1.1 UDP received 'time 19 mSec average time 69 mSec errors 33
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 33
From IP /192.168.1.1 UDP received 'time 73 mSec average time 69 mSec errors 33
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 33
From IP /192.168.1.1 UDP received 'time 72 mSec average time 69 mSec errors 33
From IP /192.168.1.1 UDP received 'time 21 mSec average time 69 mSec errors 34
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 34
From IP /192.168.1.1 UDP received 'time 70 mSec average time 69 mSec errors 34
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 34
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 34
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 34
From IP /192.168.1.1 UDP received 'time 21 mSec average time 69 mSec errors 35
From IP /192.168.1.1 UDP received 'time 70 mSec average time 69 mSec errors 35
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 35
From IP /192.168.1.1 UDP received 'time 72 mSec average time 69 mSec errors 35
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 35
From IP /192.168.1.1 UDP received 'time 19 mSec average time 69 mSec errors 36
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 36
From IP /192.168.1.1 UDP received 'time 106 mSec average time 69 mSec errors 37
From IP /192.168.1.1 UDP received 'time 64 mSec average time 69 mSec errors 38
From IP /192.168.1.1 UDP received 'time 64 mSec average time 69 mSec errors 39
From IP /192.168.1.1 UDP received 'time 65 mSec average time 69 mSec errors 40
From IP /192.168.1.1 UDP received 'time 19 mSec average time 69 mSec errors 41
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 41
From IP /192.168.1.1 UDP received 'time 111 mSec average time 69 mSec errors 42
From IP /192.168.1.1 UDP received 'time 43 mSec average time 69 mSec errors 43
From IP /192.168.1.1 UDP received 'time 92 mSec average time 69 mSec errors 44
From IP /192.168.1.1 UDP received 'time 0 mSec average time 69 mSec errors 45
From IP /192.168.1.1 UDP received 'time 72 mSec average time 69 mSec errors 45
From IP /192.168.1.1 UDP received 'time 112 mSec average time 69 mSec errors 46
From IP /192.168.1.1 UDP received 'time 31 mSec average time 69 mSec errors 47
From IP /192.168.1.1 UDP received 'time 92 mSec average time 69 mSec errors 48
From IP /192.168.1.1 UDP received 'time 63 mSec average time 69 mSec errors 49
From IP /192.168.1.1 UDP received 'time 10 mSec average time 69 mSec errors 50
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 50
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 50
From IP /192.168.1.1 UDP received 'time 70 mSec average time 69 mSec errors 50
From IP /192.168.1.1 UDP received 'time 70 mSec average time 69 mSec errors 50
From IP /192.168.1.1 UDP received 'time 21 mSec average time 69 mSec errors 51
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 51
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 51
From IP /192.168.1.1 UDP received 'time 71 mSec average time 69 mSec errors 51
From IP /192.168.1.1 UDP received 'time 73 mSec average time 69 mSec errors 51

I print the time etc every 10 UDP datagrams received or if I get an error which is a time <=65 or >-75 where errors count is incrementsed
it can be seen the average time I am getting is around 70mSec
however, you can see there are occasions when time is outside 65 or 75mSec
I am running on a Wondows 10 system which is multiprocessing so it is running other processes apart from the UDP receiver so there is variation as other processes use the processors ans the network
what operating system are you running and what other process are executing?
is your network very busy?

you are using an ESP32 to transmit UDP datagrams to your servo but don't mention what controls the servo?
if it is another ESP32 and the distance between the devices is not too large you could use ESP-NOW
e.g. a ESP32 send a packet to another ESP32 every 70mSec - receiver output

ESP32 Board MAC Address:  84:CC:A8:7A:56:6C
Test 10 Bytes received: 44 time = 70 average = 69.90 errors = 0
Test 20 Bytes received: 44 time = 70 average = 69.95 errors = 0
Test 30 Bytes received: 44 time = 70 average = 69.97 errors = 0
Test 40 Bytes received: 44 time = 70 average = 69.97 errors = 0
Test 50 Bytes received: 44 time = 70 average = 69.98 errors = 0
Test 60 Bytes received: 44 time = 70 average = 69.98 errors = 0
Test 70 Bytes received: 44 time = 70 average = 69.99 errors = 0
..
Test 1730 Bytes received: 44 time = 70 average = 69.98 errors = 0
Test 1740 Bytes received: 44 time = 70 average = 69.98 errors = 0
Test 1750 Bytes received: 44 time = 70 average = 69.98 errors = 0
Test 1760 Bytes received: 44 time = 70 average = 69.98 errors = 0
Test 1770 Bytes received: 44 time = 70 average = 69.98 errors = 0
Test 1780 Bytes received: 44 time = 70 average = 69.98 errors = 0
Test 1790 Bytes received: 44 time = 70 average = 69.98 errors = 0
Test 1797 Bytes received: 44 time = 75 average = 69.99 errors = 1
Test 1798 Bytes received: 44 time = 65 average = 69.98 errors = 2
Test 1808 Bytes received: 44 time = 70 average = 69.98 errors = 2
Test 1818 Bytes received: 44 time = 70 average = 69.98 errors = 2
...
Test 2518 Bytes received: 44 time = 70 average = 69.99 errors = 2
Test 2528 Bytes received: 44 time = 70 average = 69.99 errors = 2
Test 2538 Bytes received: 44 time = 70 average = 69.99 errors = 2
Test 2548 Bytes received: 44 time = 70 average = 69.99 errors = 2
Test 2558 Bytes received: 44 time = 70 average = 69.99 errors = 2
Test 2563 Bytes received: 44 time = 73 average = 69.99 errors = 3
Test 2564 Bytes received: 44 time = 67 average = 69.99 errors = 4
Test 2574 Bytes received: 44 time = 70 average = 69.99 errors = 4
Test 2584 Bytes received: 44 time = 70 average = 69.99 errors = 4
Test 2594 Bytes received: 44 time = 70 average = 69.99 errors = 4
Test 2604 Bytes received: 44 time = 70 average = 69.99 errors = 4
Test 2614 Bytes received: 44 time = 70 average = 69.99 errors = 4
Test 2624 Bytes received: 44 time = 70 average = 69.99 errors = 4
Test 2634 Bytes received: 44 time = 70 average = 69.99 errors = 4
Test 2644 Bytes received: 44 time = 70 average = 69.99 errors = 4
Test 2654 Bytes received: 44 time = 70 average = 69.99 errors = 4
Test 2664 Bytes received: 44 time = 70 average = 69.99 errors = 4
Test 2674 Bytes received: 44 time = 70 average = 69.99 errors = 4
...
Test 5614 Bytes received: 44 time = 70 average = 69.99 errors = 8
Test 5624 Bytes received: 44 time = 70 average = 69.99 errors = 8
Test 5634 Bytes received: 44 time = 70 average = 69.99 errors = 8
Test 5644 Bytes received: 44 time = 70 average = 69.99 errors = 8

errors is incremented if time between packets is <=68 or >= 72
there can still be delays when WiFi network is busy

Thank you. Did you connect multiple clients? The problem starts when the second client is connected (i.e iPhone or another ESP, besides the PC). Otherwise, I get the same results you do on my PC. However, my application will have three servos connected (three different clients).

I am using windows 10.
are using an ESP32 to transmit UDP datagrams to your servo but don't mention what controls the servo?
There is another ESP32 receiving the signal and driving the servo. Everything works as it should, but as soon a another ESP32 connects, or my phone, it starts sending the cluster packets with delays. Below is the output with just one client:

think we require an overview of the system
how many servos are there? do they exchangecontrol data or is there a central controller?

Currently there is only one servo. There is one ESP32 sending a position message over UDP, and another ESP32 receiving the position message and sending a pwm signal to a servo. Eventually there will be a Phone connected, and two other ESP32s listening to the same message and driving two more servos independently. However, I don't want to move on to developing the receiving end and control anything if the ESP32 is not capable of sending data without the 200 ms delay. So for now, I'm testing without servos. Lets assume there are no servos in this application. Just one PC connected and three iPhones. You can see the transmission rate changes as soon as you connect a second client, even if the client is not receiving data on a socket. Just the act of connecting to the softAP, drops the data rate. Do you get the same results? or is it just me?

It sounds like a symptom of buffered I/O. Do you have a flush() method to call after each write()?

if you have one controller sending UDP datagrams to control multiple servos could you use UDP multicast?
the controller sends a single UDP multicast datagram which contains the commands for all the servos
all the servos receive the datagram and extract the information appropriate to them ?

I mentioned ESP-NOW as an alternative to UDP - ESP-NOW also supports multicast

i do not. where/how should I implement this?

Horace, I believe ESP-NOW does not let an iPhone connect as a client/peer. The smartphone(s) are the controller interface. Does I believe I'm not able to use this setup.

you can run ESP-NOW (communicate between the controller and slaves) and WiFi (to communicate with the smart phone) on the same device
an alternative to ESP-NOW is ESP-MESH for ESP32 and ESP8266 dvices - there is also ESP-MESH for Android

thanks! will try this.

I just took a look at the source for WiFiUdp.h, and it shows there is a flush() method defined. After the last write to each packet, try inserting a call to that method. That should at the very least cause the program to wait until all those bytes are sent out. Without reading more code I'm not sure this will fix it (not sure the I/O is really buffered for this class) but it is easy enough to try.

this is the documentation for wifiudp.flush - Discard any bytes that have been written to the client but not yet read?

Looks like flush() just calls endPacket() which he's already calling, so maybe that's not it.

Hey, just wanted to let you know that after implementing ESP-NOW I'm able to send packets at 70ms and my other three ESP modules receive it perfectly. There is no delay or message clusters. I implemented the Soft-AP protocol on the master, and it is also working perfectly connected to the iPhone.
Thank you so much for the suggestion and helping me through the development!!

For others reference, I tried ESP-WROOM-32D, WROOM-32E, esp32-c3-mini and ESP32-S3, they ALL have the same behavior when sending UDP data at 70 ms to multiple clients. The modules send a cluster of three packets and then a 200ms delay.

good to hear it is now working OK
an alternative could be sending the same message to all slaves using ESP-NOW multicast where the receivers MAC address on transmission is 0, e.g.

esp_now_send(0, (uint8_t *) &test, sizeof(test))

all slaves receive the same message and pick out from the overall message sections specific to them

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.