Project showcase
Charlie Chaser

Charlie Chaser © GPL3+

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

  • 5,939 views
  • 5 comments
  • 22 respects

Components and supplies

Ph a000066 iso (1) ztbmubhmho
Arduino UNO
×1
Kingbright wp7113sgd
5 mm LED: Green
×12
Mfr 25frf52 100r sml
Resistor 100 ohm
×4
Mini Breadboard
×1
Jumper Wires
This part is a collection of wires. Many wires were used.
×1

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

  • 9,403 views
  • 0 comments
  • 23 respects

The TrafficLight

Project showcase by Advaith Jagathesan

  • 16,551 views
  • 1 comment
  • 23 respects

Pixel Chaser Game

Project tutorial by Unexpected Maker

  • 4,979 views
  • 2 comments
  • 28 respects

Measure your reaction time

Project tutorial by Jayraj Desai

  • 33,229 views
  • 10 comments
  • 35 respects

Easy Countdown with Buzzer

Project showcase by Marcazzan_M

  • 15,451 views
  • 4 comments
  • 23 respects

How to Use an RGB LED

by MisterBotBreak

  • 6,533 views
  • 2 comments
  • 22 respects
Add projectSign up / Login