Instructables
Picture of Charlieplexing LEDs- The theory
HPCharlie.bmp
This instructable is less a build you're own project and more a description of the theory of charlieplexing. It's suitable for people with the basics of electronics, but not complete beginners. I've written it in response to the many questions I've gotten in my previously published Instructables.

What is 'Charlieplexing'? It is driving lots of LEDs with only a few pins. In case you're wondering Charlieplexing is named after Charles Allen at Maxim who developed the technique.

This can be useful for lots of things. You may need to display status information on a small microcontroller, but only have a few pins spare. You may want to show a fancy dot matrix or clock display but don't want to use lots of components.

Some other projects demonstrating charlieplexing you may want to look at are:
How to drive a lot of LEDs from a few microcontroller pins.
by Westfw :- http://www.instructables.com/id/ED0NCY0UVWEP287ISO/
And a couple of my own projects,
The Microdot watch:- http://www.instructables.com/id/EWM2OIT78OERWHR38Z/
The Minidot 2 clock:- http://www.instructables.com/id/E11GKKELKAEZ7BFZAK/
Another cool example of the use of charlieplexing is at:
http://www.jsdesign.co.uk/charlie/

The Minidot 2 clock introduces an advanced charlieplexing scheme for fading/dimming which won't be discussed here.

UPDATE 19 August 2008 : I've added a zip file with a circuit that may be able to exploit the matrix charliplexing for high power LEDs discussed (at length :) ) in the comments section. It has a pushbutton + position encoder to do a user interface, plus circuitry for either USB or RS232 computer control. Each of the high side voltage rails can be set to one of two voltages, say 2.2V for RED LEDs and 3.4V for green/blue/white. The voltage for the high side rails can be set by trimpot. I'd envisage that a 20wire IDC ribbon cable be plugged into the board, and 20pin IDC connectors added along the length of the ribbon, each LED board having links to whatever wires in the matrix are desired. The circuit is in Eagle Cad and rendered in the sub image below. The high side circuit is implemented by using optocouplers which I think might be suitable.

I haven't actually tested this circuit nor written any software because of lack of time, but have put it up for comment, I'm particularly interested in the optocoupler implementation. Anyone brave enough to give it a go...please post your results.

UPDATE 27th August 2008: For those not using EagleCad....added below is a pdf of the schematic
HPCharlie.pdf(595x842) 44 KB
 
Remove these adsRemove these ads by Signing Up
1-40 of 99Next »
Is it possible to use diodes instead of LEDs, and get logic signals from a charliplexed matrix?
I really don't know why someone would build a Manual switched 20 LED charlieplexed box, But I did!
DSC_0501.JPG
that looks really cool!
maikmuc2 years ago
hi
I would like to make a chain of LED lights for the x-mas tree out of it, pulsing and blinking in different modes. I also want to use 6 pins to be able to use 30 LED's in a total lenght of 3 meters...
Will this work? or will the LED's are too dim?
Thank you so much for posting this! I am working on my electrical engineering senior design project which is going to be a bicycle with a lighting system along with other features. I am looking into Charlieplexing the taillight which is made up of 3 premade LED matrices.

My main question is, what is the actual time that each LED is lit up? I understand that the human eye takes in a new image 25 time per second, so I'm wondering how long should each LED stay lit for.

I'm also concerned that with the LED matrix I'm using, I won't actually be able to wire all of them up in the way that you've shown. This is the part I'm using: http://www.futurlec.com/LED/LEDM88RGCA.shtml

Check out http://litebike.info for more information about our project!

Thanks again.
Tail_wag3 years ago
Simply an excellent article. Can you confirm that we cannot turn on all LED's in the matrix at the same time using this method? Thanks.
rgbphil (author)  Tail_wag3 years ago
You should only keep one LED on at a time if you have no buffering on your micro, or else the current draw will exceed the micro design tolerances.

However if you read the front page, there is quite a thread on lighting several LEDs at once with a charlie matrix. It is possible, but you should really buffer the control lines.

