Tell me more ×
Electrical Engineering Stack Exchange is a question and answer site for electronics and electrical engineering professionals, students, and enthusiasts. It's 100% free, no registration required.

I am using an Atmel ATTINY13 which has a 6-pin I/O. I'd like to control about 15 LED's but am unsure how to connect everything. Without multiplexing of any sort, it seems I'd only be able to control 6 LED's at a time. Am I limited to only 6 LED's because of the size of the microcontroller?

share|improve this question
I had not seen. Possibly duplicated: electronics.stackexchange.com/questions/9860/… – Daniel Grillo Mar 4 '11 at 19:36
1  
Don't forget to compare your options against the cost of buying a slightly pinnier microcontroller. Also pay attention to the per-port and total current limits. – joeforker Mar 4 '11 at 20:39
When I began working with micros a while ago, this is a question I wished had been easy to find with clear answers. I managed to learn about charlieplexing and successfully implement it, but I wanted to recreate the question here with the excellent quality of SE-community answers. – JYelton Mar 4 '11 at 21:47
@joeforker You're right, the cost for a micro with more pins was pretty minimal, considering my project was a one-off. I thought at one point about using a micro with about 20 IO pins to accomplish the job, but one of my goals was a very small circuitboard footprint. Also, awesome adjective pinnier! – JYelton Mar 4 '11 at 21:54
Duplicate: electronics.stackexchange.com/questions/1609/… – mjh2007 Mar 10 '11 at 21:01
show 1 more comment

5 Answers

up vote 14 down vote accepted

There are several methods which can be used to drive large numbers of LEDs from a few IO pins.

The simplest is standard row/column display multiplexing. With this technique, you can drive \$( n / 2 )^2\$ LEDs with \$n\$ IO pins. Mathematically, the duty cycle is \$1 / minimum(\text{unique row patterns, unique column patterns})\$. This means that this technique has a duty cycle of 100% when all LEDs are lit (or all rows or all columns are identical) and a duty cycle of \$1 / n\$ when a diagonal line needs to be lit (or all the rows are different). You're only guaranteed 100% duty cycle when lighting every LED or one LED (or zero LEDs, but that doesn't really count for much).

Slightly more complex is Charlieplexing. With this technique, you can drive \$n^2 - n\$ LEDs with \$n\$ IO pins. Only \$n - 1\$ LEDs can be lit simultaneously with this technique. Mathematically, the duty cycle is \$1/ (\text{minimum simultaneous sets})\$, where a simultaneous set is a unique group of LEDs which has a common anode or common cathode. (This hasn't been proven, it's just what I arrived at after pondering the problem for a minute. If duty cycle is important to you, you'll want to look into this further.) This is a much more complex calculation both intellectually and computationally than the equivalent calculation for standard multiplexing. Effectively, you get a duty cycle of \$1 / n\$ when all LEDs are lit but some (only some) patterns of n-1 or fewer LEDs can have a duty cycle of 100%. You're only guaranteed 100% duty cycle when lighting 1 LED.

The last method I'll mention is to use a shift register or IO expander. With two pins (Either the raw data/clock interface, I2C, or unidirectional SPI), you can control an arbitrarily large number of LEDs. The duty cycle for any pattern is 100%, but the update rate is inversely proportional to the number of LEDs. This is the most costly method. For 15 LEDs, it will probably be cheaper to just upgrade to a micro with that many IO pins.

share|improve this answer
+1 for explaining a bit about the duty cycle aspect. In the second sentence about Charlieplexing, did you mean "drive n^2-n LED's with n IO pins? – JYelton Mar 4 '11 at 21:52
Charlieplexing can be done very similarly to multiplexing, if one simply omits one light from each row. Actually, it may be possible to "regain" that light by adding a diode, though unless column drivers are constant-current outputs, making it match the brightness of the others may be difficult. – supercat Mar 18 '11 at 15:40

Use Charlieplexing, you can directly drive n*(n-1) LEDs from n pins

Exemple:

Six LED's on 3 Pins

PINS        LEDS
0 1 2   1 2 3 4 5 6
0 0 0   0 0 0 0 0 0
0 1 Z   1 0 0 0 0 0
1 0 Z   0 1 0 0 0 0
Z 0 1   0 0 1 0 0 0
Z 1 0   0 0 0 1 0 0
0 Z 1   0 0 0 0 1 0
1 Z 0   0 0 0 0 0 1
0 0 1   0 0 1 0 1 0
0 1 0   1 0 0 1 0 0
0 1 1   1 0 0 0 1 0
1 0 0   0 1 0 0 0 1
1 0 1   0 1 1 0 0 0
1 1 0   0 0 0 1 0 1
1 1 1   0 0 0 0 0 0

enter image description here

share|improve this answer
Thank you for the output pin dataset as well as a helpful schematic. – JYelton Mar 5 '11 at 2:15
1  
Another way of drawing the schematic is as an NxN grid, but driving columns only, and replacing the primary diagonal with row-column shorts. – supercat Mar 8 '11 at 16:10

Without multiplexing (direct drive) you are limited to 6 LEDs.

With charlieplexing you can drive n*(n-1) LEDs from n pins.

With I/O expanders or shift registers you can drive a virtually unlimited number of LEDs.
Example: MCP23008 8-bit I2C I/O Expander

share|improve this answer
Can you elaborate on what I/O expanders would be? – JYelton Mar 4 '11 at 19:26
2  
An I/O expander is external chip that contains I/O pins and registers. You can use standard communication bus like I2C or SPI to communicate with them. – mjh2007 Mar 4 '11 at 19:32
+1 You can drive a lot of LEDs with TI's TLC594 (focus.ti.com/lit/ds/symlink/tlc5940.pdf), but it may be overkill for many jobs. search.digikey.com/scripts/DkSearch/… – kenny Mar 4 '11 at 21:15
Thanks - I should design a project that makes use of I/O expanders to force my learning of their usage. – JYelton Mar 4 '11 at 21:48

As @mjh2007 suggested with an I2C expander. But there are ones specifically for driving LEDs which will avoid the need for external current-limiting resistors.

share|improve this answer

Here's an example of charlieplexing that I have built.

It's a lighthouse beam simulator and uses a series of 12 LEDs charlieplexed to 4 GPIOs to sweep a beam of light around a disc. There's a video of it here.

The project is PIC based, I use a PIC12f683 which is also an 8pin uP and could be considered comparable to the 8pin AVRs.

The LED's intensity is driven by an interupt that provides a 32 step PWM at around 60Hz. Only two LEDs are allowed to be lit at any one time giving a 50% duty for each LED as that was all I needed. It also gives a good trade off of PWM refresh rate against resolution.

The coding for using charlieplexing as actually pretty simple if you stick to the "classic" method of only lighting a single LED at any one point in time at a very fast refresh rate. I work out the required PORT and TRIS (pic specific registers) first on paper then store the results in a static array. To light LED x the PIC just has to lookup the value at the array's index[x] and write them directly to the PORT (with a bit of masking to preserve the state of the other pins not used in the charliplex)

My project only has 12 LED not 15 or the maximum 20 the 5 GPIO will allow as I wanted to keep one GPIO spare for future development.

Anyway... I just thought it might be helpfull to have a working example similar to your request.

Full source code and schematics are available on my blog.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.