Step 2: Charlieplexing - The theory

Ok, the principle behind Charlieplexing is fairly simple. If you hook up 2 LED's between 2 micro-controller pins with 1 anode towards pin 1 and one anode towards pin 2, you turn on LED1 by setting pin 1 HIGH and pin 2 LOW. To turn LED2 on you reverse it - Set pin 1 LOW and pin 2 HIGH. See the first image below.

This of course means that only one of the LED's can be on at any time. Microcontrollers operate so quickly that you can just alternate their on states very quickly and it will look like both are on all the time.

Now at this point, you'll probably be saying "Well, so what? I could turn 2 LED's on using 2 pins without all this extra complexity..."

If you add a third micro-controller pin to the equation it starts getting interesting. Now you can turn on 6 LED's. Basically, you have the same setup as with 2 pins, but you also have the same setup between pin 2 and 3 and between pin 1 and 3. See the second image below.

To turn on the LED's connected to pin 1 and 3, you need to disconnect pin 2 from the circuit, and then just set pin 1 and 3 HIGH and LOW based on which LED you want to turn on. Luckily, the Arduino allows you to do this. If you change a pin to an input, it basically turns into a big resistance, which is close enough to being disconnected for this to work.

Now if you look at the third image, you can see what this looks like for 4 pins (12 LED's) and the fourth image shows you what it looks like for 5 pins (20 LED's).

You'll notice that it becomes rather interesting to wire it up by the time you get to 30 LED's with 6 pins. This for me seems like the limiting factor when building this.

