Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NeoEsp32I2s1Ws2812xMethod jitters #751

Closed
wangnick opened this issue Dec 15, 2023 · 8 comments
Closed

NeoEsp32I2s1Ws2812xMethod jitters #751

wangnick opened this issue Dec 15, 2023 · 8 comments
Assignees
Labels
bug pending Pending new release; already merged but not released in a version

Comments

@wangnick
Copy link

wangnick commented Dec 15, 2023

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):

  • OS: Win10
  • Build Environment: Arduino 1.8.19, esp32 2.0.14
  • Board target: ESP32 Dev Module
  • Library version: NeoPixelBus 2.7.7

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
Copy link
Owner

Makuna commented Dec 15, 2023

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 Makuna self-assigned this Dec 15, 2023
@Makuna Makuna added the investigating Currently under investigation for more understanding of the problem. label Dec 16, 2023
@Makuna
Copy link
Owner

Makuna commented Dec 16, 2023

@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
Copy link
Author

wangnick commented Dec 16, 2023

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
Copy link
Owner

Makuna commented Dec 23, 2023

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
Copy link
Owner

Makuna commented Dec 27, 2023

@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

@Makuna Makuna added bug active development This issue is a primary item I am actively working on. Interested testers add a comment. and removed enhancement investigating Currently under investigation for more understanding of the problem. labels Dec 27, 2023
@wangnick
Copy link
Author

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
Copy link
Owner

Makuna commented Jan 4, 2024

#754

@Makuna Makuna added pending Pending new release; already merged but not released in a version and removed active development This issue is a primary item I am actively working on. Interested testers add a comment. labels Jan 4, 2024
@Makuna
Copy link
Owner

Makuna commented Jan 19, 2024

v2.7.8

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug pending Pending new release; already merged but not released in a version
Projects
None yet
Development

No branches or pull requests

2 participants