Introduction: Chalieplexing 4 RGB-LEDs With 4 Wires on Arduino
Did you every need many LEDs, but only few wires? Then Charlieplexing is a great thing to try. With only 4 wires you can drive 12 LED with only 4 resistors as an optional protection and without any "intelligen" component like a 74595 or similar. - This example will show how to use 4 RGB LEDs to test this very nice concept. The generic code allows to control any number of lines very easy:
// A 4 wire setup
#define CHARLIE_PINS 4
// Arduino Pins 9 - 12 control the LEDs
#define CHARLIE_FIRST 9
//
// Sample 1: First LED(0,1) "On"
//
charlieClear(); // Clear all LED levels
charlieWrite(0,1,CHARLIE_MAX); // Set LED(0->1) to maximal level
charliePlex(); // Generate the output pattern
Step 1: Materials and Tools
The example will use 4 RGB LEDs which happend to lay in my drawer, but you may use any spare LEDs you want to sacrify.
Required Materials
- 4 RGB LEDs (or 12 single Color LEDs)
- Arduino whatever you have
Recommended Materials
- 4 Resistors, e.g. 3k3
- Small piece of perforated circuit board (or breadboard)
- 4 PIN male headers
Recommended Tools
- Boardmarker
- Grippers
- Wire cutter
- Soldering iron
Step 2: Prepare the Stripboard
We will add a resistor to each strip, so just leave two rows in the beginning of the strips empty: One for the headers, one for the start of the resistor, cut (= isolate) on the third row of holes, the LED will be plugged starting from the forth row (sorry, the picture is after soldering).
Step 3: Bend & Plug It Like Charlie
To simplify the bending, we mark the Stripboard distance on every pin all LEDs. This way it is very easy to bend the pin the required strip. Please be aware to keep always the same "orientation" of your LEDs. In this case Pin 3 is always the anode.
So the bending pattern is:
- LED
- Pin 1, Strip 1
- Pin 2, Strip 2
- Pin 3, Strip 3
- Pin 4, Strip 4
- LED
- Pin 1, Strip 2
- Pin 2, Strip 3
- Pin 3, Strip 4
- Pin 4, Strip 1
- LED
- Pin 1, Strip 3
- Pin 2, Strip 4
- Pin 3, Strip 1
- Pin 4, Strip 2
- LED
- Pin 1, Strip 4
- Pin 2, Strip 1
- Pin 3, Strip 2
- Pin 4, Strip 3
Step 4: Solder 28 Times
Now comes the easy part: Just solder all the LED-PINs, then the 4 resistors (I first used 3k3 throughholes and then 0k5 SMDs) and the 4 header pins. Keep a sharp eye on any shortcircuit on the front and back side of the board.
Step 5: Plug and Play With the Software
Now everything is ready to test the system. Take out your beloved Arduino (or if you're scard your Ruggduino), copy-paste the code in your Arduino sketch and modify it as required. Any improvements are welcome
/*
CharliePlexing Library
(c) by Olivier Chatelain 2014
This code is CC-BY-SA-3.0
*/
#define CHARLIE_PINS 4
#define CHARLIE_FIRST 9
// Setup the memory
#define CHARLIE_COUNT CHARLIE_PINS*(CHARLIE_PINS-1)
// Charlie Level (0 = off, 255 = max)
#define CHARLIE_LOW 0
#define CHARLIE_HIGH 255
#define CHARLIE_OFF 0
#define CHARLIE_MAX 255
// Charlie Levels for anode/cathode pin-pairs
uint8_t charliePins[CHARLIE_PINS][CHARLIE_PINS];
#define CHARLIE_GREEN 0
#define CHARLIE_BLUE 1
#define CHARLIE_RED 2
int charlieRGB[CHARLIE_PINS][3] = {{1, 2, 3}, {2, 3, 0}, {3, 0, 1}, {0, 1, 2}};
void charlieClear() {
for(int i = 0; i < CHARLIE_PINS; i++) {
for(int j = 0; j < CHARLIE_PINS; j++) {
charliePins[i][j] = CHARLIE_OFF;
}
}
}
void charlieSetAll() {
for(int i = 0; i < CHARLIE_PINS; i++) {
for(int j = 0; j < CHARLIE_PINS; j++) {
charliePins[i][j] = CHARLIE_MAX;
}
}
}
void charlieSetAllLevel(uint8_t level) {
for(int i = 0; i < CHARLIE_PINS; i++) {
for(int j = 0; j < CHARLIE_PINS; j++) {
charliePins[i][j] = level;
}
}
}
void charlieWrite(int src, int dst, uint8_t level) {
charliePins[src%CHARLIE_PINS][dst%CHARLIE_PINS] = level;
}
// current line displayed
int charlie_line = CHARLIE_PINS-1;
void charliePlexLine(uint8_t level) {
// Disable last line displayed
pinMode(CHARLIE_FIRST+charlie_line, INPUT);
if(++charlie_line >= CHARLIE_PINS) charlie_line = 0;
int i = charlie_line;
int MasterPin = CHARLIE_FIRST+i;
// Use others as follow pins (HIGH or INPUT)
for(int j = 0; j < CHARLIE_PINS; j++) {
int SlavePin = CHARLIE_FIRST+j;
if(MasterPin != SlavePin) {
if(charliePins[i][j] > level) {
pinMode(SlavePin, OUTPUT);
digitalWrite(SlavePin, LOW);
} else {
pinMode(SlavePin, INPUT);
}
}
}
pinMode(MasterPin, OUTPUT);
digitalWrite(MasterPin, HIGH);
}
void charliePlex() {
// Set one leadpin (LOW)
for(int i = 0; i < CHARLIE_PINS; i++) {
for(int j = 0; j < CHARLIE_MAX; j++) {
charliePlexLine(j);
delayMicroseconds(10);
}
}
}
// the setup routine runs once when you press reset:
void setup() {
}
void loop() {
//*
// Sample 1: First LED(0,1) "On"
//
charlieClear();
charlieWrite(0,1,CHARLIE_MAX);
charliePlex();
//*/
/*
// Sample 2: Dimm White
for(int i = 0; i < 8; i++) {
charlieSetAllLevel(1<<i);
charliePlex();
}
for(int i = 7; i > -1; i--) {
CHARLIE_PINS(1<<i);
charliePlex();
}
//*/
/*
// Sample 3: Alternate the COLORS
charlieClear();
for(int i = 0; i < CHARLIE_PINS; i++) {
charlieWrite(i, charlieRGB[i][CHARLIE_RED], CHARLIE_MAX);
}
charliePlex();
charlieClear();
for(int i = 0; i < CHARLIE_PINS; i++) {
charlieWrite(i, charlieRGB[i][CHARLIE_GREEN], CHARLIE_MAX);
}
charliePlex();
charlieClear();
for(int i = 0; i < CHARLIE_PINS; i++) {
charlieWrite(i, charlieRGB[i][CHARLIE_BLUE], CHARLIE_MAX);
}
charliePlex();
//*/
}
Enjoy it!
Participated in the
Arduino Contest