How to Drive a Lot of LEDs From a Few Microcontroller Pins.





Introduction: How to Drive a Lot of LEDs From a Few Microcontroller Pins.

Using the fact that many microcontroller pins have three states (+V, GND, or
"high impedence", you can drive N*(N-1) LEDs from N pins. So the little 8
pin microcontroller like a PIC12Fxxx or an ATtiny11 can drive 20 LEDs on
its five available output pins, and still have one pin left for some kind of input.

See also

Step 1: 20 LEDs on 5 Pins

The current crop of low pin-count microcontrollers (6 pins to 20 pins on
the whole package) are attractively priced and 'cute', but the question
arrises as to how you can make the best use of those pins for common
applications such as driving LEDs.

A direct-connect approach to driving LEDs consumes one pin for each
LED. A traditional multiplexing scheme where rows of LED anodes are
driven by one set of N pins and each row's common cathode is driven by
another set of M pins manages to light N*M LEDs with N+M pins.
However, on a processor with only 5 or fewer outputs (as is the case
with most 8-pin microcontrollers), this barely gets you any more
outputs than direct drive.

Step 2: Charlieplexing

Assuming the output pins are actually tri-state-able (active high,
active low, and high impedence (input)) it is also possible to share
the row and column drivers and control N*(N-1) LEDs with only N pins.
One pin is connected to common cathodes of a row of LEDs and driven
low, and the N-1 pins remaining are connected to the anodes and either
driven high to light that column, or left as inputs to leave the LED
off. Maxim calls this technique "Charlieplexing", and describes it in
(1); Microchip also mentions this in their document (2) (and
implements in on the PICKit 1 board as well.)

(1) "Charlieplexing - Reduced Pin-Count LED Display Multiplexing"

(2) "Tips 'n Tricks 8-pin FLASH PIC Microcontrollers"

(3) Charlieplexing LEDs- The theory An Instructable by rgbphil

Step 3: Putting It to Work.

This drives 20 LEDs from an ATtiny11. An earlier version of this board was
actually built and appears as the main page photo. I'm afraid the picture
of the schematic is pretty hopeless; you need Eagle to tell you which signals
are connected where.

Step 4: Smaller and More Versatile...

Since most of the board is taken up by the LED array, we can make room
for either a Attiny chip OR a microchip PIC12F chip. Shrink the LEDs down
to 3mm and go to a double sided board, and we get something about 27x44mm

Alas, this board hasn't been tested yet...

Step 5: Itty Bitty

Microchip of course has their 6 pin PIC10F chips, capable of driving a
mere 6 LEDs from the 3 output pins. This is about 16mm in diameter.
Going to 603 LEDs lets you get a bit smaller, but I'm not sure what's the point.

Step 6: Software

The software gets a bit messy for serveral reasons:

1) for the PCBs shown, the LEDs are laid out in a way that is convenient
to the PCB layout, rather than in "correct" bit order. IMO, this is the
way to do things, but it does mean that Row 1 doesn't necessarilly mean
bit 1, or coluimn 3 doesn't mean bit 3. This requires a level of mapping
between the usual row/column addressing and the bits that need setting.

2) Since the same bits are used for anodes and cathodes, the common
(row) connection for some bits can be in the middle of driven (column)
bits. That means you have to shift column bits around depending on whether
they are before or after the row bit for that set of columns.

3) You have to derive output words for both the ioport and the port direction

The attached ASM code for ATtiny11 is a "proof of concept." It's embarassingly
un-optimized and poorly commented, but it's all I've got written so far.



    • Science of Cooking

      Science of Cooking
    • Pro Tips Challenge

      Pro Tips Challenge
    • Pocket-Sized Contest

      Pocket-Sized Contest

    We have a be nice policy.
    Please be positive and constructive.




    Hiya, I'm really interested in how you've done this, and I would like to use the technique on a project I'm working on at the moment, which is a working model theatre. Does anyone know whether it is possible to have more than one LED on at once if they are connected through to the same pins?? Thank you!!! Dedward

    You Can, Almost all Large LED displays use this Multiplexing Theory. Its in the code to have many lights on in the same row and column on at the same time. Sadly, I'm still working on learning that Part. but there are many resources out there that can help with the code

    (after nearly a year of deep thought,) I think the problem with having more than one LED on at a time in a charlieplexed environment stems from using the microcontroller pins as both the current source and current sink for the LEDs. Most microcontrollers (old-school ones, anyway, like PICs and AVRs) can easilly source/sink enough current for ONE led (10-40mA), but if you start talking about a pin sinking the current for SEVERAL LEDs, you quickly run the risk of exceeding the maximum current specs.

    In a traditional multiplexed environment it is easy to make the anodes and/or cathodes each have their own high-current drivers as needed, but it's much more difficult to do this with a connection that can be anode, OR cathode, OR off depending on circumstances (at least, without reaching a circuit complexity level that is the opposite of what we're trying to achieve by charlieplexing.)

    This is a long time later, but still an interesting problem. You can turn on more than one LED by using PWM to light the LEDs. e.g.You can multiplex through turning on each LED (if it's LED is meant to be on) and keep it on for up to a set amount of time depending on how bright it is meant to be (lets say 1ms is the brightest). You ignore the LEDs that are meant to be off and continue on to the next LED and the next and so on until you reach the last. If the last LED is done, you then start at the beginning again. Now the problem with this is that you will pass through all the LEDs in max 20ms. The eye perceives flashing if the changes happen slower than 24mS, so we are under that threshold, so it should work. The max brightness for any LED will be 1/20 of full brightness (if all LEDs are on). However, if typically only a small number of LEDs are on, leds say 3 or 4, then they'll be on for 1/3 or 1/4 max brightness. If someone has this circuit, maybe they can experiment and see how well this works....the LEDs might be too dim if all on to be able to see any one LED being only on for 1/20 of the time.

    Well, that's pretty impressive for all passive hardware!
    It puts the programming a bit beyond a lot of people though! LOL!

    good day!!! i just want to know of what are the software used for making schematics like in this instructable...

    hoping for your answers...

    Eagle is commercial product but there is free edition which has some restrictions of course (board size, number of layers etc.). There are open source alternatives like KiCad.

    You mention the trick of re-arranging the bits to make the circuit board simpler. Good plan! The way to do it easily is to first write the software as if the bits didn't need switching. Instead of writing the output byte directly to the port, you first write it to the index register. Then you use a "scramble table" to re-arrange the bits. You index into the table, then write that byte to the port. The advantage of this scheme is if you need to change the bit order, no change is needed to the code; only the table.

    (I'm not familiar with this processor. My comments are based on the ability to do indexed addressing mode.  Index into a table. For example, for the "noadjust" routine, you would have:
    TABLE: .byte 0b00100, 0b00010, 0b00001, 0b10000, 0b01000

    copy TEMP to index register
    load accumulator TABLE,index
    copy accumulator to ANODE
    You can have separate tables for the port and the direction register. The tables can be large (256 bytes for an 8-bit scramble function) without needing a compare for each value possible. The code becomes compact and easy to debug. You can stack tables. For example, one set to give the port/direction drives, and one to do the bit scrambling (used twice: once to scramble the port bits, again to scramble the direction bits)).

    Table lookup is the key to fast processing!

    can i use Attiny13A instead of Attiny11...?? thanks :)