I would like to be able to control around 100 independent LEDs using an Arduino. The problem is that the Arduino does not have nearly enough pins that can be configured for this. What would be a way to solve this problem? Is there a chip that can demux a more complex signal from the Arduino that could then control the LEDs? Or is there another solution?
First off, an Arduino cannot directly drive 100 LEDs, as the combined current that the device must source or sink will far exceed both the microcontroller, and the voltage regulator on the Arduino board. A custom Arduino Shield with its own power source and regulation might fit the bill, though.
There are several easy approaches, the simplest approach is detailed below:
TLC5940 constant-current LED driver in cascaded configuration:
The TLC5940 drives 16 LEDs per IC, controlled by serial input through a slight variant of an SPI interface. Up to 40 TLC5940 devices can be cascaded, but 7 of them will be sufficient to drive the 100 LEDs in the question.
Suggested clock rates to send from the Arduino, and corresponding refresh rate:
- 1 MHz GSClk using code in this thread.
- 330 KHz SCLK (serial data clock)
- Thereby, LED data refresh rate 244 Hz
This is based on the formulas from the datasheet:
f(GSCLK) = 4096 * f(update)
f(SCLK) = 193 * f(update) * n
f(GSCLK): minimum frequency needed for GSCLK
f(SCLK): minimum frequency needed for SCLK and SIN
f(update): update rate of whole cascading system
n: number cascaded of TLC5940 devices
The TLC5940 is a constant current sink, so the anodes of the LEDs would be tied to a voltage a couple of volts greater than the LED Vf, or around 7 volts, whichever is lower, powered independently of the Arduino's power pins. This voltage source needs to be capable of supplying 100 * (whatever current you run the LEDs at), but can be an unregulated source.
The LED cathodes go to the drive lines of the respective TLC5940 ICs.
The TLC5940 itself consumes up to Icc = 60 mA per device during data write, so powering 7 of them from the Arduino won't work, it will require an independent 3.3 to 5 volt regulated Vcc to be provided, ideally the same value as the Vcc of the Arduino being used, and the ground traces need to connect back to the Arduino's ground, of course. Operating the TLC parts at a different voltage than the Arduino would bring in a need for level conversion of the serial signal, hence best avoided.
Several YouTube videos demonstrate using Arduino with cascaded TLC5940 ICs.
MAX7219 (serial) / MAX7221 (SPI) 8-Digit LED Display Drivers:
Although these ICs were designed for driving 7-segment numeric LED displays, they provide individual LED control, so can be used for up to 64 LEDs per IC. Two of them can be cascaded to drive the 100 LEDs required. Page 13 of the datasheet shows a cascade configuration.
The LEDs would have to be electrically connected as groups of up to 8 LEDs each sharing one cathode line (common cathode), for this design.
The MAX7219/7221 are multiplexing LED drivers, hence maximum brightness of LEDs will be lower than for a static LED driver like the previous section.
Here is a useful LED matrix library and guide using the MAX7219.
Again, these ICs were designed for driving 7-segment numeric LED displays, they provide individual LED control, so can be used for up to 40 / 64 LEDs per IC. Two / three of them can be hooked up on an Arduino SPI bus to drive the 100 LEDs required.
Design notes remain the same as the previous section. Also, individual LED maximum brightness would be lower than for the straight multiplex design of the MAX7219.
There are some YouTube videos that might be of interest.
Discrete component designs, shift registers, IO expanders, cuttable LED strips with individual controllers, and many more...
These are all approaches that have been used with varying levels of simplicity and success. They are more complex implementations than the 3 approaches above, hence not detailed any further. Searching the web would yield useful guides for these approaches, if needed.
One key irritant with such designs is the need for current control resistors on every LED or LED string. Devices specifically designed for LED driving typically do not need this.
I don't have personal experience with this last set of options, so cannot help much.
Footnote: After responding to this question, I found an older question, that has answers detailing and discussing several of the approaches in my last section. That thread makes interesting "further reading as homework".