Controlling individual LEDs in a large array

I have a project and need to get advice and direction on how to proceed. I am planning a large array (at least 64 maybe twice that) of LEDs. There will be two levels of control, a group level and individual level. The groups would be controlled to turn on and off at specific intervals. Within each group the individual LEDs fade on and off at a controlled rate, randomly. I was looking at the SPI Digital Pot but it only controls 6 LEDs. Any advice or direction on this would be extremely helpful. Thanks.

I have never done this, but Charlieplexing would be one solution.

I used some TLC5940 chips to do something similar. I wired up 32 LEDs to act as stars on the ceiling.

I would have an 8x8 array of LEDs (assuming 64 LEDs for the moment) multiplexed in the usual fashion.

Then two 8x8 arrays in RAM where each bit corresponds to a LED.

Then two main functions,

func1: Interrupt driven, does nothing but read one of the arrays and drive the LEDs.

func2: probably loop(), does all the clever stuff re groups, fading etc and writes the results to the other array. When finished it sets a flag to tell the interrupt routine which array to read, thus the system is double buffered and shouldn't have any flickering.

This will need 16 IO pins if a row decoder is not used or 11 if one is, 3 if you use shift registers. You will of course need drivers for the LEDs as well although you can get high-current shift regs.

Greynomad, your recommendation sounds like an interesting solution. Can this be managed so that each LED in the array is controlled separately to fade on then off at different rates?

Can this be managed so that each LED in the array is controlled separately to fade on then off at different rates?

The short answer is "I don't see why not". The LEDs will just follow the bits. If every now and then you toggle one of the bits then the corresponding LED will flash. Do it fast enough and it will appear to dim, do it on a sliding value and it will fade. Do it on a group of bits and they will all fade. etc etc.

Basically you moved the problem from the hardware domain to software.

Of course the software may get tricky, it depends on what fade/group/etc functions you need. But by seperating the IO writing from the main algorithm at least func2 only has to manipulate an array.

I thought so. Do you know of any programs I can look at for the set up and to control the fading? I am a Newbe at this and would like to see how to structure it.

I don't know if anything you could use, and I haven't used C++ since it first came out but I would probably have an array of objects of type "led", these objects have methods like StartFade, StopFade etc.

Above that you have a "Groups" class with the same methods plus things like AddLed etc.

You call say groups[x].StartFade() and that interates through all its led objects calling leds[x].StartFade().

StartFade probably just sets a flag to say that the led is in "fade" mode, or it could also "seed" the fade counter with the start value.

Then every millisecond you call groups[x].DoFade() and that causes all the fading led objects to decrement their current value and write it to the led array. Then as mentioned the interrupt routine will pick it up and do the actual IO write. Of course the fade value is really a PWM duty cycle so that has to be dealt with somehow.

etc etc.

It will get complicated and require a lot of deep thought, but it would be a very good learning excersize as well.

Thinking more about it, I guess you have to decide what your priorities are, using a TLC5940 looks like it would be easier, but you'll need 8 chips (or 16 for 128 LEDs). The software method only needs a couple of chips but will take you a long time to write the code if you're new to the programming game (this will be a very frustrating but eventually rewarding experience :))

So, if you need the widget next week and aren't worried about the hardware cost I'd go the 5940 route, if you want to become a C++ guru and are going to sell 1000s of these so need to keep the costs down the software approach would be better.

but you'll need 8 chips (or 16 for 128 LEDs).

You can multiplex these chips. I have done it so you get the equivalent of 4 chips from just the one. see:-

If you go the software route there is not much scope for fine brightness control, there will be little time for the processor to do anything else and it will most probably flicker because you can't do it fast enough.

Mike's right, there would be a lot of issues to work out with the software approach, I reckon it could be done, but if you can mux the 5940s that would have to be the way to go.

@Mike, very nice project BTW.

Would macetech's Centipede shield be a "plug & plug" solution to this problem? I haven't used one, but seems like this is a suitable application if someone wants a shield solution...

Thanks for sussing out the hardware vs software issues guys. That is super! Since I do not know C++ the project will have to be hardware driven (as much as possible). Would love a plug and play solution and I will see if the centapede shield will work. I suspect that it will still have to have software to drive each led but minimize the design and wiring is a great step in simplifying the problem. Does anyone know if I can integreate the 5940 with the centipede shield?


To control more than 64 LEDs, I think you can use PCA5555 or MAX7219/7221.

PCA9555 can expand digital IO port by I2C bus. Each PCA9555 can expand 16 IO ports. you can paralle 8 PCA9555 s to control more LEDs.

MAX7219/7221 can easily control 8x8 LED Matrix. Each MAX7219/7221 can drive one 8x8 LED Matrix, and you can cascade more MAX7219/7221 to drive more LED matrixes.

The Centipede Shield probably does not have the speed to PWM all the I/O individually, you could get some level of brightness control but it would not appear very smooth. The strength of the Centipede Shield is the general purpose I/O, so that you can mix and match inputs and outputs as needed. If you just need outputs, shift registers are a better approach.

Instead, the Octobrite DEFILIPPI would work well. It can control 24 channels of LEDs with 4096 levels of brightness on each LED. You merely shift the data into the device and it takes over all the high speed PWM work. It has an internal 4MHz oscillator and auto restart so you don't even need to provide the PWM clock or restart the PWM cycle, like the TLC5940 requires. You can chain multiple boards together to control a large number of LEDs from only four Arduino pins. Additionally, the OctoBrite outputs are current regulated, so you do not need any resistors on the outputs, just connect the LEDs directly. The other solutions require dropping resistors.

Here's the link: