How to drive 16 individual multi-color LEDs?

Thread Starter

abritinthebay

Joined Dec 17, 2008
6
Ok, so... I'm not electronics expert, I admit that, but I've run into something of a brain teaser.

I need to drive 16 LEDs seperately using PWM to make them appear to fade in intensity (and so be able to mix their colors).

So I need to have 48 lines with PWM... ack.

However - the goal here is to build off of a Gumstix embedded linux-pc and be able to control the leds in software from that.

Now I'm able to control basic i/o pins, but they aren't PWM pins, and even if they were there aren't 48 of them.

Help? I really have no idea how the hell I'd be able to go from a few lines of IO to multiple lines of PWM.

Someone suggested to me the 74HC595 but I'm not sure how that would actually help in this case...
 

StephenDJ

Joined May 31, 2008
58
This is something I'm interested in, as I'd like to build a sign full of LEDs. I agree, I'm not sure how you'd use the 74HC595 either. Maybe they are talking about using just six outputs of your computer to feed the serial inputs of 6 separate 74HC595's and let each one break out with 8 bits in parallel.
 

RiJoRI

Joined Aug 15, 2007
536
16 LEDs can be combined into a 4x4 matrix, thereby needing only 8 control lines for single or bi-color LEDs. Can you give some info on your multi-color LEDs?

I just did some PWM stuff for a white LED. THe duty cycle was regular -- 10%, 20%, ... 100%, and I found that optically the LED quickly reached maximum brightness. I used a "kind-of" logarithmic set of numbers, and it worked a LOT better. I think I used log [20..90], and converted the result into a 2-digit whole number: log 2 = .3010; .3010 became 30.

--Rich
 

Thread Starter

abritinthebay

Joined Dec 17, 2008
6
Some more detail - these are tri-color (RGB... effectively) LED's.

They are going to be wired up so that 12 of them are in a single row in one part of the project and 4 of them are going to be in completely separate places.

Each of the LED's has 3 lines in - one for each color. Each has a slightly different voltage, as it to be expected, but that isn't really important for now.

The key is the individual control - for that I need 3 PWM lines for each LED. 48 in total.

One suggestion is 8 atmega48 microcontrollers and
a single Arduino. The Arduino development environment would let
me program the Arduino and use the kit as a simple development platform and let me program the atmega48 devices with the Arduino code.
Then serially talk to all 8 atmega48 devices.

But damn that seems like a really round-about (not to mention complex) solution.
 

Thread Starter

abritinthebay

Joined Dec 17, 2008
6
I just did some PWM stuff for a white LED. THe duty cycle was regular -- 10%, 20%, ... 100%, and I found that optically the LED quickly reached maximum brightness. I used a "kind-of" logarithmic set of numbers, and it worked a LOT better. I think I used log [20..90], and converted the result into a 2-digit whole number: log 2 = .3010; .3010 became 30.
That certainly gives me some good info for when I do have them wired up.

The plan is to control them eventually from a Gumstix linux computer (verdex pro mobo for those interested). But right now it seems rather tough to do...
 

RiJoRI

Joined Aug 15, 2007
536
... They are going to be wired up so that 12 of them are in a single row in one part of the project and 4 of them are going to be in completely separate places.

Each of the LED's has 3 lines in - one for each color. ...
OK, a few more questions. I shall be away until January 5th, so maybe someone else can help, here.

First, HOW the LEDs are finally arranged is immaterial. Think of a 4x4 matrix of LED holders. You use that matrix to prove the concept works. Then add really l-o-n-g wires to the LEDs, and place them however you like. This is a concept you need to own. You MUST be able to understand the matrix is a concept of how to control the LEDs, NOT how to arrange them physically.

Now, I am not really familiar with tri-color LEDs. I am guessing that there is a common connection with the LEDs resulting in 4 lines? Or as you put it, three in and one out?

If this is the case, expand the matrix to 7x7. You need 48 control lines; 7x7 == 49, which is one more than you need. Now, instead of needing 48 I/O pins, you only need 14 pins.


Possible arrangement:
R00 R01 R02 R03 R04 R05 R06
R07 R08 R09 R10 R11 R12 R13
G00 G01 G02 G03 G04 G05 G06
G07 G08 G09 G10 G11 G12 G13
B00 B01 B02 B03 B04 B05 B06
B07 B08 B09 B10 B11 B12 B13
R14 R15 G14 G15 B14 B15 N/U

Or,

R00 R01 R02 R03 R04 R05 R06
R07 R08 R09 R10 R11 R12 R13
R14 R15 G00 G01 G02 G03 G04
G05 G06 G07 G08 G09 G10 G11
G12 G13 G14 G15 B00 B01 B02
B03 B04 B05 B06 B07 B08 B09
B10 B11 B12 B13 B14 B15 N/U


Notice that no matter how I arrange the LEDs in the matrix, it doesn't really matter, because you, as the programmer, are in control of which pins are active when.

Another thing, if you have pins to spare, is 3 4x4 matrices, one for each color. The advantage here is that you can do preliminary testing with one matrix, then copy the code for the other two.


R00 R01 R02 R03
R04 R05 R06 R07
R08 R09 R10 R11
R12 R13 R14 R15

G00 G01 G02 G03
G04 G05 G06 G07
G08 G09 G10 G11
G12 G13 G14 G15

B00 B01 B02 B03
B04 B05 B06 B07
B08 B09 B10 B11
B12 B13 B14 B15


Finally, if your heart is REALLY set on multiple processors, look at the Parallax Propeller chip. It has 8 processors (they call them "cogs") and 32 I/O bits in one package. I'm using one to run the LEDs on a DIY Christmas tree: one cog is doing the PWM control for the "star" LED, another cog is turning the other LEDs off and on in a semi-random pattern. The two cogs are running their code totally independent of each other.

HTH,
--Rich
 

Thread Starter

abritinthebay

Joined Dec 17, 2008
6
I guess I don't quite understand how the matrix means I can control them individually, while lowering the control line count. It seems to me that I could only have one LED on each row working independently at a time - they'd share the same PWM signal... which is key really - binary on/off isn't the issue (I see how it would work for that).

Something for me to work out I guess - but I see the logic, just not quite how it works (like I said, I'm a programmer, not a electrician!)

Something for me to chew over, but that's really helpful, thank you.
 

RiJoRI

Joined Aug 15, 2007
536
ASCII-graphics image of 1/4 of the Matrix (Call me "Neo" :D )
And a bit of C code to show how it works. Note that
(a) the code has not been checked, nor does it say how the color arraysget loaded; and
(b) you'll most likely need some type of drivers for the micro to work; and
(c) I do not know if it is fast enough to prevent the LEDs from flickering.

--Rich


Rich (BB code):
/*
 *  
 *  
 *               +--------------------------------------------------+------->
 *               |                                                  |
 *               |  +--------------------------------------------+--|------->
 *               |  |              ______                        |  |                  ______
 *  Red_Port.0 --*------[Red]-----/      \---[Ground]-----+      |  +-------[Red]-----/      \---[Ground]-----+
 *                  |             | LED1 |                |      |                    | LED4 |                |
 *  Blue_Port.0 ----*---[Blue]----\______/---[Green]---+  |      +----------[Blue]----\______/---[Green]---+  |
 *                                                     |  |                                                |  |
 *  Green_Port.0 --------------------------------------+--|------------------------------------------------+--|-->
 *                                                        |                                                   |
 *                                                        |                                                   |
 *                                                        |                                                   |
 *               +--------------------------------------------------+                                         |
 *               |                                        |         |                                         |
 *               |  +--------------------------------------------+  |                                         |
 *               |  |              ______                 |      |  |                  ______                 |
 *  Red_Port.1 --*------[Red]-----/      \---[Ground]-----+      |  +-------[Red]-----/      \---[Ground]-----+
 *                  |             | LED3 |                |      |                    | LED2 |                |
 *  Blue_Port.1 ----*---[Blue]----\______/---[Green]---+  |      +----------[Blue]----\______/---[Green]---+  |
 *                                                     |  |                                                |  |
 *  Green_Port.1 --------------------------------------+--|------------------------------------------------+  |
 *                                                        |                                                   |
 *  Col_Port.0 -------------------------------------------+                                                   |
 *                                                        |                                                   |
 *  Col_Port.1 -----------------------------------------------------------------------------------------------+
 *                                                        |                                                   |
 *                                                        |                                                   |
 *                                                        V                                                   V
 *                                                                                                            
 *                 
 */                  
                   

/* These will get loaded elsewhere */
char Red_Ary[4];
char Green_Ary[4];
char Blue_Ary[4];

while(1)
{
    for(Col = 1; Col < 16; Col << 1)
    {
        Col_Port = ~Col;            /* Turn off column */
        for(Row = 0; Row < 4; Row++)
        {
            PWM(Row);
        }
    }
}


void PWM(char Row)
{
  char Red = Red_Ary[Row];
  char Blue = Blue_Ary[Row];
  char Green = Green_Ary[Row];
  char n;

    for(n = 0; n < 255; n++)
    {
        if(Red)
        {
            Red_Port = (1 << Row);
            Red--
        }else{
            Red_Port = ~(1 << Row);
        }

        if(Blue)
        {
            Blue_Port = (1 << Row);
            Blue--
        }else{
            Blue_Port = ~(1 << Row);
        }

        if(Green)
        {
            Green_Port = (1 << Row);
            Green--
        }else{
            Green_Port = ~(1 << Row);
        }
    }
}
 

Thread Starter

abritinthebay

Joined Dec 17, 2008
6
Ah I see, so to do this I'd cycle through the columns and rows so fast that although I wouldn't be able to control each LED at the same time it wouldn't matter because the rate of change would be so fast that it would appear to be lit at the same time (PoV I guess).

Of course that means I'd have to cycle PWM as well as scanning the matrix, but that shouldn't be a huge problem.

Am I on the right path?

If so... now to work out what to use to drive the PWM and talk to the host PC. The LED Wiz is a little pricey, but does have more than the needed 14 outputs. Anyone have any other ideas on that front?
 
Top