From 1ff3ff43e4dbf81b414d4c3ff51dfba435e872a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Mon, 18 Aug 2025 20:24:48 +0300 Subject: [PATCH] Make the ESP-IDF v5.x RMT driver execute faster --- .../src/lib/adafruit-Adafruit_NeoPixel/esp.c | 42 +++++++++++++------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/Software/src/lib/adafruit-Adafruit_NeoPixel/esp.c b/Software/src/lib/adafruit-Adafruit_NeoPixel/esp.c index ec08e7d5..d056fda6 100644 --- a/Software/src/lib/adafruit-Adafruit_NeoPixel/esp.c +++ b/Software/src/lib/adafruit-Adafruit_NeoPixel/esp.c @@ -2,11 +2,15 @@ #include "driver/rmt_tx.h" // This code is adapted for the ESP-IDF v5.x RMT driver API // WS2812 timing parameters (in nanoseconds) -#define WS2812_T0H_NS 350 -#define WS2812_T0L_NS 1000 -#define WS2812_T1H_NS 900 -#define WS2812_T1L_NS 350 +#define WS2812_T0H_NS (400) +#define WS2812_T0L_NS (850) +#define WS2812_T1H_NS (800) +#define WS2812_T1L_NS (450) #define WS2812_RESET_US 280 +#define WS2812_T0H_TICKS (WS2812_T0H_NS / 25) +#define WS2812_T0L_TICKS (WS2812_T0L_NS / 25) +#define WS2812_T1H_TICKS (WS2812_T1H_NS / 25) +#define WS2812_T1L_TICKS (WS2812_T1L_NS / 25) static rmt_channel_handle_t led_chan = NULL; static rmt_encoder_handle_t led_encoder = NULL; @@ -131,23 +135,35 @@ err: return ret; } -void espShow(uint8_t pin, uint8_t* pixels, uint8_t numBytes) { - if (led_chan == NULL) { +void espShow(uint8_t pin, uint8_t* pixels, uint32_t numBytes) { + static bool initialized = false; + + if (!initialized) { rmt_tx_channel_config_t tx_chan_config = { .clk_src = RMT_CLK_SRC_DEFAULT, .gpio_num = pin, .mem_block_symbols = 64, - .resolution_hz = 10 * 1000 * 1000, + .resolution_hz = 40 * 1000 * 1000, // 40 MHz .trans_queue_depth = 4, }; ESP_ERROR_CHECK(rmt_new_tx_channel(&tx_chan_config, &led_chan)); - ESP_ERROR_CHECK(rmt_new_led_strip_encoder(&led_encoder)); + + rmt_bytes_encoder_config_t bytes_encoder_config = { + .bit0 = { .level0 = 1, .duration0 = WS2812_T0H_NS / 25, + .level1 = 0, .duration1 = WS2812_T0L_NS / 25 }, + .bit1 = { .level0 = 1, .duration0 = WS2812_T1H_NS / 25, + .level1 = 0, .duration1 = WS2812_T1L_NS / 25 }, + .flags.msb_first = 1 + }; + ESP_ERROR_CHECK(rmt_new_bytes_encoder(&bytes_encoder_config, &led_encoder)); + ESP_ERROR_CHECK(rmt_enable(led_chan)); + initialized = true; } - rmt_transmit_config_t tx_config = { - .loop_count = 0, - }; + rmt_transmit_config_t tx_config = { .loop_count = 0 }; ESP_ERROR_CHECK(rmt_transmit(led_chan, led_encoder, pixels, numBytes, &tx_config)); - ESP_ERROR_CHECK(rmt_tx_wait_all_done(led_chan, portMAX_DELAY)); -} \ No newline at end of file + + // optional: only wait if strict timing required + // ESP_ERROR_CHECK(rmt_tx_wait_all_done(led_chan, portMAX_DELAY)); +}