Charlieplexing is a method for controlling a large number of LED's with a relatively low number of pins on the AVR. Charlieplexing was developed by Charlie Allen at Maxim, and several specialized controllers exist for controlling seven segment displays. The following explanation uses only the AVR, no specialized controllers.
Whereas multiplexing uses <math>n+m</math> pins to control <math>n*m</math> LED's, charlieplexing can control <math>n*(n-1)</math> LED's with only <math>n</math> pins. This is possible by using the tri-state property of the ports on the AVR. Each IO pin can be either high (connected to VCC), low (connected to GND), or input (not connected to anything). When the pin is set to input, it will not affect the voltage of the connected wire. This is one of the principle that makes charlieplexing possible. The other important principle is that LED's only produce light when the ON-voltage is exceeded in the forward direction. That is, if the voltage over the LED is less than the ON-voltage, the LED does not produce any light.
Using the <math>n*(n-1)</math> formula, the smallest number of pins possible is 2, which will control 2 LED's. The setup can be seen in the diagram below. This simple setup is overkill, but as the table further down shows, we now have full control over which LED's are emitting light. Note that only three of the nine cases are useful, so there is a lot of overkill. Z represents High-impedance, which can be translated to Input on the AVR.
By adding another pin, four more LED's can be controlled (<math>3*(3-1)=6</math>), and we end up with a circuit diagram like below. This is the simplest case where the third state is needed. By setting PIN1 high, and PIN2 low, D1 will emit light. But we also need to set PIN3 to control the other LED's. If PIN3 is set to high-impedance, then only D1 will emit light. Current will flow from PIN1 to PIN2 through D1, making it emit light, but there will also be a parallel circuit through D5 and D4. Since this circuit has two LED's in series, the voltage over each LED is only half of the voltage over D1. By choosing the VCC (high voltage) above the ON-voltage but less than twice the ON-voltage, only D1 will emit light.
Using this method, every LED can be controlled individually. The circuit diagram above can be expanded by adding more pins. Each pin should be connected to every other pin with an LED, in both directions. Using this method, a single LED can be turned on by setting the anode-pin high, the cathode-pin low, and every other pin to input (high impedance).
Charlieplexing and 7-segment displays
Charlieplexing seems perfect for controlling 7-segment displays, because it uses fewer pins than multiplexing. 8 7-segment displays can be used with only one port on an AVR. The following method can use a maximum of 6 7-segment displays, because this simplifies the firmware and makes it easier to control a single 7-segment.
The circuit diagram below shows how to connect 6 7-segment displays to 8 IO-pins. The first display (CHR0) connects led1 to A, led2 to B ... led7 to G and led8 to the common pin. The 7-segment display can be common cathode or common anode. The rest of the article assumes common anode, because it is slightly easier to program.