There's a bunch of LED driver ICs, for instance TLC5951DAP. See it in use here:
Mbled
Similar problems has been solved in a few open source projects, like Peggy2.
The chip Peggy2 is using seems to be going out of production, MBI5026 might be a replacement.
I've had the same problem as the OP and found this post on the NXP forums which describes my problem (and I think the OP's problem?) well. In any case this ESE page is one of the first sites that appears when searching for PCA9685 flickering LEDs
, so I thought I'd add my solution here. From the NXP forum:
Looking at the datasheet
(http://www.nxp.com/docs/en/data-sheet/PCA9685.pdf) fig. 11 on page 20
this looks according to design, the problem is whenever LEDn_ON >
LEDn_OFF and the LEDn_OFF register is updated, the device skips one
whole output phase, switching the output off regardless of the
registers -- look at the empty cycle between "register(s) updated in
this cycle" and "output(s) updated in this cycle". There's no empty
cycle when LEDn_ON < LEDn_OFF as seen on fig. 10 on the preceding
page.
So it isn't an electrical problem, or a problem with the Picobuck (I'm using plain old MOSFETs), it's a problem with the PCA9685 chip itself: keeping the output off for (the remainder of?) a cycle whenever the duty is changed if certain register conditions are met, and if the rising edge is not synchronised with the chip's internal timer.
This poster's final comment was:
Is there a way to avoid this kind of behavior and still benefit from output load balancing?
Spoiler alert: as of writing this there is no answer yet - But this lead me to investigate and try turning off whatever this "load balancing" thing is. I'm using this library for driving it, and after scouring the source I tried changing the declaration of the PCA9685 object found in the sample from this:
PCA9685 pwmController;
to this:
PCA9685 pwmController(Wire, PCA9685_PhaseBalancer_None);
And... Smooth as butter!
So what is load balancing, and why should I care?
Well, it appears to be a way to stagger the rising edge of the PWM signal across each channel, presumably to ease the instantaneous current changes of all 16 channels rising at once and potentially falling at once if the brightness/duty of each channel is equal. The other options in the library are *_Linear which staggers the waveforms by a fixed delay for each channel from the one before it, *_Weaved which interleaves the delays across channels, "balancing the first few outputs better" (whatever that means) and *_Count which is not implemented by the library and works exactly the same as *_None.
Any staggering of the phase results in flickering as soon as levels are changed, and this may also have an effect on particular duty cycle ranges based on the PWM frequency.
Implications I presume are unstable power draw and stronger EMI. I presume this means power should be buffered with a good sizeable cap, but I'm not sure what to do (if anything) about the potential EMI - is it a problem? Is there another issue to consider with turning off phase balancing? If anyone more technical can comment on this, I'd be most grateful.
Best Answer
Your calculations seem correct to me.
However, do you really care about the rise time being >25ns?
If you say you don't need the range below 1% brightness, then you can simply use only values in range 10 to 1023 out of 1023, and you therefore get a rise time of at least 10*50ns = 500ns.
If by mistake (or to simplify code/design) you still use the 0 to 9 out of 1023 range, then you will simply get in one of the following situations :
Which of the above will happen depends of the exact components you use for driving the LED (I would guess 1 or 2 are the most likekly.)
Between 0 and 9, you might not get brightness proportionnal to PWM, but you should get:
If you don't care about what exactly happens below 1% of brighness, either don't use values 1 to 9, or just accept the fact that you will not get perfect linearity for those.