s00500 / ESPUI

A simple web user interface library for ESP32 and ESP8266

Home Page:https://valencia.lbsfilm.at/midterm-presentation/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Need Advice on Reducing Control Latency (improve response times)

thomastech opened this issue · comments

** QUESTION **

/* I searched the issue database for a similar discussion and did not find anything regarding my situation. So I think I'm doing something wrong. */

I'm running recently released (5 days ago) ESPUI on a ESP32. The GUI has over forty controls that span six tabs. Application being developed is FM transmitter control.

Function-wise, ESPUI is working fine. But GUI latency is a nuisance. For example, if I press a web button the GUI updates take up to 1 second to occur. Sometimes they are immediate, but long delays occur often. And pressing a button any faster than 1S will usually result in the "ERROR: Too many messages queued" and the queued presses can take several seconds to complete.

There are two controls updated in the background. One update occurs every 1 Sec, another every 2.5 Secs. Beyond that, the only time a ESPUI control (Label or Text) is updated is from pressing a button.

I've checked my main loop and total execution time for all code is 1mS maximum (no blocking code). Pinging the device results in times ranging from 6mS to 400mS. And I've experimented with ESPUI.jsonUpdateDocumentSize & ESPUI.jsonInitialDocumentSize. But no joy.

Except if I run in AP mode the latency is acceptable. So I moved my device's WiFi access to my access point router (quieter traffic) and STA ping times are much better. But the latency issue still occurs.

So I'm looking for advice on how to improve response times. Perhaps there are some known recommendations that I can apply to my project.

  • Thomas

A latency of 400ms to the ESP seems quite bad. I set up a ping to one of mine and started fiddling with my test UI (which contains over 100 controls!), refreshing the page etc. without it having any appreciable effect:

64 bytes from 192.168.1.158: icmp_seq=10 ttl=255 time=4.120 ms
64 bytes from 192.168.1.158: icmp_seq=11 ttl=255 time=3.942 ms
64 bytes from 192.168.1.158: icmp_seq=12 ttl=255 time=5.226 ms
64 bytes from 192.168.1.158: icmp_seq=13 ttl=255 time=4.353 ms
64 bytes from 192.168.1.158: icmp_seq=14 ttl=255 time=3.179 ms
64 bytes from 192.168.1.158: icmp_seq=15 ttl=255 time=3.847 ms
64 bytes from 192.168.1.158: icmp_seq=16 ttl=255 time=6.676 ms
64 bytes from 192.168.1.158: icmp_seq=17 ttl=255 time=3.418 ms
64 bytes from 192.168.1.158: icmp_seq=18 ttl=255 time=4.092 ms
64 bytes from 192.168.1.158: icmp_seq=19 ttl=255 time=3.370 ms
64 bytes from 192.168.1.158: icmp_seq=20 ttl=255 time=4.540 ms
64 bytes from 192.168.1.158: icmp_seq=21 ttl=255 time=5.125 ms
64 bytes from 192.168.1.158: icmp_seq=22 ttl=255 time=7.329 ms
64 bytes from 192.168.1.158: icmp_seq=23 ttl=255 time=9.543 ms
64 bytes from 192.168.1.158: icmp_seq=24 ttl=255 time=2.682 ms
64 bytes from 192.168.1.158: icmp_seq=25 ttl=255 time=3.860 ms

The highest I saw was still below 10ms. Can this be an issue with your Wi-Fi or hardware?

@iangray001, thanks for checking your installation. I'm envious!

I installed the Library's example gui.ino on the same device (TTGO T8 ESP32 board) and had it connect to my "fast" network. I still see the "ERROR: Too many messages queued" if I rapidly (~twice per sec) press the "Other Button" control. As with my project, the presses are queued and take a couple seconds to play out.

And unusual behavior was observed. If I rapidly press the "Other Button" (which updates a label and panel color) the ping times drop like a rock, often under 5mS.

Here are the ping results when I don't press the "Other Button" control:

Pinging 192.168.1.14 with 32 bytes of data:
Reply from 192.168.1.14: bytes=32 time=63ms TTL=255
Reply from 192.168.1.14: bytes=32 time=78ms TTL=255
Reply from 192.168.1.14: bytes=32 time=85ms TTL=255
Reply from 192.168.1.14: bytes=32 time=91ms TTL=255
Reply from 192.168.1.14: bytes=32 time=104ms TTL=255
Reply from 192.168.1.14: bytes=32 time=112ms TTL=255
Reply from 192.168.1.14: bytes=32 time=23ms TTL=255
Reply from 192.168.1.14: bytes=32 time=38ms TTL=255
Reply from 192.168.1.14: bytes=32 time=155ms TTL=255
Reply from 192.168.1.14: bytes=32 time=172ms TTL=255
Reply from 192.168.1.14: bytes=32 time=193ms TTL=255
Reply from 192.168.1.14: bytes=32 time=198ms TTL=255
Reply from 192.168.1.14: bytes=32 time=217ms TTL=255
Reply from 192.168.1.14: bytes=32 time=20ms TTL=255
Reply from 192.168.1.14: bytes=32 time=29ms TTL=255
Reply from 192.168.1.14: bytes=32 time=48ms TTL=255
Reply from 192.168.1.14: bytes=32 time=64ms TTL=255
Reply from 192.168.1.14: bytes=32 time=80ms TTL=255
Reply from 192.168.1.14: bytes=32 time=87ms TTL=255
Reply from 192.168.1.14: bytes=32 time=87ms TTL=255
Reply from 192.168.1.14: bytes=32 time=104ms TTL=255
Reply from 192.168.1.14: bytes=32 time=113ms TTL=255
Reply from 192.168.1.14: bytes=32 time=123ms TTL=255
Reply from 192.168.1.14: bytes=32 time=141ms TTL=255
Reply from 192.168.1.14: bytes=32 time=155ms TTL=255
Reply from 192.168.1.14: bytes=32 time=166ms TTL=255
Reply from 192.168.1.14: bytes=32 time=180ms TTL=255
Reply from 192.168.1.14: bytes=32 time=305ms TTL=255
Reply from 192.168.1.14: bytes=32 time=223ms TTL=255
Reply from 192.168.1.14: bytes=32 time=23ms TTL=255
Reply from 192.168.1.14: bytes=32 time=38ms TTL=255
Reply from 192.168.1.14: bytes=32 time=59ms TTL=255
Reply from 192.168.1.14: bytes=32 time=75ms TTL=255
Reply from 192.168.1.14: bytes=32 time=96ms TTL=255
Reply from 192.168.1.14: bytes=32 time=115ms TTL=255
Reply from 192.168.1.14: bytes=32 time=132ms TTL=255
Reply from 192.168.1.14: bytes=32 time=154ms TTL=255
Reply from 192.168.1.14: bytes=32 time=150ms TTL=255
Reply from 192.168.1.14: bytes=32 time=174ms TTL=255
Reply from 192.168.1.14: bytes=32 time=188ms TTL=255
Reply from 192.168.1.14: bytes=32 time=200ms TTL=255
Reply from 192.168.1.14: bytes=32 time=211ms TTL=255
Reply from 192.168.1.14: bytes=32 time=18ms TTL=255
Reply from 192.168.1.14: bytes=32 time=39ms TTL=255
Reply from 192.168.1.14: bytes=32 time=46ms TTL=255
Reply from 192.168.1.14: bytes=32 time=56ms TTL=255
Reply from 192.168.1.14: bytes=32 time=78ms TTL=255
Reply from 192.168.1.14: bytes=32 time=94ms TTL=255
Ping statistics for 192.168.1.14:
    Packets: Sent = 48, Received = 48, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 18ms, Maximum = 305ms, Average = 112ms

Here's the ping report when I machine-gun the "Other Button" control:

