-
-
Notifications
You must be signed in to change notification settings - Fork 264
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
Update WS2812X ESP32 RMT timing for WS2815 compat #795
base: master
Are you sure you want to change the base?
Conversation
The existing values are out of spec for WS2815 which results in flickering, especially on longer cable runs. These new RMT values are still closer to ideal WS2812B specs than the current I2S WS2812X timing (about 310us / 940us). | | T0H | T1H | T0L | T1L | | ----------------------- | ------- | --------- | -------- | ------- | | WS2812B | 250-550 | 650-950 | 700-1000 | 300-600 | | WS2815 | 220-380 | 580-1600 | 580-1600 | 220-420 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The WS2815 and WS2812 are not the same chip nor the same timing specs. This is the wrong place to make a modification. The WS2812x fits a large "swath" of chips that state they are WS2812 but all vary slightly in timing. Adding a another more extreme restriction is not the solution.
Also note, this library supports more than the ESP32 RMT, so whatever changes needed must be applied across all the methods, including others for ESp32 like i2s.
The WS2814 and WS2805 are present in Master and updated, WLED hasn't picked up the latest changes to these yet. Could you give one of these a try to see if they are compatible as they are closer to the WS2815.
@@ -313,8 +313,8 @@ class NeoEsp32RmtInvertedSpeedWs2811 : public NeoEsp32RmtInvertedSpeedBase | |||
class NeoEsp32RmtInvertedSpeedWs2812x : public NeoEsp32RmtInvertedSpeedBase | |||
{ | |||
public: | |||
const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(400, 850); | |||
const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(800, 450); | |||
const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(315, 935); // WS2812B / WS2815 compat compromise |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WS2812x is the wrong place to add support for WS2815
Further checks, While the WS2805/WS2814 might function, the WS2815 might have the same issue as previous WS2812 chips, in that the overall kbps must be no faster than 800kbps. Looking at the very latest update on the spec sheet, they added an addition that was not present before in the spec sheets I have. |
The Tm1914 which is already present is close, also try it. Increasing its reset to 300us and aliasing it to WS2815 would make it fully compatible. |
Hmm you're right with the newer WS2815 datasheet, they seem to be very inconsistent. I'll do some more research to summarise these and do some more scientific testing to determine the limits of my WS2815. I haven't tried Tm1914 yet but I did try NeoEsp32RmtSpeedWs2811 which appeared to be even closer to the specs than Tm1914, but there was still flickering. So my testing so far: Stable
Unstable, occasional flickering
|
Datasheet summary
I noticed that WS2811 has exactly the same timing spec as the earlier WS2815 variants. I'm ignoring the T1L value for WS2815B-V1 2.0 and assuming that this is actually 220-420 like WS2811. Additional testingConstant 1250us Tdata, T1L = T0H+50
I only realised after this testing that there is a 25us quantum with ESP32 RMT, so I think all of these values were actually rounded down to the nearest 25us resulting in a Tdata of 1225us for each test. Regardless, I think this confirmed the WS2812 RMT timing is extremely marginal with WS2815 LEDs and going slightly further out of spec by increasing T0H & T1L resulted in much more corruption. Constant 350us T0H, 400us T1L
Constant 300us T0H, 350us T1L
I think my initial test with NeoEsp32RmtSpeedWs2811 was flawed and that the corruption I saw was probably due to WiFi interrupt shortly after WLED startup, or I just made a typo. The datasheets & further testing show that the existing WS2811 timing seems to be good for my WS2815, and also within the published specs for WS2815B-V1 2.0 (ignoring an obviously wrong value in the datasheet). So maybe there is not much to do here except add an alias from WS2815 to WS2811? Instead I will turn my attention to WLED and try authoring a PR to split their "WS281X" mode into:
|
Yeah, I will be adding a WS2815 aliases into NeoPixelBus, see newly created issue to track this. But in general, WLED will be minimizing the number of specific methods they use to a set that are considered "compatible" to reduce the option matrix, so in the future they may expose WS2815 but may only map to the WS2811 anyhow. |
Just to chime in regarding WLED. @rmounce I've talked to @Makuna about the reduction of methods used to save some additional RAM and flash. Introducing new methods - or better - adding variation of existing methods will be very low on TODO list for WLED. PR or not. @Makuna would there be a simpler way to call some base class virtual functions instead of what we do now? case I_32_RN_NEO_3: (static_cast<NeoPixelBusLg<NeoGrbFeature, NeoEsp32RmtNWs2812xMethod, NeoGammaNullMethod>*>(busPtr))->Show(consistent); break; |
Virtual functions add code and heap usage. The model I went with reduces it, so the library works on small AVRs (ATTINY with between 64-512 bytes of total RAM for stack and heap) the original target I built the library for. WLED and a few others are unique in that they require dynamic reconfiguration across all features. Most users don't need this. I am investigating into "virtual" Features and Methods for those platforms that can dismiss the loss of 30 to 300 bytes of RAM and code space (because they would already spend it working around the lack of dynamic configuration). But some "reconfiguration" will still require memory churn, going from RGB to RGBW or even WS2812x to SM168xx requires back buffers to be released and reallocated. Not to mention one wire (NeoPixel) vs two wires (Dotstars). |
Just to toss in on the "overall kbps must be no faster than 800kbps" timing, my I don't know what I'm doing experiments with NeoPixelBus show I can push RMT at 1.333MHz and it's stable... enough? These are allegedly WS2812b pixels, according to the AliExpress listing. I also shortened the break, which I found entirely too long and that helps loop around faster too. 208 FPS on 256 pixels, 52 here on 1024 pixels in a chain. Probing the end of the chain show the "clock" was propagated all along the panels. PXL_20240329_205309319.mp4 |
Individual experience on the reset timing will vary, as true/real WS2812x (b,c,etc) officially need at least 280us. Clones/fakes can be all over the place, from 50us to 300us. This is why it was set to 300us. The issue with overall speed comes from longer strips. If you have 300 pixels, with official/real WS2812x you will see glitches after about 60 pixels. And this was running at 833Kbps. |
Thank you! I am also running 2 WS2813 LED strips (79 and 78 leds respectively) on a d1 mini ESP32 running WLED (0.15.0-b7), and I kept having the 1st led on the 2nd strip flicker occasionally triggering the whole strip to flicker (inverting the strips order changed which strip flickered telling me it wasn't a wiring/hardware issue). Setting the second strip to Apa106 indeed fixes the problem. One small note, manually updating NeoPixelBus from the default 2.8.0 to 2.8.3 seemed to make the issue worse. |
Context
I'm using WLED and have been trying to troubleshoot flickering issues for a while now with my WS2815 LED strips from BTF-Lighting. I have about 6 metres of cable between my controller and each strip, and have taken the following measures so far:
These efforts cleaned up the data signal and reduced flickering considerably, but it never went away until I upgraded to WLED 0.15 beta. This finally fixed the flickering for one of my two LED strips! A bit more investigation showed that WLED changed to I2S by default for the first output, which has different timing to RMT. And reading the WS2815 datasheet showed that the RMT timing for WS2812B is out of the specs for WS2812.
Commit Summary
The existing values are out of spec for WS2815 which results in flickering, especially on longer cable runs.
These new RMT values are still closer to ideal WS2812B specs than the current I2S WS2812X timing (about 310us / 940us).
Datasheet specs:
Note for ESP32 WLED users interested in this PR
To resolve flickering issues in the meantime, upgrade to WLED 0.15 beta. For more than 1 output, this also adds APA106 support which uses compatible timings with WS2815 on the second output.