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?
|
|
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. |
|||||
|
|
Use Charlieplexing, you can directly drive n*(n-1) LEDs from n pins Exemple: Six LED's on 3 Pins
|
||||
|
Without multiplexing (direct drive) you are limited to 6 LEDs. |
|||||||||||
|
|
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. |
||||
|
|

