Go Down

Topic: Using PCA9685 as a current sink when driving LEDs (Read 1 time) previous topic - next topic

Aasmund

TLDR: How do i run a PCA9685 shield in open drain mode for running LEDs?


Essay explaining why I ask:

I bought a PCA9685 breakout shield (Adafruit clone) from Aliexpress to drive LEDs with. As far as I can tell this shield primarily meant to drive servos, the documentation mentions LEDs only as an aside. Servo power comes from a separate power supply, but LEDs connected directly to PWM would draw power from the PCA9685 chip, which in turn draws from Arduino's 5V line. Since I want to run 16 LEDs at up to 20 mA, max drain would be 320 mA, which is rather close to the absolute maximum 400 mA of the Arduino. In addition, each PWM output from the chip can only source 10 mA.

I was originally thinking that I would have to connect each PWM signal to the base of a transistor and let the transistor regulate an external current (like Figure 13, page 29 of the datasheet). But then I read that the chip could also be configured to be in "open drain" mode, and then each pin could sink 25 mA! (Figure 15, same page)

I don't really understand how to use the raw I2C bit-strings in the datasheet, so I've looked for libraries. The Adafruit library seems to be current-source mode only, and I can't tell what the NachtRaveVL library or the brunnel library does, mode-wise.


The 400 mA max current issue could be handled by connecting a regulated power supply directly to the 5V line rather than the Arduino's regulator. Then the Arduino would only draw what it needs for itself, and the rest would go directly to the LEDs and the driver chip.

So the question is: How do I set up the chip to be a current sink instead of source?


Bonus question: Ideally I want to fade LEDs individually and independently, in a non-blocking manner. Is this possible?

Wawa

How do i run a PCA9685 shield in open drain mode for running LEDs?

Since I want to run 16 LEDs at up to 20 mA, max drain would be 320 mA, which is rather close to the absolute maximum 400 mA of the Arduino.

In addition, each PWM output from the chip can only source 10 mA.

The Adafruit library seems to be current-source mode only, and I can't tell what the NachtRaveVL library or the brunnel library does, mode-wise.
So the question is: How do I set up the chip to be a current sink instead of source?

Bonus question: Ideally I want to fade LEDs individually and independently, in a non-blocking manner. Is this possible?
Possible to code the PCA for that, but why. Arduino pins can drive LEDs (source and sink), and those pins are not open drain.

20mA is the absolute max for common 3mm/5mm LEDs. You won't have to go near that.
5-10mA is already very bright for modern LEDs.
Note that that PCA board has 220ohm CL resistors.
That might limit current for a red LED to ~12mA and a high brightness LED to ~8mA.
Where did you get that 400mA from.
What you can draw from the 5volt pin depends on where the Arduino gets it's power from.
400mA is not a problem for e.g. an Uno on USB supply. e.g. a 5volt phone charger connected to the USB socket.

And sink 25mA. LEDs won't have to go between pin and ground. They also can go between pin and VCC.
Again, no open drain needed for that.

I use the Brunnels PCA9685 library with CC LED drivers. Never used the chip to drive bare LEDs.
Sink/source is just flipping PWM values in code. 0-4095 can be 0-100% or 4095-0 can be 0-100%.

Yes. just write a new PWM value to the corresponding PCA9685 pin (or a range of pins).
Then the Arduino is not needed anymore, until you want to change a PWM value.
Leo..


Aasmund

Possible to code the PCA for that, but why. Arduino pins can drive LEDs (source and sink), and those pins are not open drain.
I plan to use those pins for switches and SPI, and only six of those pins have hardware PWM.


20mA is the absolute max for common 3mm/5mm LEDs. You won't have to go near that.
5-10mA is already very bright for modern LEDs.
Note that that PCA board has 220ohm CL resistors.
That might limit current for a red LED to ~12mA and a high brightness LED to ~8mA.
Where did you get that 400mA from.
What you can draw from the 5volt pin depends on where the Arduino gets it's power from.
400mA is not a problem for e.g. an Uno on USB supply. e.g. a 5volt phone charger connected to the USB socket.

And sink 25mA. LEDs won't have to go between pin and ground. They also can go between pin and VCC.
Again, no open drain needed for that.
400 mA was off the top of my head from other forum threads. I could have mixed it up with maximum sum pin current of the atmega328.

It's perfectly possible I don't understand what "open drain" means.

I use the Brunnels PCA9685 library with CC LED drivers. Never used the chip to drive bare LEDs.
Sink/source is just flipping PWM values in code. 0-4095 can be 0-100% or 4095-0 can be 0-100%.

Yes. just write a new PWM value to the corresponding PCA9685 pin (or a range of pins).
Then the Arduino is not needed anymore, until you want to change a PWM value.
Leo..


So if I connect the LED between V+/VCC and PWM it will just work and I don't have to fiddle with setting modes, INVRT bits etc? Great! Thank you.

Grumpy_Mike

Quote
As far as I can tell this shield primarily meant to drive servos,
The chip itself was designed specifically to drive LEDs.

Quote
So if I connect the LED between V+/VCC and PWM it will just work
You need a current limiting resistor as well, that chip has no current control.

Quote
and I don't have to fiddle with setting modes, INVRT bits etc?
It depends what you want to do. I have found that you can not drive LEDs and servos from the same chip without inverting the signal outside the chip for one or the other.

Go Up