fix(ESP32 RMT): make RMT memory block size user-overridable (fixes BLE/WiFi ghost pixels)#922
Open
darkgrue wants to merge 3 commits into
Open
Conversation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…MT_MEM_BLOCK_SYMBOLS Hardcoded mem_block_num=1 (64 symbols, ~40us half-buffer at 800Kbps) allows BLE/WiFi interrupt handlers to preempt the RMT refill ISR and hold the data line idle past the 300us LED latch threshold, producing ghost pixels at 8-pixel intervals. Add NEOPIXELBUS_RMT_MEM_BLOCK_SYMBOLS (default 64, backward-compatible). Projects with active BLE or WiFi can set -D NEOPIXELBUS_RMT_MEM_BLOCK_SYMBOLS=512 to allocate 8 memory blocks (320us half-buffer), eliminating false latches. Fixes: Makuna#921 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When a BLE or WiFi connection is active on ESP32, sparse LED patterns produce ghost pixels at index N+8 for every addressed pixel N. The defect scales with strip position and is introduced during RMT transmission, not in the software color buffer.
Root cause:
config.mem_block_num = 1allocates a single 64-symbol RMT memory block. With ping-pong DMA, the RMT refill ISR must be serviced within ~40 µs at WS2812x 800 Kbps. NimBLE and WiFi event handlers run at higher interrupt priority than the RMT refill ISR and routinely preempt for longer, leaving the data line idle past the ~300 µs LED latch threshold.Fixes #921.
Solution
Add a user-overridable preprocessor macro
NEOPIXELBUS_RMT_MEM_BLOCK_SYMBOLSthat controls the number of RMT memory blocks allocated.Default (backward compatible): 64 symbols →
mem_block_num = 1(unchanged behavior)BLE/WiFi fix: add to build flags:
This allocates 8 memory blocks; the ping-pong half-buffer holds 256 symbols × 1.25 µs = 320 µs, which exceeds the 300 µs latch threshold.
Changes
src/internal/methods/NeoEsp32RmtMethod.h:#ifndef NEOPIXELBUS_RMT_MEM_BLOCK_SYMBOLS/#define NEOPIXELBUS_RMT_MEM_BLOCK_SYMBOLS 64/#endifafter theNEOPIXELBUS_RMT_INT_FLAGSblockconfig.mem_block_num = 1;→config.mem_block_num = (NEOPIXELBUS_RMT_MEM_BLOCK_SYMBOLS + 63) / 64;Hardware Constraints
On the original ESP32 (8 RMT channels × 64 symbols each), setting
NEOPIXELBUS_RMT_MEM_BLOCK_SYMBOLS=512consumes all 8 channels' memory for one strip. Users running multiple simultaneous RMT strips must choose a value that fits within available channels. Recommended values by use case:mem_block_numTesting
Verified by the issue reporter's reproduction sketch (ESP32 + NimBLE server, single pixel set to red):
-D NEOPIXELBUS_RMT_MEM_BLOCK_SYMBOLS=512: only pixel 0 lights