10

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?

JYelton
  • 32,302
  • 33
  • 134
  • 249
  • I had not seen. Possibly duplicated: http://electronics.stackexchange.com/questions/9860/what-is-needed-to-control-200-leds-from-an-arduino – Daniel Grillo Mar 04 '11 at 19:36
  • 3
    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 04 '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 04 '11 at 21:47
  • 1
    @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 04 '11 at 21:54
  • Duplicate: http://electronics.stackexchange.com/questions/1609/how-many-individual-lights-can-an-arduino-control – mjh2007 Mar 10 '11 at 21:01
  • @mjh: I wanted to post a question worded in this way because at one time I would have found it immensely helpful. The question you reference is specific to an Arduino though certainly the principle is identical. – JYelton Mar 10 '11 at 23:30

6 Answers6

18

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.

Ricardo
  • 6,134
  • 19
  • 52
  • 85
Kevin Vermeer
  • 19,989
  • 8
  • 57
  • 102
  • +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 04 '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
12

Using Charlieplexing you can directly drive \$n \times (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

Schematic of Charlieplexing with 3 output pins

Ricardo
  • 6,134
  • 19
  • 52
  • 85
Daniel Grillo
  • 7,659
  • 18
  • 51
  • 69
8

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

mjh2007
  • 3,899
  • 24
  • 49
  • Can you elaborate on what I/O expanders would be? – JYelton Mar 04 '11 at 19:26
  • 3
    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 04 '11 at 19:32
  • +1 You can drive a lot of LEDs with TI's TLC594 (http://focus.ti.com/lit/ds/symlink/tlc5940.pdf), but it may be overkill for many jobs. http://search.digikey.com/scripts/DkSearch/dksus.dll?Detail&name=TLC5940NTG4-ND – kenny Mar 04 '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 04 '11 at 21:48
4

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.

Brian Carlton
  • 13,252
  • 5
  • 43
  • 64
2

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.

Matt Casey
  • 43
  • 2
0

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.

needfulthing
  • 197
  • 4