-
-
Notifications
You must be signed in to change notification settings - Fork 3.3k
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
PWM enhancements (phase shifting and dithering) #4115
Conversation
Using dithering allows for longer pulse times if not FET driver is used. In current configuration, on the slowest speed setting the minimum on-time is 400ns, which is enough time to drive a FET directly from a GPIO. The down side of using dithering: the PWM frequency drops for the lowest duty-cycle values (minimum frequency is basefrequency/(1<<ditheringbits) phase shifting is added to distribute the load better over one period. the algorithm used is very simple and does not perfectly distribute the signals in all cases but it is not too bad for a nice-to-have feature. TODO: -dithering is only tested with 4bits, less may be possible -the way the frequency settings are used is just a POC -need a proper way to enable/disable phase shift as well as dithering
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.
Looks quite complicated. 😄
I think you could forego phase shifting for anything but PWM CCT. And simplify that to always shift 180°.
your call, the code is already there :) |
I've updated the PR to include changes in PinManager. |
I dont fully get what you mean. |
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.
bc.frequency
uses "slowest", "slow", "normal", "fast" and "fastest" monikers that relate to pre-determined WLED_PWM_FREQ frequencies. Why did you choose to change that logic/pre-determined values?
Is it necessary for dithering? If so there will need to be an explanation why WLED_PWM_FREQ is no longer respected as a "normal" frequency (it is twice that now).
I have not yet digested show()
logic. But will do that ASAP.
default: | ||
case WLED_PWM_FREQ : _frequency = WLED_PWM_FREQ*2; break; // fast, 40kHz, 8bit + 4bit dithering | ||
case WLED_PWM_FREQ*2 : _frequency = WLED_PWM_FREQ*3; break; // ultra fast, 60kHz, 8bit + 4bit dithering | ||
case WLED_PWM_FREQ*10/3 : _frequency = WLED_PWM_FREQ*4/3; _depth = 10; ditheringbits = 0; break; // no dithering, 26kHz, 10bit |
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.
I am referring to this line.
The frequencies chosen are preliminary and just a suggestion from my side. In my tests using a FET module (dual AOD514 from Ali) I found that a GPIO can not drive it any faster than a 400ns pulse, below that, the output would not switch on (still need to get some IRLZ44n to check how they perform). These are the chosen settings:
the last one could also be dropped to 20kHz i.e. the WLED_PWM_FREQ (I just chose it to be different so I could use it to ID that mode as I had no other variable available). I would also suggest a renaming of "slowest", "slow", "normal", "fast" and "fastest" but I have no good suggestions. Since I expect few users to read any documention on the new PWM settings, it should be clear what they are intended for. I am open for suggestions on frequencies and bit depth / dithering bits (I assume also 2 and 3 bit dithering will work with some minor modifications). |
I am not sure I follow. Let me try to explain how I see "dithering" (that will extend pulse width fo our purposes). Having 12 bit resolution means there are 4096 different pulse widths possible (minus 2 if we take 0 and 4095 out). Each pulse (regardless of its width) happens within a period of PWM frequency (i.e. 19531 Hz or 51.2 us). The shortest pulse will therefore be 12.5 ns. Is my understanding so far correct? If yes, then I see no point in changing the frequency as we already "extended" pulse width to a reasonable width by reducing bit depth (if your FETs are still too slow, you can use slower frequencies from the chosen list). So it is just a matter of correctly alternating that lowest bit in time to achieve "perceived" resolution of 12 instead of 8 bits. FYI I have 2 IRLZ44N on my desk, attached to 2 5V 3W analog LEDs WW & CW. I am using level shifter for driving FETs and they perform adequately at 12 bit at 19531 Hz. I can see brightness changes down to global brightness of 1. |
As a solution for your other problem (UI option) I would go with "Use dithering" checkbox. |
your understanding seems correct. let me put in other words: |
There is a simple answer for that: If your LEDs turn off at higher brightness levels (i.e. too soon) use dithering or try lower frequencies or both. |
Temporal, that was the word I was searching for. 😄 |
The "slowest" frequency already is half of WLED_PWM_FREQ which is 9765 Hz that will produce 400 ns pulse with 8 bit resolution. Or does it not? |
slowest is indeed the same. I just got some IRLZ44n in the mail today btw, will check how they perform. |
As I've commented on Discord I finally understand how this should work. Let me explain. We should talk about 2 different things: phase shifting and dithering. Lets start with phase shifting. Dithering. I will update |
Closed in favor of #4126 |
TODO: