You want to control lots of LEDs using as few GPIO pins as possible.
The way to do this is to use a technique called Charlieplexing. The name comes from the inventor, Charlie Allen of the company Maxim, and the technique takes advantage of the feature of GPIO pins that allows them to be changed from outputs to inputs while a program is running. When a pin is changed to be an input, not enough current will flow through it to light an LED or influence other pins connected to the LED that are set as outputs.
Figure 9-12 shows the arrangement for controlling six LEDs with three pins.
Figure 9-13 shows the breadboard layout for the LEDs and resistors.
To make this recipe, you will need:
• Breadboard and jumper wires (see “Prototyping Equipment” on page 380)
• Three 470Ω resistors (see “Resistors and Capacitors” on page 380)
• Six LEDs (see “Opto-Electronics” on page 381)
Open an editor (nano or IDLE) and paste in the following code. As with all the program examples in this book, you can also download the program from the Code section of the Raspberry Pi Cookbook website, where it is called charlieplexing.py.
This example code prompts you to enter a number between 0 and 5 and then lights one of the six LEDs:
import RPi.GPIO as GPIO pins = [18, 23, 24] pin_led_states = [ [1, 0, -1], # A [0, 1, -1], # B [-1, 1, 0], # C [-1, 0, 1], # D [1, -1, 0], # E [0, -1, 1] # F ] GPIO.setmode(GPIO.BCM) |
Discussion
To understand how Charlieplexing works, imagine that you want to light LED A in Figure 9-12. An LED will only light when its positive lead is high, and its negative lead is low. If the voltage is the other way around, it will not light. To light LED A, you need its lead connected to GPIO 18 (via a resistor) to be high and the other lead to LED A, connected to GPIO 23 by a resistor, to be low. However, you must also make sure that GPIO 24 is set to be an input; otherwise, LED C or D will also light depending on whether GPIO 24 is high or low.
The array pin_led_states holds the settings for each GPIO for each of the six LEDs. If the value is 0, the pin is low; 1 means high and -1 means set to be an input.
The number of LEDs that can be controlled per GPIO pin is given by the formula:
LEDs = n² – n
Using 4 pins, we can have 16, 4, or 12 LEDs, whereas 10 pins would give you a massive 90 LEDs.
In this example, you’re lighting only one LED at a time. To light more than one at a time, you need to run a refresh loop that keeps the desired state of the LEDs in an array and refreshes the display, turning on the LEDs that need to be on before moving on to the next. It must do this sufficiently fast so that it appears that more than one of the LEDs is on at the same time.
The more LEDs you use when it comes to making it appear that more than one LED is on at a time, the less time the LED will actually be lit, and the dimmer the LEDs will become.
See Also
For more information about Charlieplexing, see Wikipedia. If you are interested in using only a single LED, see Recipe 9.1.
Table A-3. Prototyping equipment | |
Description | Suppliers |
M-M jumper wires | SparkFun: PRT-08431, Adafruit: 759 |
M-F jumper wires | SparkFun: PRT-09140, Adafruit: 825 |
F-F jumper wires | SparkFun: PRT-08430, Adafruit: 794 |
Half-sized breadboard | SparkFun: PRT-09567 Adafruit: 64 |
Pi Cobbler | Adafruit: 1105 |
Table A-4. Resistors and capacitors | |
270Ω 0.25W resistor | Mouser: 293-270-RC |
470Ω 0.25W resistor | Mouser: 293-470-RC |
1kΩ 0.25W resistor | Mouser: 293-1k-RC |
3.3kΩ 0.25W resistor | Mouser: 293-3.3k-RC |
4.7kΩ 0.25W resistor | Mouser: 293-4.7k-RC |
10 kΩ trimpot | Adafruit: 356, SparkFun: COM-09806, Mouser: 652-3362F-1-103LF |
Photoresistor | Adafruit: 161, SparkFun: SEN-09088 |
220nF capacitor | MCM: 31-0610, Mouser: 80-C322C224M5U5HA |
Table A-7. Opto-electronics | |
5mm red LED | SparkFun: COM-09590, Adafruit: 299 |
RGB common cathode LED | SparkFun: COM-11120 |
TSOP38238 IR sensor | SparkFun: SEN-10266, Adafruit: 157 |