22 April 2009

Musings on Charlieplexing

Some time ago I stumbled over an article about charlieplexing on hackaday.com. Charlieplexing is basically a method to control n * (n-1) LEDs using only n I/O ports of a microcontroller. Say you have 5 I/O ports, then you can control 5 x 4 = 20 LEDs independently! Find more details in Wikipedia. I was fascinated, because I had never thought it was possible to control so many LEDs with so little hardware.

But it seems that charlieplexing comes with a few drawbacks. While this is certainly true, some of these drawbacks are in my opinion over-emphasised, especially when compared to "conventional" LED multiplexing. So I set out to explore the issue, just for the fun of it.

One misconception that seems not to go away is that there can always be only one LED activated at a time. Allegedly this means that a very high multiplexing frequency has to be used. Not true. If one I/O port is set to L, then the other ports can be set to either H or Z. For every port set to H, exactly one LED will be activated.

Perhaps this becomes clearer, if we compare a conventional LED multiplex matrix with a charlieplexed matrix.

A normal LED matrix looks like this:

You set one row line to L, the other two to H or Z. By setting any of the column lines to H you can activate their corresponding LED. With this conventional set-up you need 6 I/O ports and every LED has a duty cycle of 33%.

Now let's look at a charlieplexing configuration. I chose a schematic structure that is similar to the one above to make things clear:

Note that the R-ports have vanished. They are replaced by C-ports, which means that now there are only 3 ports controlling the matrix. You can verify that this is a charlieplexing structure by checking if there is a LED from every port to every port.

The result is that now we have three ports less, at the cost of three LEDs less. Those LEDs were useless, because there anodes and cathodes would be connected to the same I/O port in the new structure. Of course it would be possible to use 4 ports and then control 4 x 3 = 12 LEDs, but I wanted to keeps things similar.

If you look at that structure, perhaps it is easier to see how multiple LEDs can be activated at the same time. The duty cycle for a 6 LED set-up is again 33%. And immediately another fact can be seen. The layout of a charlieplexing structure is not more complicated than that of conventional multiplexing. This is true even for larger structures. Of course, a two layer wiring scheme is necessary, because in both cases there are a lot of lines crossing.

It is obvious that it is possible to move the LEDs so that you get a normal LED matrix. All you have to do is to bend your wiring somewhat. This is what I mean:

This is exactly the same structure as before, only the LEDs have moved to form an orderly matrix. Some people say that programming a charlieplexed display is quite difficult. I think this example shows that it really isn't to bad, because there is a lot of regularity in it. Controlling the display as shown here is just a little bit of bit-juggling - piece of cake.

And here is one last issue, that I would like to address: The limited current one can get from a microcontroller's I/O ports. It makes good sense to use very bright LEDs for a multiplexed display, because of the relatively low duty cycle per LED. So you get relatively high current requirements per LED. Many bright LEDs are rated at 20 mA, but can be supplied with higher pulse currents. This is a problem for many microcontrollers, because they can not drive these amounts of current. When you have a traditional multiplexed display, the solution is to use transistors. Usually an inverted driver configuration is used, like so:

For a charlieplexed display, an inverting driver would not work. But a non-inverting configuration works perfectly well. Here is how:

Simply an emitter follower. The hardware costs per port are the same as for conventional multiplexing. But remember that less ports are needed. So the total hardware costs are actually less.

To test my theories on charlieplexing, I had to build a display myself. I can say that everything works as expected. Here is a photo of that experiment. It consists of an Amtel tiny13, 20 LEDs, five transistors and resistors for current limiting. Lots of fun, and a nice project to show off...

Here is a photo of the hardware. It is built on a prototype board.

This video shows the display in action. Unfortunaltely it flickers a bit. It doesn't do that in real life.

And finally here is the schematic...

...and the corresponding layout.

That's it. My first post is finished. Let me know, what you think. Any comment is appreciated.

Update 25-Mar-2011: Due to popular demand, here is a link to the source code: Link.

It is written in assembler and probably not too well commented. It wasn't meant for publishing. If you just want to create your own patterns, leave everything alone apart from the main_loop. There is a "video ram" consisting of registers matrix0-4. Its contents will be converted and displayed by the interrupt routine.