Check out the comments on this and follow the links back to the bloke who put me right in this regard.....he's got some great examples of more advanced charliplexing on his pages and probably a better explanation than I could have done.
Eliche3 years ago
Excellent explanation, very easy to follow and very helpful.
budabob073 years ago
If you were to set pin A to high and pin C to low, led 5 would light up. But wouldnt leds 1 and 3 also light up (dimly) This is what happened to me when i tried the circuit
rgbphil (author)  budabob073 years ago
Yes...check the comments in the text. The amount would depend on the type of LEDs, their forward voltages, minimum operating current and the voltage/current you are putting across the grid.
I suspect either you have some really cool low current LEDs, the voltage is too high or the current limit resistors being used are too small.
lavert314 years ago
hey, if instead if disconnecting pin B you will put it in HIGH you'll get the same effect. current wont go through LED 1 due to zero voltage difference. i say that because i wonder how can you disconnect and reconnect pins in the microcontroller? you can either put it on 1 or 0 no?
Good question. That is addressed in the next "step", "Tri-states".
Typo: In the 6th paragraph, last sentence,

// With 5V on pin B and 0V on pin A LED1 will glow.

should be "LED2", right?

- rob
rgbphil (author)  Rob Cranfill3 years ago
Yep, thanks, should be updated now.
WVvan4 years ago
A most excellent article. Couldn't be more clear.
Vick Jr4 years ago
OK. I understand the theory completely, even the math for computing how many leds can be controlled with x many io pins. If that schematic for a charlieplex matrix were expanded, it would be fractal. It's pretty cool actually. Now to turn theory into practice. I'm trying to make a charlieplexed led cube that's 4x4x4 (64 leds) which could theoretically be controlled with 9 io pins, but I can't wrap my head around mapping a 2d fractal charlieplex schematic into a 3d circuit. I already have all the wows done, with all the cathodes on a row connected and the anodes unconnected for now. How do i complete it? Any help would be appreciated. I plan to control it with an arduino, and may make it into an instructible. (if people aren't tired of led cubes, that is) My backup plan is to just have a pin corresponding to each of the 4 levels and each of the 16 columns. Thats 20 io pins needed. The arduino has 13 regular digital pins, 6 analogue pins that can also be used as digital io, so it's 1 pin short. I'd have to leave something off.
rgbphil (author)  Vick Jr4 years ago
Heres how I did mine; http://www.instructables.com/id/3D-LED-Charlieplex-Cube-from-Chrismas-Tree-Lights/ I had grids or meshs forming the charlieplex array. Note, my array was very sparse, so I was using more signal lines than I really needed. This was mostly for mechanical convenience than anything else. Phil
Vick Jr rgbphil4 years ago
Ahhhh, I see what you did. I actually got the idea to use xmas tree leds from you, but I was constructing it according to this and didn't alternate the polarity of the leds with the layers, which I think is the key to your method. No matter, I have plenty of xmas lights and plenty of time. I can make 2 cubes (or one giant stack!) There might also be a way to charlieplex one or two places in my configuration. I only need to reduce the number of io pins by 1 to work with the ardiuno. Thanks for your help, and how's your next cube with the "proper charlieplex driving scheme" coming along? Try making a template to put your leds in, then overlay the chicken wire or whatever (I used paperclips) and solder it in. That would be a good way to get the leds and their support structure as exact as possible.
rgbphil (author)  Vick Jr4 years ago
Glad to be any help. I honestly haven't had time for any more charlieplexing cubes....although I have been thinking of alternatives....why not have a hex structure, each LED is in the vertex of a 3d hex shape rather than a cube so they are all equidistant.....a bit different (more net interest), plus higher LED density. Another alternative may be to do away with the lattice (cube or hex) altogether. Instead have a charliplexed string driven from below without any cross connections at all. Eg three pins, gives 6 LEDs, 4 gives 12 LEDs high. Then just arrange the strings vertically into whatever shape you want, cube, cylinder, sphere etc. You could also make a charlieplex chandelier if they hang freely. You can be flexible, test as you go and build as you go as well. This would probably require more io pins, I've been wracking my brain how to share io between strings on this setup. Note charlieplexing with fewer io pins means lower individual brightness because only one LED can be easily lit at a time (scrummage through the comments below, there is a solution for making several lit at a time...albeit at an increase in wiring complexity). More io pins used on a sparse charlieplex matrix increases the brightness. Good luck, please experiment and if you have time write up an instructable (linking to any reference sources of course) for others to enjoy and learn from. I've gotten quite a buzz from all the happy campers who've read this instructable and learnt something. phil
Vick Jr rgbphil4 years ago
I like the hex idea-sortof like an led ball or sphere. As for the string idea, check out this project for charlieplexed string of 12.

If and when I make an instructable, I'll be sure to refer to yours. I'm having problems getting my cube to work with my arduino though. When I test it with a battery, connecting positive and negative to the correct wires, the correct led lights up, but when I use the ardiuno, some leds work fine, but others will not light up, or have other leds light up with them. If the cube works, then it must be a problem with my arduino or with my program.

Is it possible that there's some sort of interference or something between the pins that makes them not behave as expected?

Here's my code (sorry if formatting is undone.)

It's pretty well commented. The cube is set up like yours, with alternate rows as complimentary drives. I use all the io pins except 13 and 19 (analogue 5).  T light up an led first disconnect all pins (set as input), then set it's poll and level as input and apply voltage and ground (digital out HIGH/digital out LOW) appropriately.

/*
This program controls a 4x4x4 semi-charlieplexed LED cube using 18 io pins
Alternate rows of the cube have leds with opposite poles, and are complimentary drives.
pins are refereed to by row, column, and layer (r,c,l), going front-to-back,left-to-right, and bottom-to-top.
The rows and columns are connected to poles that go through the layers.
*/

//array mapping led rows and columns to arduino pins
int gridPinMap[4][4]=
{
{0,1,2,3},
{4,5,6,7},
{11,10,9,8},
{14,15,16,12}
};

//ints mapping cube levels to arduino pins
int levels01pin = 17;
int levels23pin=18;

void setup(){
Serial.begin(9600);// initialize serial communications at 9600 bps:
allOff();
pinMode(13, INPUT);//we don't use 13 b/c it has a built-in resistor but just in case, disconnect it
}

void loop(){//main loop
//this simple program turns each pin on for a second successivly
for (int r=0;r<4;r++){
for (int c=0;c<4;c++){
for (int l=0;l<4;l++){
LEDON(r,c,l);
delay(1000);
allOff();
delay(1000);
}
}
}
}

//this function disconnects all the io pins we are using, so nothing should be on at all.
void allOff(){
Serial.print("\nOFF" );
//set everything to output by default
for (int r=0;r<4;r++){
for (int c=0;c<4;c++){
pinMode(gridPinMap[r][c], INPUT);
}
}
pinMode(levels01pin, INPUT);
pinMode(levels23pin, INPUT);
}

//this function turns on the led at (r,c,l)
void LEDON(int r, int c, int l){
Serial.print("\n(");
Serial.print(r);
Serial.print(c);
Serial.print(l);
Serial.print(")");

//if the led to light is in row 0 or 2, it's column needs a ground (digital out LOW), and the level needs a positive voltage (digital out HIGH).
//Vice-versa if on levels 1 or 3

switch (l) {
case 0://bottom level
//disconnect the other two columns so no other pins go on
//pinMode(levels23pin, INPUT);
//send ground to column of pin
pinMode(gridPinMap[r][c], OUTPUT);
digitalWrite(gridPinMap[r][c],LOW);
//send voltage to row of pin
pinMode(levels01pin, OUTPUT);
digitalWrite(levels01pin,HIGH);
break;
case 1://first level up
//pinMode(levels23pin, INPUT);
pinMode(gridPinMap[r][c], OUTPUT);
digitalWrite(gridPinMap[r][c],HIGH);
pinMode(levels01pin, OUTPUT);
digitalWrite(levels01pin,LOW);
break;
case 2://second level up
//pinMode(levels01pin, INPUT);
pinMode(gridPinMap[r][c], OUTPUT);
digitalWrite(gridPinMap[r][c],LOW);
pinMode(levels23pin, OUTPUT);
digitalWrite(levels23pin,HIGH);
break;
case 3://top level
//pinMode(levels01pin, INPUT);
pinMode(gridPinMap[r][c], OUTPUT);
digitalWrite(gridPinMap[r][c],HIGH);
pinMode(levels23pin, OUTPUT);
digitalWrite(levels23pin,LOW);
break;
}
}
rgbphil (author)  Vick Jr4 years ago
Hi, I've got a few things on my plate today...so I haven't had a thorough read of the code sorry. So based on this: Some possibilities: - I'm guessing all the LEDs are the same colour, if not see the instructable about the issue where the forward voltage difference between colours can result in a problem. - check your digitalWrite and PinMode routines don't have the read/modify/write issue common to PICs (I'm not familiar with Arduino code ). In PICs a bit change on a port can sometimes be unreliable for various reasons, it's usually better to use a shadow port register and write the whole port register at once from this or use a r/c/l coordinate to locate a bit mask as in my code. Instead of setting each r/c/l to INPUT individually, just set the whole port register or registers to INPUT at once in the allOff routine. It'll be faster as well without an array sweep. If you check my code I stored the port register input/output bit masks as well as the output register bit masks and outputted those. Try changing the code to simply run through a couple of LEDs then stop. Then use a multimeter to see if multiple I/O pins are being set to low or high. You should only have two lines active either low or high, the rest should be tri-state or input. You can use a large pull up/pull down resistor sitting on the multimeter probe to check if the line is tri-state. If you can pull it up and down then it's set to an input. If it sticks at high or low, then it is an output. Phil
Vick Jr rgbphil4 years ago
The LEDs are the same type, but they are ripped from an old string of xmas lights. They are bleached from sunlight, some are rusty, but they seem to work.

The regular arduino language is a high level C-like library with functions for pin manipulation, but I did find this page on directly manipulating pins . It should be helpfull. I'll try it in a bit.
lavert314 years ago
Ohhhh o.k! now i answered myself! putting pin B in an HIGH state will cause LED 3 to glow... the only solution is to disconnect pin B . thanks for this very comprehensive tutorial! Etay
lavert314 years ago
:-) o.k now you actually answered my question about disconnect pins. but still, instead of disconnect you can put it on HIGH no?
tonysofla4 years ago
I made a 12 led Charlieplexed with softwarebased 8bit PWM
http://www.youtube.com/watch?v=8apRaZQbv5w
rgbphil (author)  tonysofla4 years ago
nice work, it's pretty hard getting good PWM on charlieplex unless you're throwing lots of cycles at it so hats off. I look forward to a fancied up instructable of your own detailing the innards of the software.
codongolev4 years ago
man.... that explained it so well. thanks!
RobbMeex4 years ago
I just put this thing together!! Thanks a bunch. I was looking for a simple two digit display for a GPS speedometer.
haooken4 years ago
Excellent explanation. I'll definitely have to give this a try.
i first i was slightly intimidated by ur explanation but after reading it, i feel like i can teach my electronics teacher this concept. thanks -drew
Thanks a lot!
Koolraap5 years ago
It's such an easy to understand explanation, i totally graped the concept with one read :)
ian25 Koolraap5 years ago
I have never understood this "charlieplexing" thing, but after reading this I understood it completely. 5 *'s
rgbphil (author)  ian255 years ago
Thanks for the compliment...and to all the other people the instructable has helped and taken the time to comment.
aolinger5 years ago
I've got it, and I'm a complete new to to microcontrollers and electronics! Thanks for this great explanations! Alex
51fordf25 years ago
Thanks, about the easiest to understand explanation I have seen. R
geeklord5 years ago
In step two, don't you want 3.2-3.8 volts across an LED?
rgbphil (author)  geeklord5 years ago
No, if you read closely you find I looked at my forward operating region for the LED from my graph and it was 1.9V, I wanted 3.1V shared between the two resistors. For combined red/green/blue LED matrices I made a note in step six to be careful about mixing different colours as they might have different forward voltages. In practice I found with the LEDs I had for my clock the green/blue LEDs lit up nicely at 1.9V, presumably because they were low power SMD devices or I was just luck ...so I didn't have to worry, however you do need to check this first. Other LEDs may well have higher forward voltages and in that case green/blue LEDs will need a separate matrix.
thank you, that was helpful
UziMonkey5 years ago
Thanks, this was really helpful.
1-40 of 99Next »