I’ve recently been doing some simple Python programming with the Raspberry Pi and a set of traffic light LEDs that connect to it. In this post I’ll look at setting up a Pi to drive the lights. In future posts, I’ll explore some other programming / devops concepts using the base setup described here.
I subsequently wrote versions of this article describing the same process using the Go programming language (here), Swift (here), Java (here), C (here), Bash scripting (here), Node.js (here) and also Node RED (here). Most recently I looked at this for Arduino, Rust and .NET/C# too.
- A Raspberry Pi (I’ll use the Pi 3 Model B here, but any model with GPIO pins will work — if you want to use the Pi Zero you’ll need to solder some headers onto it). I’m going to assume you have a Pi 2 or 3 with 40 pins
- A power supply for your Pi (Raspberry Pi 4 requires a different USB C power supply)
- Some sort of case is probably a good idea to protect the Pi (but you’ll need to leave the lid off to expose the GPIO pins to connect your lights to)
- A Micro SD card to install your operating system on (or get one with the OS pre-installed). If you want to install the operating system yourself, you’ll need a Mac, PC, Linux machine with an SD card reader
- A set of traffic lights from Low Voltage Labs (the two pack is good value)
- Any USB keyboard to type on the Pi, you might want a mouse too
- Any HDMI display to show output from the Pi
Attaching the Traffic Lights
The Low Voltage Labs traffic lights connect to the Pi using four pins. One of these needs to be ground, the other three being actual GPIO pins used to control each of the individual LEDs.
Before powering up the Pi, attach the traffic lights so that the pins connect to the GPIO pins highlighted in red:
When you’re done it’s going to look something like this… (an easy way to make sure you have it right is to locate the lights on the left hand row of pins as you look at the Pi with the USB ports to the bottom, then count 8 pins up and attach the lights there).
Don’t turn the Pi on yet, you’ll need to prepare an operating system image for it first…
Operating System Setup
Once you’ve got the operating system installed, make sure you can login, and have a working wired or wifi internet connection.
Now you can go ahead and start turning lights on and off!
Programming the Traffic Lights
We’ll use the Python programming language to make the lights work. First, you need to install a couple of extra software packages needed to allow you to download my sample code, and to give Python access to the GPIO pins on the Pi. Enter the following at the command line:
$ sudo apt-get install python-dev python-rpi.gpio git
Answer “Y” when asked if you want to install additional packages.
Now get the code from my GitHub repo:
$ git clone https://github.com/simonprickett/pitrafficlights.git $ cd pitrafficlights
You should now be able to test the lights:
$ python basicdemo.py
And if they are connected to the correct GPIO pins, they should start to flash on and off in the UK traffic light pattern (red, red + amber, green, amber, red). If you don’t see anything, you might need to make sure that you have the lights connected to the right pins.
How it Works
The code for this is very simple. It starts by importing the
RPi.GPIO library, plus
time which gives us a timed wait function,
signal that allows us to trap the signal sent when the user tries to quit the program and
sys so we can send an appropriate exit signal back to the operating system before terminating.
import RPi.GPIO as GPIO import time import signal import sys
Next we put the GPIO library into “BCM” or “Broadcom” mode (so we can refer to pins by the same numbers as are labeled with in GPIO pin diagrams), and sets pins 9 (red LED), 10 (amber LED) and 11 (green LED) to be used as outputs:
# Setup GPIO.setmode(GPIO.BCM) GPIO.setup(9, GPIO.OUT) GPIO.setup(10, GPIO.OUT) GPIO.setup(11, GPIO.OUT)
The main part of the program will run in an infinite loop until the user exits it by stopping Python with
Ctrl-C. It’s a good idea to add a handler function that will run whenever this happens, so that we can turn off all the lights prior to exiting (thus ensuring they’ll also be in the state we expect them to start in the next time the program is run):
# Turn off all lights when user ends demo def allLightsOff(signal, frame): GPIO.output(9, False) GPIO.output(10, False) GPIO.output(11, False) GPIO.cleanup() sys.exit(0) signal.signal(signal.SIGINT, allLightsOff)
The main body of the code then consists of an infinite
while loop that turns on the red light (pin 9), waits, turns on the amber light (pin 10), waits, then cycles through the rest of the traffic light pattern by turning the appropriate LEDs on and off:
# Loop forever while True: # Red GPIO.output(9, True) time.sleep(3) # Red and amber GPIO.output(10, True) time.sleep(1) # Green GPIO.output(9, False) GPIO.output(10, False) GPIO.output(11, True) time.sleep(5) # Amber GPIO.output(11, False) GPIO.output(10, True) time.sleep(2) # Amber off (red comes on at top of loop) GPIO.output(10, False)
Control-C is pressed an interrupt signal
signal.SIGINT is sent. This is handled by the
allLightsOff function that switches all the lights off, tidies up the GPIO library state and exits cleanly back to the operating system.
In the next post in this series, I’ll look at how to drive the lights in either the UK or USA patterns of operation then we’ll move on to other ways to structure and deploy the code.
I’d love to hear what you’re up to with the Raspberry Pi — find me on Twitter. If you enjoyed this article, please share it far and wide!