JSchaenzle / ESP32-NeoPixel-WS2812-RMT

NeoPixel (WS2812) Driver Example code using RMT peripheral
The Unlicense
117 stars 31 forks source link

Would like to see timings for other common LED types #13

Closed trader-dave closed 2 years ago

trader-dave commented 2 years ago

Hi, I'm going to try to incorporate your lib into my project, but I'm going to have to arrive at the RMT bit timings by trial and error since I don't have access to a logic analyzer and I don't use WS2812 (I use WS2812b or WS2811). Below are some bit timing values that I've collected from the various WS28xx datasheets.

That said, I don't understand your "low" timing values. All bits should have a constant time, meaning the microseconds of a 0 bit should be the same as a 1 bit. Unfortunately, the WS2812 datasheet contradicts itself by saying all bit times are 1.25us, then it gives TH/TL values that don't add up to 1.25 (as the other datasheets do). The SparkFun datasheet you reference does give equal 0/1 bit times, but they are 1.71us each. The lights must be able to accept a lot of variance, but it's probably best to get as close as possible to the datasheet values for stability and transmission rate.

I assume that your CPU and peripheral clock speeds are the default values?

Thanks, dave

/ LED TIMINGS, per their datasheets:

ghost commented 2 years ago

I'm working on some improvements to the library, and was going to add some comments explaining timings to use for different types. I have a WS2812, but for some reason have only had success using the timings for the WS2811, which it's compatible with. I wonder if we should change the Kconfig to allow selection of the LED type itself, which would configure appropriate values?

From https://cdn.sparkfun.com/datasheets/Components/LED/adafruit-neopixel-uberguide.pdf :

`My Microcontroller Isn’t Fast Enough to Do That

The WS2812 appears to be backwardly-compatible with the 400 KHz WS2811 signal. If you can precisely match the latter chip’s timing, either type will respond. The WS2811 pro to co l is no t simply a half-speed WS2812. The duty cycle for the “0” and “1” bits is slightly different. From the WS2811 datasheet (http://adafru.it/cDS):

The WS2812 appears to be backwardly-compatible with the 400 KHz WS2811 signal. If you can precisely match the latter chip’s timing, either type will respond. The WS2811 protocol is not simply a half-speed WS2812. The duty cycle for the “0” and “1” bits is slightly different. From the <a href="http://www.adafruit.com/datasheets/WS2811.pdf" title="Link: http://www.adafruit.com/datasheets/WS2811.pdf">WS2811 datasheet<span class="pdf-short-link"> (http://adafru.it/cDS):`

trader-dave commented 2 years ago

Hi Rebecca,

I have tested [my version of] the code with timing values for WS2812b:

define T0H 13 //RMT bit time = 50

define T0L 37

define T1H 38

define T1L 12

Note first this is 2812B, which is different than 2812. Also note that for ALL WS28xx LEDs, the total bit time for a "1" or "0" are the same. For my values, the RMT total bit time is 50. Which is part of my confusion regarding the existing code - a "0" bit is 14+52=66, and a "1" bit is 52+52=104? Doesn't make sense.

2812 (according to the datasheet) has the same bit time as 2812B, it's just that the high-to-low ratios are different. What I think are more accurate values for 2812 are:

define T0H 13 //this is not tested (I've never used 2812)

define T0L 37

define T1H 35

define T1L 15

The bit times for 2811 are 2x the bit times for 2812 and 2812B. Based on their high/low ratios, the values should be:

define T0H 20 //RMT bit time = 100

define T0L 80

define T1H 48

define T1L 52

I haven't tested this yet, but I will in the next month or so; I've got a few existing 2811 projects to port to ESP32.

-dave

ghost commented 2 years ago

I've opened a pull request that adds the timings you originally mentioned to README.md: https://github.com/JSchaenzle/ESP32-NeoPixel-WS2812-RMT/pull/14

Also, I noticed there's a closed PR that looks useful: https://github.com/JSchaenzle/ESP32-NeoPixel-WS2812-RMT/pull/7

The default configuration did not allow for short enough pulses when sending data to WS2812B LED's
Changes

    APB clock source
    Updated timings for T0H, T1H & TL
    Changes clock divide from 2 to 1

Tests

    Compiles and runs on ESP32s2 (Not tested on regular ESP32)
    Checked timings according to [WS2812B datasheet](https://cdn-shop.adafruit.com/datasheets/WS2812B.pdf)
    Tested on 136 WS2812B/ WS2812B-MINI LED's
JoeyStrandnes commented 2 years ago

My issue and PR were posted quite some time ago, I remember that I was having issues with the timings when using the ESP32s2 and WS2812B LEDs. The “data transfer timings” were way to long resulting in a garbled mess on the LED panel (136 LED's).

The difference was an order or two magnitudes to slow so I was forced to use the 80 MHz APB clock source instead of the default clock-source of 1 MHz (if I remember correctly).

The adjusted clock-source and "bit timings" worked great, timings were correct as can be seen in my PR #7, never had any issues after that change.

Not really sure why I closed the issue, didn't get a response for half a year so closed it when someone found it useful. It doesn't seem like the issue was addressed but I've been out of the loop for a long time so might be wrong.

Hope you resolve the issues. //Joseph

trader-dave commented 2 years ago

So I tested the RMT values for WS2811. It was pretty interesting, because the original values I came up with (20, 80, 48, 52) do not work - they simply turn every LED on at full white - meaning that the pixels are interpreting all bits as 1 bits. Using a cheap PC based logic analyzer, the original value timings looked perfect - 0.5us, 2.0us, 1.2us and 1.3us.

I had to tweak the WS2812B timings as well, decreasing the T0H time and increasing the T1H times. I made the same adjustments for WS2811 and it works flawlessly. Go figure... So the working values are:

define T0H 18 //RMT bit time = 100

define T0L 78

define T1H 49

define T1L 51

JoeyStrandnes commented 2 years ago

It's quite odd that the WS2811 does not work with the datasheet timings. Have you tried doubling the data rate? The WS2811 supports both the 400khz mode and 800khz. The timings you posted are for the slow speed. The datasheet says to halve the timings for the high speed mode.

Another thing worth trying is decoding the frame with your logic analyzer. Sigrok pulse view is an open source pc based logic analyzer program that is compatible with a large amount of devices. It supports protocol decoding for the WS28xx LEDs.

You could also try my timings , I've tested them on an ESP32 and WS2812Bs and it's worked without an issue. Don't own any WS2811s... Might also be a hardware related issue for you?

trader-dave commented 2 years ago

The WS2811 supports both the 400khz mode and 800khz. The timings you posted are for the slow speed. The datasheet says to halve the timings for the high speed mode.

Thanks. You know, I've read that datasheet dozens of times but completely missed the one sentence that says that. I tried percentages based on the datasheet values and they didn't work (even though it looks fine in the logic analyzer). I then tried simply using the same values that I use for WS2812B and it works fine.

JoeyStrandnes commented 2 years ago

Glad it finally worked! Its always nice reading things outload or talking to someone else, real easy starring yourself blind on datasheets! Case closed?

trader-dave commented 2 years ago

Yes, thanks! I have since tweaked the timings a bit to bring them a little closer to the datasheet, and this is what I ended up with:

//Bit times for WS2811

define T0H 12

define T0L 38

define T1H 26

define T1L 24

So there is obviously a large range of supported timings.