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
Remove these ads by
Signing UpStep 1Some LED theory
Firstly what happens when you connect an LED to electricity.
The main diagram below shows what is called the If v Vf curve of a typical 5mm low power LED.
If stands for 'forward current'
Vf stands for 'forward voltage'
The vertical axis in otherwords shows the current that will flow through an LED if you put the horizontal axis voltage across it's terminals. It works the other way around as well, if you measure that the current is of some value, you can look across to the horizontal axis and see the voltage the LED will present across it's terminals.
The second diagram shows a schematic representation of an LED with If and Vf labelled.
From the main diagram I've also labelled areas of the graph that are of interest.
- The first area is where the LED is 'off'. More accurately the LED is emitting light so dimly you won't be able to see it unless you had some sort of super-duper image intensifier.
- The second area has the LED just slightly emitting a dim glow.
- The third area is where an LED is usually operated and is emitting light at the manufacturers rating.
- The forth area is where an LED is operated beyond it's operating limits, is probably glowing very brightly but alas for only a short time before the magic smoke inside escapes and it won't operate again......ie in this area it burns out because too much current flows through it.
Note that the If/Vf curve or operating curve of the LED is a 'non-linear' curve. That is, it is not a straight line...it has a bend or kink in it.
Lastly this diagram is for a typical 5mm red LED designed to operate at 20mA. Different LEDs from different manufacturers have different operating curves. For example in this diagram at 20mA the forward voltage of the LED will be approximately 1.9V. For a blue 5mm LED at 20mA the forward voltage might be 3.4V. For a high power white luxeon LED at 350mA the forward voltage might be around 3.2V. Some LEDs packages might be several LEDs in series or in parallel, changing the Vf/If curve again.
Typically a manufactuer will specify an operating current which is safe to use the LED at, and the forward voltage at that current. Usually (but not always) you get a graph similiar to below in the datasheet. You need to look at the datasheet for the LED to determine what the forward voltage is at different operating currents.
Why is this graph so important? Because it shows that when a voltage is across the LED, the current that will flow will be according to the graph. Lower the voltage and less current will flow.....and the LED will be 'off'. This is part of the theory of charlieplexing, which we'll get to in the next step.
| « Previous Step | View All Steps | Next Step » |















































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?
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.
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.
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.
// With 5V on pin B and 0V on pin A LED1 will glow.
should be "LED2", right?
- rob
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;
}
}
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.
http://www.youtube.com/watch?v=8apRaZQbv5w