Charlieplexing is a rather new multiplexing technique. It was first proposed in early 1995 by Charlie Allen at Maxim Integrated Products for driving a multiplexed display. Like other multiplexing techniques (eg matrix), charlieplexing is used to control more loads with less I/O ports.
A typical I/O port of a microcontroller, when used as an output, has basically two states: the HIGH and the LOW state. When the port is used as an input, it is driven into High Impedance state. During this state, the port's internal resistance gets very high values (Mega Ohm), and the current that flows through the port is very small, measured in micro amperes.
Charlieplexing can multiplex the I/O ports of a microcontroller more efficiently, because it utilizes this characteristic, which is called "tri-state".
Step 1: A Very Simple Example
Look at the following simple circuit, which uses two ports to control two LEDs.
Here is the principle of operation. The two LEDs are connected anti-parallel, the anode of the red LED (left) is connected to the cathode of the green LED (right).
When port 1 becomes HIGH and port 2 becomes LOW, then the green LED turns on, and when port 1 becomes LOW and port 2 becomes HIGH, the red LED turns on.
Step 2: One More Port...
Now we add one more port to control more LEDs. I have broken apart the circuit into 3 sub-circuits, each one showing 2 ports. So, we have 2 LEDs controlled by port 1 and 2, two more LEDs controlled by ports 1 and 3, and another 2 LEDs controlled by ports 2 and 3, a total of 6 LEDs.
So, with the same principle as before, a microcontroller can control individually 6 LEDs with only 3 ports. As i said before, the charlieplexing utilizes the tri-state of a micro-controller's port. But how?
Let us re-draw the same circuit with the 3 ports and the 6 LEDs, but this time we will not draw them separately:
When Port 1 is HIGH and Port 3 is LOW, then L6 will light. But in what state must Port 2 be? If Port 2 is HIGH, then L4 will light as well, and if it was LOW, L2 would light simultaneously. So, to avoid unwanted situations, Port 2 must be in High impedance state. We make this pin an INPUT. Same applies of course if we try to light L2. Port 1 should become HIGH and Port 2 should become LOW. If Port 3 was HIGH, L3 would light as well, and if it was LOW, L6 would light simultaneously. So, the general rule is that, only 2 ports can be simultaneously outputs and all others are in High Impedance state by defining them as inputs.
You can find a working example here: