Multiple LEDs from anode + pin from digital pin common cathode -

Hi everyone need some help to see if there is a better way to reduce the number of components between the arduino digital pin out and the LEDs, as they are tri LEDs and have common Cathode - . (Note I can't change the tye of LEDs)
As you know LEDs can't be run straight off the Ardunio, as I am hooking up 48 LEDs to a mega pro.
The solution I have is to use ULN2803 chip off the digital pin then through a resistor then through a MPQ2907 ( PNP quad transistor IC) I am hoping this chip over single NPNs as I hope this will use less space on the PCB even though the NPNs are lot cheaper than the IC.
Your thoughts please on a better way to get the LEDs using Anode - off a digital pin as cathode (ground) has to be common. OH I rather use through hole component's.
If it was common anode it would be easy as I just use the ULN2803 chips

Why are you using a low side switch instead of a high side switch? Packaging?

As you know LEDs can't be run straight off the Ardunio

They can with a series resistor.

Common cathode, then put that to ground and connect a resistor from each anode to the outputs of the Arduino.

Why so many transistors? Are you trying to control each led individually?

Also are we talking about power leds? How much current do the leds need?

And why do you think a DIP14 package takes less space than 4 transistors?

schematic ?

Look into MIC5891, a current source (high side drive) shift register.
With 6 of them daisy chained, you can send out data for 16 common cathode RGB LEDs,
and only need 3 IO pins - SCK, MOSI, and strobePin (I would use the SPI's SS if you don't have other SPI transfers going on, as SS needs to be an output to be the SPI master)

for (x = 0; x < 6; x = x+1){
  SPI.transfer(dataArray[x]);
}
digitalWrite (strobePin, LOW); // only need this if the strobePin cannot be guaranteed to low normally
digitalWrite (strobePin, HIGH); // high pulse latches data into output register
digitalWrite (strobePin, LOW);

Not sure whether you mean 48 individual LED elements or 48 RGB LEDs totalling 144 elements.

Nevertheless, the much better way to do this is to matrix them using MAX7219 drivers. The MAX7219 is designed to multiplex a matrix of 64 LEDs but for common cathode or common anode LEDs this is limited to 16 RGB LEDs each MAX7219, multiples of which are chained to all be controlled by only three Arduino pins.

Even a Mega 2560 has a limited number of available PWM pins so I figure you cannot be intending to use PWM for colour shading on so many LEDs, so a Nano can drive your MAX7219s perfectly adequately.

Prior to Covid-19 and an absurd increase in "shipping costs" I recommended just buying a number of these kits:

Or these ones

which used to be more expensive but are now generally cheaper and more useful if you wish to stack matrix arrays.

The point is that you do not install the matrix arrays from the kits themselves - or their socket pins, but just solder to the positions on the PCB and you have a durable and reliable assembly to drive your own matrix arrays.

Why did I say "a number"? Well, you can fully assemble the first one as the matrix with which it comes and practice programming it. Then the remainder for your current project and some more - for the next! :grinning:

Considering the cost, it used to make no sense to just buy the bare minimum though now I am not so generous!

(Sorry, eBay has hidden the images recently - try "view image". :roll_eyes: )

I have a MAX7219 breakout board that could accept common cathode RGB LEDs easily.

This pic shows 4 LEDs. Each block of 2x8 is 8 separate anodes and 8 common cathodes.
So the anodes of two RGB LEDs would be used in each block, 8 blocks, so there's the 48 anodes that need to be driven.
To change color, a new byte is written for each pair of RGB LEDs.
If the LEDs are arranged as:
xRGBxRGB, then the code is simple:

digitalWrite (ssPin, LOW);
SPI.transfer (registerAddress); // 1 to 8 for the MAX7219
SPI.transfer(dataPair[registerAddress]);
digitalWrite (ssPin, HIGH);

where

dataPair[0] is not used
dataPair[1] = RGBs 0 and 1
dataPair[2] = RGBs 2 and 3
dataPair[3] = RGBs 4 and 5
dataPair[4] = RGBs 6 and 7
dataPair[5] = RGBs 8 and 9
dataPair[6] = RGBs 10 and 11
dataPair[7] = RGBs 12 and 13
dataPair[8] = RGBs 14 and 15

When a color change is needed, update the appropriate half of a byte, and send it out, examples:

dataPair[x] = dataPair[x] & 0xf0; // clear the lower nibble
dataPair[x] = dataPair[x] | newNibble;  // lower 4 bits OR'd into the byte
:
:
dataPair[x] = dataPair[x] & 0x0f; // clear the upper nibble
dataPair[x] = dataPair[x] | (newNibble<<4);  // upper 4 bits shifted left and OR'd into the byte

This limits you to the 8 colors when a LED is either ON or OFF if that suits your project needs.
R
G
B
RG
RB
GB
RGB
all off


This conversation seems to be a one way thing, just us. No engagement from the OP.

Grumpy_Mike:
This conversation seems to be a one way thing, just us. No engagement from the OP.

What's new? :roll_eyes:

The OP has never acknowledged a reply to any of his previous (two) queries. But that is not exactly unusual on the fora here! And it is only four days after all - some callers have other things to occupy their week. :grinning: