wezhunter / ESP32_LinuxCNC_MotionController_RealTime

ESP32 hardware based real-time LinuxCNC motion controller
GNU General Public License v3.0
16 stars 10 forks source link

Improve performance #4

Closed BogdanTheGeek closed 8 months ago

BogdanTheGeek commented 9 months ago

You can add these to your sdkconfig to maximise the udp performance:

CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=4096

CONFIG_FREERTOS_UNICORE=n
CONFIG_FREERTOS_HZ=1000

CONFIG_ESP_INT_WDT=n
CONFIG_ESP_TASK_WDT_EN=n

CONFIG_LWIP_ETHARP_TRUST_IP_MAC=n
CONFIG_LWIP_IRAM_OPTIMIZATION=y
CONFIG_LWIP_TCPIP_TASK_PRIO=23

CONFIG_IPERF_TRAFFIC_TASK_PRIORITY=23
CONFIG_IPERF_REPORT_TASK_PRIORITY=24
CONFIG_LWIP_TCPIP_CORE_LOCKING=y
CONFIG_LWIP_TCPIP_CORE_LOCKING_INPUT=y
CONFIG_COMPILER_OPTIMIZATION_PERF=y

#
# ESP32-specific
#
CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=16
CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=64
CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=64
CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y
CONFIG_ESP_WIFI_TX_BA_WIN=32
CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y
CONFIG_ESP_WIFI_RX_BA_WIN=32

CONFIG_LWIP_TCP_SND_BUF_DEFAULT=65534
CONFIG_LWIP_TCP_WND_DEFAULT=65534
CONFIG_LWIP_TCP_RECVMBOX_SIZE=64
CONFIG_LWIP_UDP_RECVMBOX_SIZE=64
CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=64

CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
CONFIG_ESPTOOLPY_FLASHFREQ_40M=y

CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=240

You might also want to test higher priorities for the udp task (21 decresses the jitter a lot for me).

Here is the reference: https://github.com/espressif/esp-idf/blob/v5.2/examples/wifi/iperf/sdkconfig.defaults

wezhunter commented 8 months ago

Excellent - thank you for this! I was planning on optimising lwip within the Arduino core and esp-idf SDK config defaults via PIO but not quite gotten round to it just yet so you've probably saved me quite a bit of time.

I will give them a go and test in detail very soon I have a significant refactor commit coming with loads of new features to make it completely board type agnostic and a full serial console for config management. There will be two firmware versions - SPI ethernet and Native. Both Motion Controller and ESP-NOW Client features are integrated into the same firmware too, effectively it hopefully becomes an "ESP32 ecosystem" for LinuxCNC Oh... as well as a full featured simulator of an ESP32 for rapid development and GDB debugging.

Tasks have changed quite a bit in the new version but shall review again based on your advice just to be sure

BogdanTheGeek commented 8 months ago

I have done some extensive testing and optimising of latency on the esp32. the biggest problem with spi and wifi is jitter, here is an example between an spi , rmii ethernet PHY and wifi: image image image

Wifi does have good throughput, but the jitter is a bit high, spi has less jitter, but less performance too. A dedicated RMII interface is as good as you can get.

wezhunter commented 8 months ago

Nice work! Thank you

Yeah pretty much as expected. Packet jitter shouldn't necessarily be a major issue for positional commands since the command position is buffered by FAS library and the host. It will affect feedback pos/vel though especially once quad encoder feature is added and LinuxCNC pid is enabled. I'll certainly add your data onto the readme and docs to ensure people are aware and why RMII PHY is the best option all round.

Also, I know, based on my own past projects that the USB device mode RNDS/ECM virtual networking on the S2/S3 will be a ultimate seamless plug-and-play solution since it is actually surprisingly low latency for a virtual network adapter. Only at 10Mbps link speed but that doesn't matter for this use case. Having a USB controller you just plug in, sets itself up and works would be nice. USB EMI issues can typically be resolved with a good shielded cable - mach3 controllers are mostly usb based so it's a non-issue really

wezhunter commented 8 months ago

Also, just to make you aware. I am aware of some minor motor velocity jitter (not quite smooth) when ramping up at reasonable speeds and is noticeable on a scope connected to a step pin. The pulse train wanders slightly when accelerating. It's not a performance related issue. LinuxCNC commanded velocity is clipping as it ramps up in the FAS library. FAS expects a single target velocity for the movement command but LinuxCNC sends a ramped velocity per movement. I've tested "vel_limit" which is the current set max velocity based on jogging feedrates in LinuxCNC and produces nice a smooth pulse train. However it's not updated when a job is running or using feedrate overrides. I intend to solve it somehow - it's resolvable one way or another and may need a minor LinuxCNC PR. Unsure just yet...

kzali commented 8 months ago

HI Wezhunter Have you considered setting up a discussions tab? It may be better than issues. just a suggestion. Excited to see your work!

wezhunter commented 8 months ago

Good point. Apologies for the spam. Done

kzali commented 8 months ago

Good point. Apologies for the spam. Done

Not Spam and thanks