Makuna / NeoPixelBus

An Arduino NeoPixel support library supporting a large variety of individually addressable LEDs. Please refer to the Wiki for more details. Please use the GitHub Discussions to ask questions as the GitHub Issues feature is used for bug tracking.
GNU Lesser General Public License v3.0
1.18k stars 265 forks source link

NeoEsp32I2s1Ws2812xMethod jitters #751

Closed wangnick closed 10 months ago

wangnick commented 11 months ago

Describe the bug The data stream produced by NeoEsp32I2s1Ws2812xMethod is jittering between 1200ns and 1263ns per bit. DS1Z_QuickPrint3DS1Z_QuickPrint5

To Reproduce Compile and deploy attached NeoPixelBusEsp32I2s1Jitter.ino. Check data stream on GPIO27 with oscilloscope.

Expected behavior Bits should always be 1250ns long. Attached Esp32I2s1NoJitter demonstrates that this is possible on ESP32. DS1Z_QuickPrint7DS1Z_QuickPrint6

Development environment (please complete the following information):

Minimal Sketch that reproduced the problem: NeoPixelBusEsp32I2s1Jitter.ino.txt Esp32I2s1NoJitter.ino.txt

Additional context I recognised the issue because my old WS2812B start flickering when the bit timing is fluctuating.

Makuna commented 11 months ago

Notes on your example for no Jitter: It is not using DMA memory for the buffer. So internally to the core API it is using its own set of DMA buffers that it fills from your memory buffer. Thus, it is a blocking call until it is sent and also causes interrupts to trigger to keep the DMA buffer full as it gets drained. Not an ideal solution or comparison.

I have no in-site into their core code to see the details of what they do or not do that would improve this. Most of the code is derived from their initial code before they exposed the driver model, with a sprinkling of what has been learned by the community. It is not well documented as to what each config does. Lots of trial and error to get it to this point.

One thing you could try until I can find time to look into this more... In the file Esp32_I2c.c, you will find this line

    clkm_conf.clka_en = 0;

Change the value to being set to 1. This was on my list to further investigate why examples were disabling the clock for ESP32 but not for other variants (ESPS2/C3, etc).

Makuna commented 11 months ago

@wangnick Thanks for being detailed and providing the two example sketches. It helps a lot. I think I have an initial plan for deeper investigate thanks to them.

wangnick commented 11 months ago

I am currently investigating the new i2s_std.h API of ESP-IDF 5. It allows non-blocking transmissions. I have some initial example code. But it seemingly also comes with its own set of quirks, refer https://esp32.com/viewtopic.php?f=13&t=37349. Also, its unclear when Arduino-Esp32 will migrate, and when the users will follow ...

Btw, clka_en = 1 was one of the first things I tried, before raising this issue. But I recall it did not help.

Makuna commented 11 months ago

Ok, after spending some time with tons of debug code and writing some python to enhance logic analyzer decoder so it calculated the deltas for bits; I can see a 64ns variability in pulse width and the pulse period. I tried every setting difference other than the clock calculation values and it did nothing to improve it.

But when I hardcoded their clock values for a test, it then dropped to 1ns or less variability. This makes me believe that they know from the four hardware clock variables that are applied to make the final frequency, that certain variables will cause less accuracy over others when applying them.

So, I need to reevaluate how the final clock is calculated to try to mimic their priority.

FOUR variables to provide a working clock frequency!

Makuna commented 11 months ago

@wangnick I believe I have a solid solution. I still need to test the parallel modes before merging into master, but you can use the following branch to test it out.

https://github.com/Makuna/NeoPixelBus/tree/Esp32I2sJitter

wangnick commented 11 months ago

you can use the following branch to test it out. https://github.com/Makuna/NeoPixelBus/tree/Esp32I2sJitter

@makuna, I confirm that with the fixes on that branch the ESP32 I2S signal is now stable, with no observable jitter (at 1GSa/s). And my LEDs don't flicker anymore. Well done!

Makuna commented 10 months ago

https://github.com/Makuna/NeoPixelBus/pull/754

Makuna commented 10 months ago

v2.7.8