You can just set those registers. There is also a set of  display manipulation routines, like scroll_up, invert_all and so on. See example patterns in the main_loop as to how they are used.


  1. can you message me the c source code for this please?

  2. great idea !
    where is the source code ?
    can you upload them pleas ???

  3. Hi there and thanks for your interest in the source code. It should be available now for download.

    musab2006, I can't mail it to you, because I don't have your mail address.

  4. What's with the 5 extra resistors? Your schematic only shows 1 per transistor base and one per cathode column. Did you put on in the anode path as well?

  5. ... or maybe you just didn't have the right values and had to put two smaller ones in series?

  6. Exactly. I didn't have the right values for the resistors, so I used them actually in parallel.

  7. Thanks for the response - I am going to try your 4x4x4 cube. I'll let you know how it goes :)

  8. I have a question...
    The transistors are used to source a higher current than what your uC can handle, right? But this current is sunk through the uC pins anyway. Therefore the transistors are useless?

  9. Ah, you are partly right. But consider how the multiplexing works. The transistor supplies a full column of LEDs. The cathodes of the LEDs of that column are connected to one port each. The uC ports can source/sink enough current for one LED. So there is no need for a transistor on the rows. But for the columns a transistor _is_ needed.

  10. hi tom..

    just want to know what compiler did you use for the program? tnx

    1. Hi,
      i used the AVR Studio, available free of charge from Atmel. You start a new project, point it to the right directory and to the downloaded asm file.

  11. Hi Tom. I just wanted to say thanks for this post. You helped me immensely with a school project involving Charlieplexing. I based a lot of my initial design on your LED matrix-like circuit diagram.

    In case you want to check out what I made, check this youtube link.

    1. Hi p3lb0x, thanks for letting me know. I had a look at your video and it really looks great. The 7x8 matrix is quite impressive.

  12. Hello,

    Could show explain how you calculate the duty cycle in multiplexing?

    20 LEDs 5 ports at a frame rate of 50Hz : this means u scan the entire 20 leds at 50hz
    4 LEDs simultaneous update rate 250Hz : this is 5 times more
    in your blog : The duty cycle for a 6 LED set-up is again 33% :- how did u arrive at 33% duty cycle?

    This same comment is on youtube too...

  13. Ahmed,

    yes, this is a very important point I was trying to make in this post. Most people maintain that with charlieplexing, the duty cycle is 1/(number of LEDs). They say that because they assume that only one LED can be active at any time.

    But this need not be true. In my smaller 3-port example (with the driver transistors), there will be one port "high" (activating one transistor). Then the other two ports can either be "low" or "off". This means that 2 LEDs can be active at the same time.

    Then you can cycle through the 3 ports. Always, on port is high, while the other two ports can be low. Each individual LED can be switched on, when the corresponding driver is active - this means for 33% of the time.

    With the larger set-up, everything scales up. You have 5 ports cycling through, resulting in a 20% duty rate. The interrupt, which cycles through the driver transistors and activates the LEDs runs at 250 Hz. But it has to cycle through 5 drivers before every LED had a chance to get activated. So the frame rate is 50 Hz. But the important point is that the LED duty cycle is 20%, not 5% as some people would have you believe.

    Maybe the text in the video is a little misleading...

  14. Dear Tom,

    Thank you for the answer. Now I understand your circuit very well. You are using all in the LED's in forward bias mode i.e, they are powered by the transistors.

    As per the microchip appnote and this link : http://www.josepino.com/microcontroller/how_control_leds :- the difference in connecting leds one in forward bias and other in reverse bias to the same port compared to your circuit made me to think.

    About duty cycle, your explanation is clear. I need to do my math to understand better. If in case I need clarification will seek your help.

    With regards
    Mukhthar Ahmed

  15. Dear Tom,

    I have to say I am new in electronics and can't read schematics properly. So where exactly do the collectors of the transistors go to and what's the role of the 100n in the circuit? Thanks in advance!

    1. Alexander, the collectors all go to +5V, that is what the little arrows symbolise.

      Don't worry too much about the 100n capacitor. It is a decoupling capacitor.


      It is there for moments, when the circuit needs a lot of current in very little time. It then acts as a kind of high speed battery.

      It might not even be necessary in this circuit, But it doesn't hurt, so it is good practise to add it.

  16. Hey Tom, wouldn't wiring rgb leds like this create problems because of the different voltage drops?

    1. Yes, they would. This is a limitation of charlieplexing.

      Wikipedia says (http://en.wikipedia.org/wiki/Charlieplexing):
      Forward voltage

      When using LEDs with different forward voltages, such as when using different color LEDs, some LEDs can light when not desired.

      In the diagram above it can be seen that if LED 6 has a 4v forward voltage, and LEDs 1 and 3 have forward voltages of 2v or less, they will light when LED 6 is intended to, as their current path is shorter. This issue can easily be avoided by comparing forward voltages of the LEDs used in the matrix and checking for compatibility issues. Or, more simply, using LEDs that all have the same forward voltage.

      I think, normally red LEDs start to light up at around 1.5V and modern blue LEDs have forward voltages of around 3V. To avoid the problem you could add a series diode to the red LEDs, effectively increasing their forward voltage.

  17. How can a led light up without having it's cathode Low and it's anode High? I can see how it would affect things in the wiki example but we are implementing charlieplexing differently here.

    1. Alexander, the answer is obviously, that an LED can't light up without the cathode low and the anode high.

      In principle, charlieplexing is implemented just like in the Wikipedia. The only difference is that I added driver transistors to the anodes of all LEDs.

      The transistors behave like non-inverting drivers.

      Keep in mind that in my matrix, exactly one transistor will be active (high) at any given time. So four LEDs will see high on their anodes.

      All other port pins are either low or tri-state, so of the four LEDs, any number can see a low on their cathode - lighting them up.

  18. Tom here is another question. Are the base resistors required and how would it affect the circuit if we omitted them ?

    1. Alexander, I think you can omit those resistors without any consequences.They can be useful if you are experimenting and something goes wrong (like a short circuit).

      I added them to limit the transistor's base current. But under normal circumstances, higher base current means higher LED current, which means higher LED voltage, which means lower base-emitter voltage, which means lower base current.

      So the base current will be "self-setting".

    2. PS: It might actually be possible to omit the 270 Ohm resistors as well, depending on your supply voltage. The controller's IO pins can only drive a certain amount of current and that current will be not enough to destroy the LEDs.

      What happens is that a heavily loaded IO pin will not be able to "deliver" a "clean" low. Instead, the voltage will be somewhat above 0 Volts. Have a look at the data sheet. This is another stabilising effext. YMMV!

    3. I made a matrix using your design but omitting the base resistors and it seems there are capacitance problems with the transistors delaying when I switch them off. Maybe the resistors in your circuit help to discharge the capacitance ?

      Btw the problem with the wikipedia example is that when you set a pin as high , another as low and the others as high impedance , there are more than one possible paths for the current to travel but the voltage drops prevent the extra leds to glow very brightly.

      Oh there is also a very new charlieplexing technique which allows to control n*n ports with only n pins using extra diodes.

    4. Alexander, I don't think that those resistors help discharging any capacitor. But I don't really understand what you mean by delay. The multiplexing happens at high speed (>100Hz), so a switching delay should not be visible. Could there be a problem with your software?

      Yes, the wikipedia example shows that there are alternative current paths. This is really a problem, when you mix colours (e.g. blue and red: 3.3 Vot/1.7 Volt).

      I read about such a multiplexing technique. But it needs relatively complex driver/decoder circuits, which makes them less attractive.

      I am also using drivers, but they are no more complex than those of a conventionally multiplexed matrix.

  19. This page is the best explnataion of how to do charlieplexing properly that I have found.

    What's the purpose of R1-R5, in my experience emitter followers self-limit the base current.

    1. Thank you!

      And yes you are right, R1-R5 are useless. I put them in out of caution. This was an experimental set-up and I wanted to add some protection against short circuits, etc.

  20. This comment has been removed by a blog administrator.