PxMatrix icon indicating copy to clipboard operation
PxMatrix copied to clipboard

Flicker after upgrading from 1.7.0 to 1.8.2

Open sovcik opened this issue 4 years ago • 8 comments

Just a note:

In 1.8.0 you have introduced latch_time in method void PxMATRIX::display(uint16_t show_time) which basically increases previously used show_time.

Took me some time to figure out why my display started flickering after upgrading from 1.7.0 to 1.8.2. Please, mention similar changes in release notes next time :-)

sovcik avatar May 04 '20 05:05 sovcik

Also the change from color steps to color bits should be mentioned ;)

The time the LEDs stay on is now basically half as long as before for the first color bit. It's the same as before for the 2nd color bit and then it doubles for each additional color bit.

With display(40) and PxMATRIX_COLOR_DEPTH 4 you now get LED pulses of 20µs, 40µs, 80µs and 160µs.

With display(40) and PxMATRIX_COLOR_DEPTH 8 (old default) you now get LED pulses of 20µs, 40µs, 80µs, 160µs, 320µs, 640µs, 1280µs, 2560µs. Using PxMATRIX_COLOR_DEPTH 8 with the new code is just overkill, because what was 8 before is now 3. Also, 2.5ms LED on may break the code because it may be longer as the refresh interval - especially because it's executed up to 16 times in a row with a 1/16 panel and it also may trigger a wdt reset...

Maybe changing the define so the code will break intentionally and throw a meaningful error may help to communicate this change?

#ifdef PxMATRIX_COLOR_DEPTH
#error "use PxMATRIX_COLOR_BITS instead and reduce the value. Code changed from steps to bits. Use 2 if you used 4 before, 3 if you used 8, 4 if you used 16, ..."
#endif 

xsrf avatar May 04 '20 06:05 xsrf

Yeah...you are right. I adapted the effect of show_time so it gives similar results to the previous implementation with the new default PxMATRIX_COLOR_DEPTH 4. However if people overwrite this it will lead to unexpected results.

I would probably just check if it is defined in the sketch and throw a warning with some info?

2dom avatar May 04 '20 08:05 2dom

Even with the default PxMATRIX_COLOR_DEPTH 4 , display(x) now takes four times as long as before for the most significant color bit.

Maybe it would be better to use the show_time as maximum for the MSB and half it for every less significant color bit? This may reduce brightness compared to versions before, but it wouldn't mess with timing / break code completely.

Users who use fast_update should also be aware that there is a minimum latch_time which cannot be below the time it takes to fill the display buffer via SPI. (at least as long as blocking SPI transfer is used)

xsrf avatar May 04 '20 08:05 xsrf

Basically, there are a lot of things to consider when switching from regular pwm to binary pwm. Let's say you have 3 bit / 8 steps and 100% brightness. For simplicity assume you have only one row to deal with and the code that updates it is executed at a constant rate every 100µs. Also assume display_time to be 100µs.

With regular PWM to display the color, you must execute the code 8 times and you get 100% duty cicle. With binary pwm, you only need to execute the code three times. However, only the first execution reaches 100% duty cicle. The second time its only 50% and the third time only 25%. In sum, you cannot get above 58% as long as the code is executed at a constant rate. What you gain however is update rate because you only need 3 executions instead of 8.

This is especially helpful for higher color depths. But if you're happy with 3bit, this may actually be a disadvantage :/

To solve this, the execution rate of the code would actually have to adapt too...

Guess I may have introduced more problems than improvements with my idea 🙈

Edit: And of course you save a lot of RAM with binary...

xsrf avatar May 04 '20 09:05 xsrf

Regarding color depth:

I think the "big question" is "What is the target use case?" Well, this lib and implementation is not targeted for 24bit color depths :-) I tend to think that the majority might be fine with 3-4bit color depth (well, I use it for 4 colors only).

On Mon, May 4, 2020 at 11:29 AM xsrf [email protected] wrote:

Basically, there are a lot of things to consider when switching from regular pwm to binary pwm. Let's say you have 3 bit / 8 steps and 100% brightness. For simplicity assume you have only one row to deal with and the code that updates it is executed at a constant rate every 100µs. Also assume display_time to be 100µs.

With regular PWM to display the color, you must execute the code 8 times and you get 100% duty cicle. With binary pwm, you only need to execute the code three times. However, only the first execution reaches 100% duty cicle. The second time its only 50% and the third time only 25%. In sum, you cannot get above 58% as long as the code is executed at a constant rate. What you gain however is update rate because you only need 3 executions instead of 8.

This is especially helpful for higher color depths. But if you're happy with 3bit, this may actually be a disadvantage :/

To solve this, the execution rate of the code would actually have to adapt too...

Guess I may have introduced more problems than improvements with my idea 🙈

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/2dom/PxMatrix/issues/193#issuecomment-623357557, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAATZSXNNJQBYKPDUIJA7NLRP2DF5ANCNFSM4MYOVC2Q .

sovcik avatar May 04 '20 11:05 sovcik

I think 4 bit is a good compromise - it gives you reasonably accurate color rendering whilst being faster and using less ram in comparison to the previous implementation. If you drop down to 3 bits you can actually see the blocking of colors already, e.g. in the Aurora demo.

So I would just leave it there as a default - anyone brave enough to fiddle with this will also figure our how to set show_time. It is always a balance between giving the majority of users a good out-of-the box experience / not over-explaining things in the readme whilst giving the pros some freedom to change things.

Do you guys think explaining in the Readme how the color engine works actually gives value to the user or does it just confuse more then it helps. Maybe add a pro section to the end where we shift all the technical stuff (including how the matrix works itself)?

2dom avatar May 06 '20 02:05 2dom

Do you guys think explaining in the Readme how the color engine works actually gives value to the user or does it just confuse more then it helps. Maybe add a pro section to the end where we shift all the technical stuff (including how the matrix works itself)?

I think it would be amazing to have some section that would cover basic concepts that this library is using and maybe some technical limitations that users can hit.

I've received my LED matrices (3x64x64, for 192x64 pinball display) yesterday and so far I've manged to make a lot of stuff work, but it's kinda "trial and error" approach, because I'm never sure if I'm doing something wrong or I'm just hitting some limitation of my ESP32. I'm fiddling with PxMATRIX_COLOR_DEPTH, PxMATRIX_SPI_FREQUENCY, PxMATRIX_DEFAULT_SHOWTIME etc. and sometimes it doesn't work at all, sometimes it flickers, sometimes it works absolutely fine, but I would love to understand why are certain "settings" failing.

hrocha1 avatar May 07 '20 20:05 hrocha1

I also wouldn't mind a technical section in the readme :)

xsrf avatar May 07 '20 20:05 xsrf