Fix LED glitches on long strips for C3#5688
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughTwo single-line changes increase the ChangesStrip isUpdating() yield timeout increase
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~3 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
willmmiles
left a comment
There was a problem hiding this comment.
I think this is fine for now. I agree we don't want to take on a lot of complexity to work around a single buggy bus driver.
The alternative near-term approach would be to replace RMT with bitbanging on C3. Trade performance for stability.
Longer term, there may be some advantages to pipelining the current contents of WS2812FX::show(), though mostly on multicore systems with lots of memory. The three stages (blend to _pixels, _pixels mapping to Bus buffers, and Bus show()) could potentially be split in to parallel tasks. With that in hand, it'd be straightforward to implement a "quiesce show" feature. In theory it could be useful for multiplexing the output hardware (eg. sharing an I2C or SPI output via different chip select GPIOs) but I don't think it's worth the effort until we're there.
|
looks reasonable - I think you could even reduce the max delay, 120ms means that someone has a strip that cannot deliver more than 8 FPS. But then, this is an upper limit so it should be safe. Mabe we also need a strip wait in file.cpp - especially in I agree with @willmmiles on most aspects. About "replace RMT with bitbanging on C3" - Why not add bitbang as a general option? Especially on C3 we only have 2 possible outputs pins - it might fit some usecases if we add bitbanged output as an additional pin (or 2?). Let people try - for example when high FPS are less important than reducing wire chain chaos. Think of a sunshade/umbrella with LEDs: you'd want a centered layout with lots of connections, but each "beam" might just be 20-30 LEDs long. |
|
@softhack007 I thought you already added some file read/write improvements? Or was that general sequence fixes? Re bitbang: that can be added but NPB runs them sequentially, getting quite slow if someone does 500+ LEDs. My new driver does support parallel bitbanging and I recently tested that with 8x output, longest one with 1000 LEDs on a C3 and it worked, ISR disabled completely, UI gets slow but no crashes, AR sync still worked ok-ish. Problem with BB in NPB is that it allows ISRs during BB and if timing is violated it stops. So on longer strips the tail end gets way fewer FPS and DDP may be a no-go, did not test that with NPB. |
Just in 0.15.x - the idea (at that time) was to have an ugly hack for the release version, but prefer to implement a proper -C3 RMTHI variant in Edit: To help -C3 users, i could port #5435 to 16.0.0 (as addition after merging this PR) - should be straight forward. What do you think? |
ah now I remember that fix, forgot it was only for 0.15 - porting it for C3 only would make sense for the time being |
|
cherry picked to 16_x |
* increase wait time, remove unnecessary FPS check
increase wait time to 150ms which is enough for almost all realistic scenarios.
previous discussion see #5683
The reason I chose not to defer to a follow-up loop and instead just wait is this: deferring is futile if target FPS is higher than actual FPS, which is very likely the case in the scenarios where such glitches appear. It just overcomplicates code for little to no gain.
The proper way to do it would be this:
runBlockingFunctions()function that is executed instrip.show()just beforeBusManager::show()which needs to wait for the bus anyway.it would however convolute code by running "background stuff" in
show()- very bad design. The alternative would be to havestrip.show()not callBusManager::show()but instead setting a flag "_frameReady" then return to main(),runBlockingFunctions()from there and afterwards runBusManager::show()if the frame is ready and clear the flag. Pretty much overcomplicating it just to fix an edge case IMHO. Unless there are other things that would benefit from such an approach @willmmiles & @softhack007 your thoughts on this?Summary by CodeRabbit