Holooly Plus Logo

Question 9.10: You want to control lots of LEDs using as few GPIO pins as p......

You want to control lots of LEDs using as few GPIO pins as possible.

Step-by-Step
The 'Blue Check Mark' means that this solution was answered by an expert.
Learn more on how do we answer questions.

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)
def set_pin(pin_index, pin_state):
if pin_state == -1:
GPIO.setup(pins[pin_index], GPIO.IN)
else:
GPIO.setup(pins[pin_index], GPIO.OUT)
GPIO.output(pins[pin_index], pin_state)
def light_led(led_number):
for pin_index, pin_state in enumerate(pin_led_states[led_number]):
set_pin(pin_index, pin_state)
set_pin(0, -1)
set_pin(1, -1)
set_pin(2, -1)
while True:
x = int(raw_input(“Pin (0 to 5):”))
light_led(x)

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
9.12
9.13

Related Answered Questions

Question: 9.11

Verified Answer:

Assuming you have a 5V volt meter, you can use a P...
Question: 9.9

Verified Answer:

Use PWM to control the power to each of the red, g...
Question: 9.8

Verified Answer:

Using the Tkinter user interface framework, write ...
Question: 9.7

Verified Answer:

Using the Tkinter user interface framework, write ...
Question: 9.5

Verified Answer:

Use a relay and small transistor. Figure 9-5 shows...
Question: 9.1

Verified Answer:

Connect an LED (see “Opto-Electronics” on page 381...
Question: 9.3

Verified Answer:

Use a piezo-electric buzzer connected to a GPIO pi...
Question: 9.4

Verified Answer:

These high-power LEDs use far too much current to ...
Question: 9.6

Verified Answer:

Use a PowerSwitch Tail II (see “Modules” on page 3...