Pinging 192.168.1.14 with 32 bytes of data:
Reply from 192.168.1.14: bytes=32 time=37ms TTL=255
Reply from 192.168.1.14: bytes=32 time=151ms TTL=255
Reply from 192.168.1.14: bytes=32 time=2ms TTL=255
Reply from 192.168.1.14: bytes=32 time=14ms TTL=255
Reply from 192.168.1.14: bytes=32 time=7ms TTL=255
Reply from 192.168.1.14: bytes=32 time=208ms TTL=255
Reply from 192.168.1.14: bytes=32 time=20ms TTL=255
Reply from 192.168.1.14: bytes=32 time=29ms TTL=255
Reply from 192.168.1.14: bytes=32 time=38ms TTL=255
Reply from 192.168.1.14: bytes=32 time=58ms TTL=255
Reply from 192.168.1.14: bytes=32 time=3ms TTL=255
Reply from 192.168.1.14: bytes=32 time=96ms TTL=255
Reply from 192.168.1.14: bytes=32 time=3ms TTL=255
Reply from 192.168.1.14: bytes=32 time=31ms TTL=255
Reply from 192.168.1.14: bytes=32 time=4ms TTL=255
Reply from 192.168.1.14: bytes=32 time=6ms TTL=255
Reply from 192.168.1.14: bytes=32 time=5ms TTL=255
Reply from 192.168.1.14: bytes=32 time=3ms TTL=255
Reply from 192.168.1.14: bytes=32 time=3ms TTL=255
Reply from 192.168.1.14: bytes=32 time=4ms TTL=255
Reply from 192.168.1.14: bytes=32 time=13ms TTL=255
Reply from 192.168.1.14: bytes=32 time=3ms TTL=255
Reply from 192.168.1.14: bytes=32 time=50ms TTL=255
Reply from 192.168.1.14: bytes=32 time=73ms TTL=255
Reply from 192.168.1.14: bytes=32 time=3ms TTL=255
Reply from 192.168.1.14: bytes=32 time=4ms TTL=255
Reply from 192.168.1.14: bytes=32 time=7ms TTL=255
Reply from 192.168.1.14: bytes=32 time=105ms TTL=255
Reply from 192.168.1.14: bytes=32 time=171ms TTL=255
Reply from 192.168.1.14: bytes=32 time=2ms TTL=255
Reply from 192.168.1.14: bytes=32 time=246ms TTL=255
Reply from 192.168.1.14: bytes=32 time=3ms TTL=255
Reply from 192.168.1.14: bytes=32 time=4ms TTL=255
Reply from 192.168.1.14: bytes=32 time=6ms TTL=255
Reply from 192.168.1.14: bytes=32 time=10ms TTL=255
Reply from 192.168.1.14: bytes=32 time=6ms TTL=255
Reply from 192.168.1.14: bytes=32 time=76ms TTL=255
Reply from 192.168.1.14: bytes=32 time=33ms TTL=255
Reply from 192.168.1.14: bytes=32 time=51ms TTL=255
Reply from 192.168.1.14: bytes=32 time=66ms TTL=255
Reply from 192.168.1.14: bytes=32 time=98ms TTL=255
Reply from 192.168.1.14: bytes=32 time=92ms TTL=255
Reply from 192.168.1.14: bytes=32 time=114ms TTL=255
Reply from 192.168.1.14: bytes=32 time=24ms TTL=255
Reply from 192.168.1.14: bytes=32 time=4ms TTL=255
Reply from 192.168.1.14: bytes=32 time=7ms TTL=255
Reply from 192.168.1.14: bytes=32 time=168ms TTL=255
Reply from 192.168.1.14: bytes=32 time=4ms TTL=255
Reply from 192.168.1.14: bytes=32 time=5ms TTL=255
Ping statistics for 192.168.1.14:
    Packets: Sent = 49, Received = 49, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 2ms, Maximum = 246ms, Average = 44ms

If I ping my other ESP8266 devices (home automation stuff) that's on the same network the ping times on them is typically ~3mS and never exceed 20mS. But I also have a couple ESP32 devices and their ping times are much slower (25-220mS).

--> Was your testing on a ESP8266 by chance? Do the ping times eventually grow slower when buttons are no longer pressed?

I'm not even sure if the slow ping times are the main cause of my latency complaint. But seems plausible.

BTW, I'm still trying to understand the log report's "ERROR: Too many messages queued." The ESP32 AsyncWebSocket library reports this only if the queue exceeds 32 messages. That's 4X more than the ESP8266. I have no idea how this limit is being exceeded in my project's code or the ESPUI gui.ino example. That is to say, I can't imagine where are all these json messages are coming from.

  • Thomas

I found the problem. Thanks to Mr. Google. The issue is known to affect the ESP32 and is related to the WiFi sleep feature. As described here: espressif/arduino-esp32#1484

So I added WiFi.setSleep(false); to my project. Ping times are fantastic, averaging 6mS. Button presses very snappy too.
Example of my patch:

    WiFi.setSleep(false);  // Add this, improve ping times.
    WiFi.begin();

EDIT (UPDATE): If I rapidly press a GUI button I can see that some commands are getting queued; They take a moment to catch up after I stop my rapid-fire presses. But I rarely see the "ERROR: Too many messages queued" in the serial log. So another win.

  • Thomas

Hey Thomas, again awesome catch, I was not fully aware of this issue, i might have hit it in the past myself though :-)

After I get my project's demons under control I will create a PR to update all the ESPUI example projects. I think that would help other ESP32 users avoid this nasty problem.

  • Thomas