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

  • \$\begingroup\$ I had not seen. Possibly duplicated: electronics.stackexchange.com/questions/9860/… \$\endgroup\$ Mar 4, 2011 at 19:36
  • 3
    \$\begingroup\$ 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. \$\endgroup\$
    – joeforker
    Mar 4, 2011 at 20:39
  • \$\begingroup\$ 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. \$\endgroup\$
    – JYelton
    Mar 4, 2011 at 21:47
  • 1
    \$\begingroup\$ @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! \$\endgroup\$
    – JYelton
    Mar 4, 2011 at 21:54
  • \$\begingroup\$ Duplicate: electronics.stackexchange.com/questions/1609/… \$\endgroup\$
    – mjh2007
    Mar 10, 2011 at 21:01

6 Answers 6


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:

$$\frac{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:

$$\frac{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.

  • \$\begingroup\$ +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? \$\endgroup\$
    – JYelton
    Mar 4, 2011 at 21:52
  • \$\begingroup\$ 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. \$\endgroup\$
    – supercat
    Mar 18, 2011 at 15:40

Using Charlieplexing you can directly drive \$n \times (n-1)\$ LEDs from \$n\$ pins.


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

Schematic of Charlieplexing with 3 output pins

  • \$\begingroup\$ Thank you for the output pin dataset as well as a helpful schematic. \$\endgroup\$
    – JYelton
    Mar 5, 2011 at 2:15
  • 1
    \$\begingroup\$ Another way of drawing the schematic is as an NxN grid, but driving columns only, and replacing the primary diagonal with row-column shorts. \$\endgroup\$
    – supercat
    Mar 8, 2011 at 16:10
  • \$\begingroup\$ means I cannot turn all of them on at once? Does that mean If I want to turn all of them on at once I have to do time-plexing enough to fool the eyes? \$\endgroup\$
    – MaNyYaCk
    Jul 20, 2018 at 12:05
  • \$\begingroup\$ @MaNyYaCk Yes. You're right. \$\endgroup\$ Jul 20, 2018 at 19:44

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

  • \$\begingroup\$ Can you elaborate on what I/O expanders would be? \$\endgroup\$
    – JYelton
    Mar 4, 2011 at 19:26
  • 3
    \$\begingroup\$ 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. \$\endgroup\$
    – mjh2007
    Mar 4, 2011 at 19:32
  • \$\begingroup\$ +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/… \$\endgroup\$
    – kenny
    Mar 4, 2011 at 21:15
  • \$\begingroup\$ Thanks - I should design a project that makes use of I/O expanders to force my learning of their usage. \$\endgroup\$
    – JYelton
    Mar 4, 2011 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.


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.


Another option would be to use the Neopixel LEDs. They have a built-in control IC and you only need one pin to control as many LEDs as you like. Of course you will need an adequate separate LED power source then.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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