I generated the images from the following link (I see the link is dead at the moment... I'm not sure if this is temporary):

<p>good one i also got the same idea for making a water fountain which consisted of 2000+leds which have different styles to glow using one arduino. so i used nearly 6 pwm pins to vary value to give a fading effect and rest of the pins as blink </p>
<p>Hey, this is the best Charlieplexing tutorial I have come across, your wiring diagram helped me so much!</p><p>I ended up doing mine in groups of four (And the wiring is hideous...) but the code still cycles through beautifully from one to the next. Thank you so much!</p>
<p>Hey.</p><p>I have managed to adapt your code to run my 15 LEDs in charlieplexing.<br>I don't know why you grouped your LEDs in 5 arrays of 4, but I had to un-group it in order to run 15 LEDs in one row. I am impressed by that bit math, I have never had that kind of &quot;math&quot; nor in C++ or Java programming that I did in universities, so I appreciate you sharing your code. I've learned a lot and manage finish my little project.</p><p>Thank you.</p>
<p>Hey.</p><p>Here is a working pin of a very useful, quick an easy way to see the wiring needed for n amount of pins:<br><a href="http://www.modelci.net/charlieplex/index.php?pin=5" rel="nofollow">http://www.modelci.net/charlieplex/index.php?pin=5</a></p><p>You could probably replace the dead link you have with this one.</p>
<p>I meant to write &quot;link&quot;... Too much of charlieplexing for me today, head is wrecked :)</p>
<p>I had this same issue with multiple LEDs lighting when I thought only one should. For me the problem was that I was writing a new data value before setting the correct port direction. That short bit of time was enough to light some LEDs. Not saying that was your issue but it sounds like what I was seeing.</p>
<p>Hey hey... this is a nice trick!!! thanks for sharing it !!!! ... know leds do something awesome! =)</p>
This is pretty cool, i successfully hooked it up using a simple two pin and then a three pin. I'd say i can confidently handle this on a larger scale now. You are right though this does take up a lot of space, but at least it uses less pins. Thanks!
Great and clear I'ble! Thanks for sharing. <br> <br>Could I use Charlieplexing as you described it, with &quot;AnalogWrite&quot; (instead of DigitalWrite).? I would like to change the intensity of a large numer of LED's and Arduino has a limited amount of pins to do this (pins 3, 5, 6, 9, 10 , 11).
this helped some, thanks
I'm struggling to understand your code. Would you mind going through Display_Frames.pde and commenting so that we could figure out what each section a little easier?<br><br>I'm new to coding and it would REALLY help.<br><br>Please :-}
I'm a bit swamped at the moment, but I'll try to help you out with this on the weekend.
Thanks! I appreciate you finding time to help :-)
I'm very confused about something. In the image above you have a red and a black wire coming from what I assume are the +5 power and ground pins. In neither of the images below do you show anything about a power and a ground. Did I miss something? <br><br>To make things easier for me when I set up my Charileplexed matrix I did it exactly as you see the first image. <br><br>Into a piece of wood I drilled two sets of five holes about 5 inches apart. Then I strung wire between those holes and soldered the LEDs across them as you showed in the first example. I soldered resistors to the end of the wires. I checked the matrix by running power across each wire. The LEDs lit up correctly and worked fine. Then I plugged them into pins 1, 2 , 3 ,4 and 5. <br><br>However when I loaded your program, which I have to admit I have trouble following, nothing happened... Where did I go wrong?
The power from the Arduino to the breadboard is just a habit I have... It's not actually hooked up to something in the Charlieplex circuit.<br><br>The second problem you have is that the pins in the software doesn't correspond to the way you've wired them up to the Arduino. This is a bit confusing, and I don't specifically mention it... I'll fix that in the Instrucatable. <br><br>If you look at the code, you'll see this at the top:<br>#define A 8<br>#define B 9<br>#define C 10<br>#define D 11<br>#define E 12<br><br>That defines what pins connect the Arduino to the Charlieplex. So just change your connections to connect to pins 8-12 and it should work fine.
Duh, I looked at the code and understood that much. I don't know why that didn't occur to me. If it was a snake it would have bit me...<br><br>http://www.youtube.com/watch?v=YBJwUTHt8Do <br><br>I had to change this part:<br><br>int c[5][4][2] =<br>{<br> { {A, B}, {A, C}, {A, D}, {A, E} },<br> { {B, A}, {B, C}, {B, D}, {B, E} },<br> { {C, A}, {C, B}, {C, D}, {C, E} },<br> { {D, A}, {D, B}, {D, C}, {D, E} },<br> { {E, A}, {E, B}, {E, C}, {E, D} }<br>};<br><br>To this:<br><br>{<br> { {A, B}, {B, A}, {B, C}, {C, B} },<br> { {C, D}, {D, C}, {D, E}, {E, D} },<br> { {A, C}, {C, A}, {B, D}, {D, B} },<br> { {C, E}, {E, C}, {A, D}, {D, A} },<br> { {B, E}, {E, B}, {A, E}, {E, A} }<br>}<br><br>So that my LEDs would light in order. <br><br>I know this may be asking a bit much but if I wanted to create different patterns instead of just cycling through each LED what might be the best way?
The sketch in step 7 lets you set up custom displays. and display them. It's not the easiest code to customize, but I haven't come up with anything better yet.<br><br>The 'int frames[][5] = {..}' array defines the patterns to display, and you can display the pattern using the 'void display( int frame[5], int duration ){...}' method.
Ahh, crap... I had the wrong sketch attached to step 7... The new sketch I've attached to step 7 is what's running in the video.
Sadly that code is way above my abilities at the moment. I have however figured out how to make three different types of light animations the hard way. Hey I'm just learning :-)<br><br> Below is the first &quot;frame&quot; of animation code that would start out in the middle of a strip of 20 charlieplexed LEDs then go out to both ends and back into the middle again.<br><br>int ledPin1 = 8;<br>int ledPin2 = 9;<br>int ledPin3 = 10;<br>int ledPin4 = 11;<br>int ledPin5 = 12;<br><br>void setup() {<br>}<br><br>void loop() {<br> int a;<br> for( a = 0; a &lt; 50; a++ )<br> {<br> pinMode(ledPin1, INPUT);<br> pinMode(ledPin2, OUTPUT); <br> pinMode(ledPin3, INPUT); <br> pinMode(ledPin4, OUTPUT); <br> pinMode(ledPin5, INPUT);<br> digitalWrite(ledPin2, HIGH);<br> digitalWrite(ledPin4, LOW);<br> delay(.5);<br> pinMode(ledPin1, OUTPUT);<br> pinMode(ledPin2, INPUT); <br> pinMode(ledPin3, OUTPUT); <br> pinMode(ledPin4, INPUT); <br> pinMode(ledPin5, INPUT); <br> digitalWrite(ledPin3, HIGH);<br> digitalWrite(ledPin1, LOW); <br> delay(.5);<br> }<br><br><br>Now I just have to figure out how to add a potentiometer to vary the speed of the animation and either a rotary switch or a series of switches that would enable me to change to the different patterns...<br><br>Thanks for the head start. :-)
This is so cool. I have never understood Charlieplexing until now. Thanks for posting this. You got my vote!
Thanks for the thumbs up. I'm glad I could help.

About This Instructable


105 favorites


More by riaancornelius: Controlling 20 Led's from 5 Arduino pins using Charlieplexing Accessing 5 buttons through 1 Arduino pin - Revisited How to access 5 buttons through 1 Arduino input
Add instructable to: