Project showcase
Charlie Chaser

Charlie Chaser © GPL3+

A simple demonstration of charlieplexing: 12 LEDs are individually lit over 4 wires.

  • 4,535 views
  • 4 comments
  • 19 respects

Components and supplies

Necessary tools and machines

Tweezers
Those tiny jumper wires don't place themselves.

Apps and online services

Codebender
My primary IDE

About this project

Why did I do this?

At a recent MakerFaire, I acquired a SparkFun Badger where SparkFun was teaching people how to solder. Fortunately, the engineer who designed the Badger was standing right in front of me to assist and answer questions. I asked Shawn, "How did you get so many LEDs to illuminate individually with only eight pins?" He went on to explain charlieplexing. A few days later, I took the Badger and plugged it into my computer at work where it greatly reduces my productivity as I ponder the LEDs, microcontrollers, and other topics of electronics.

What is charlieplexing?

https://en.wikipedia.org/wiki/Charlieplexing summarizes it this way:

Charlieplexing is a technique for driving a multiplexed display in which relatively few I/O pins on a microcontroller are used to drive an array of LEDs.

The combination of active pins and current direction determines which individual LED illuminates. The voltage drop of other LEDs in series prevents them from illuminating even though they are biased correctly.

This diagram makes it easy to see:


If J1 pins 1 and 3 are connected to - and + of a current source respectively, then only LED 5 will illuminate. Even though LEDs 2 and 3 have the same orientation, their combined voltage drop will prevent illumination.

Where n is the number of pins: max number of LEDs = n² - n.

I'm keeping this short short because there are so many other explanations out there already.

The Charlie Chaser

One morning I was digging through my LED box and noticed I have about 200 right-angle green LEDs. "Something must be done about this," I said to myself. Supplies combined with the inspiration of the Badger, it was clear that I must charlieplex something. The mini bread board holds 12 LEDs which just happens to be the maximum supported by four pins.

Each LED sat directly across the breadboard aisle from another with the poles reversed. Placing jumpers across to it's twin made this puzzle a bit easier to solve. At that point it was essentially multiplexing. Six more jumper wires to complete all connections, and it was ready for a sanity check. The multimeter revealed no shorts, so I pulled out a battery pack and manually tested every combination of inputs. Two or three mistakes were made, but they were nondestructive and easy to correct. With corrections made, I hooked it up to the Arduino Uno.

The Chase Begins

With the hardware done, the coding began. I started by making a class for a pair of "across the aisle" LEDs. I called it "Charlie". Charlie objects handle all the pinMode(), digitalWrite(), and analogWrite() functions so the loop doesn't have to. Every Charlie function requires a boolean argument to specify which LED of the pair it will use. Looking back, software objects representing pairs of physical objects was probably inelegant, but hindsight is a fantastic teacher. Charlies are instantiated as global variables, and the loop calls functions to turn them on and off.

Several iterations of trial and error later, I have an array of LEDs chasing (hence the name) around the perimeter of the bread board. The duration of the flash vary with each loop. I really wanted to use the PWM pins of the Uno so I could dim the flash as well. 


Code

Untitled fileArduino
int ledPins[] = {5, 6, 10, 11};
int pinCount = 4;

class charlie{
	int pin1,pin2;
	
	public:
	charlie(int firstPin, int secondPin){
		pin1 = firstPin;
		pin2 = secondPin;
	}
	
	void flash(int duration, bool forward){
		setupPins();
		if(forward){
	    	digitalWrite(pin1, LOW);
	    	digitalWrite(pin2, HIGH);
		} else {
	    	digitalWrite(pin1, HIGH);
	    	digitalWrite(pin2, LOW);
		}
    	delay(duration);
	}
	
	void flash(int duration, bool forward, int intensity){
		setupPins();
		if(forward){
	    	analogWrite(pin1, intensity);
	    	digitalWrite(pin2, HIGH);
		} else {
	    	digitalWrite(pin1, HIGH);
	    	analogWrite(pin2, intensity);
		}
    	delay(duration);
	}
	
	private:
	
	void setupPins(){
		for (int thisPin = 0; thisPin < pinCount; thisPin++) {
	    	if(ledPins[thisPin] != pin1 and ledPins[thisPin] != pin2){
	    		pinMode(ledPins[thisPin], INPUT);
	    	}
		};
		
		pinMode(pin1, OUTPUT);
    	pinMode(pin2, OUTPUT);
	}
};

charlie C1(6,10);
charlie C2(11,10);
charlie C3(11,6);
charlie C4(11,5);
charlie C5(10,5);
charlie C6(6,5);

charlie Charlies[] = {C1,C2,C3,C4,C5,C6};

void setup()
{
	
}

void loop()
{
	int duration = 40;
	int durationStep = 3;
	int intensityStep = 3;
	
	for(int intensity = 240; intensity > 0; intensity += 0){
		for (int thisCharlie = 0; thisCharlie < 6; thisCharlie++) {
	    	Charlies[thisCharlie].flash(duration, true, intensity);
	    	intensity -= intensityStep;
		};
		for (int thisCharlie = 5; thisCharlie >= 0; thisCharlie--) {
	    	Charlies[thisCharlie].flash(duration, false, intensity);
	    	intensity -= intensityStep;
		};
		duration -= durationStep;
	}
	
	for (int thisCharlie = 0; thisCharlie < 6; thisCharlie++) {
	    	Charlies[thisCharlie].flash(duration, true);
		};
		for (int thisCharlie = 5; thisCharlie >= 0; thisCharlie--) {
	    	Charlies[thisCharlie].flash(duration, false);
		};
	
	for(int intensity = 0; intensity < 240; intensity += 0){
		for (int thisCharlie = 0; thisCharlie < 6; thisCharlie++) {
	    	Charlies[thisCharlie].flash(duration, true, intensity);
	    	intensity += intensityStep;
		};
		for (int thisCharlie = 5; thisCharlie >= 0; thisCharlie--) {
	    	Charlies[thisCharlie].flash(duration, false, intensity);
	    	intensity += intensityStep;
		};
		duration += durationStep;
	}
}
Charlie Chaser
This code creates objects for each pair of LEDs connected in parallel, but opposite polarity. The "flash" methods control how the lights are turned on. The main loop increases and then decreases speed and intensity of the LEDs chasing around the perimeter of the breadboard.

Schematics

Breadboard Layout
This show the details of how the breadboard is laid out.
Screen%20shot%202016 01 16%20at%2011.06.51%20am
Schematic
Charliechaserschematic

Comments

Similar projects you might like

Police Chaser Lights

Project showcase by Jolynn Awesome

  • 5,197 views
  • 0 comments
  • 20 respects

The TrafficLight

Project showcase by Advaith Jagathesan

  • 12,824 views
  • 1 comment
  • 20 respects

LED Blink Pattern

Project tutorial by Matt Arnold

  • 30,376 views
  • 14 comments
  • 84 respects

Measure your reaction time

Project tutorial by Jayraj Desai

  • 28,837 views
  • 9 comments
  • 29 respects

Arduino Button Troubleshooting

Project showcase by 3 developers

  • 465 views
  • 1 comment
  • 0 respects

00 to 99 on Seven-Segment Displays

by KVLakshmiSri

  • 26,456 views
  • 4 comments
  • 21 respects
Add projectSign up / Login