Wikijunior:Raspberry Pi/Raspberry Pi LEGO® Traffic Lights

From Wikibooks, open books for an open world
Jump to navigation Jump to search

Tutorial by Andrew Oakley
Public Domain 26 Sept 2015
www.cotswoldjam.org

LEGO® is a trademark of the LEGO Group of companies which does not sponsor, authorize or endorse this tutorial nor Cotswold Raspberry Jam.

Introduction[edit | edit source]

This tutorial shows you how to build a set of traffic lights based around LEDs (lights) and a Raspberry Pi computer. The lights can be placed inside a LEGO® Technic brick and used with other LEGO® models.

Getting started[edit | edit source]

Conventions[edit | edit source]

Things that appear on the screen or need to be typed in are written like this.

At the end of each line, you will usually have to press the ↵ Enter key.

Your tutor should have prepared your Raspberry Pi for you. If not, see the section "Preparation" at the end.

The electronics[edit | edit source]

Components[edit | edit source]

The light-emitting diode (LED) has a short leg and a long leg. If you feel around the rim, you'll also find a flat edge. The short leg and flat edge always connect to the negative (ground). We use 5mm LEDs because they fit into LEGO® Technic holes.

The resistor can be connected any way around. Lower value (lower Ohm) resistors will allow more current through and will make the LED brighter; higher values will let less current through and make it dimmer. We're using a 270 Ohm resistor but anything between 220–470 Ohms will work fine. We will use one resistor connected to the ground to cover all 3 LEDs.

These three LEGO® bricks can be made into a traffic light, and the 5mm LEDs fit inside the holes of the Technic brick.

The part numbers for these bricks – which can be purchased second-hand on sites such as eBay or Bricklink.com – are:

Push the LEDs into the Technic brick so that the short legs of each LED are at the bottom.

You will need to connect the short legs to a single resistor and then to one of the Raspberry Pi’s ground pins. Your tutor may have made up a special "pigtail" cable to do this, or you may use a breadboard.

Ground (negative) wires[edit | edit source]

Pigtail cable
Your tutor may have made up this cable using a DuPont crimper

It has three female ends on one side, which plug into the short legs of the LEDs, a resistor in the middle, and a single female end on the other side which plugs into pin 9 (ground) of the Raspberry Pi. A short bit of clear sticky tape wraps around the resistor to hold it in place.

Breadboard

If you don’t have a specially-made pigtail cable, you can use a breadboard to connect the three LEDs' short legs to one resistor and ground. You will need four male-to-female jumper wires, plus the resistor.

Do not worry about the colours of the jumper wires. They do not have to match the LED colours. The author of this document is heavily colourblind, so the colours will be random anyway.

The three jumper wires at the top of the breadboard go to the short legs of the LEDs. The single jumper wire at the bottom goes to ground (pin 9) on the Raspberry Pi.

Signal (positive) wires[edit | edit source]

Once you’ve got the resistor and ground connected to the LEDs’ short legs, you can test any LED by using a female-to-female jumper wire to connect the long leg to pin 1 (live 3.3 Volts) on the Raspberry Pi (assuming the Raspberry Pi is powered on).

However, we don’t want the lights on all the time; we need them to be controlled by a program. Disconnect pin 1 once you’re finished testing the lights.

To control the LEDs from our program, use female-to-female jumper wires to connect the long (positive) legs of the LEDs to the following pins on the Raspberry Pi:

  • Pin 11 — Red
  • Pin 13 — Yellow
  • Pin 15 — Green

The program[edit | edit source]

Power up your Raspberry Pi, log in and go to the desktop. If you need to log in, the default username is pi and the password is raspberry. If the desktop still does not appear, type startx and press the ↵ Enter key.

From the menu, select Programming – Python 3. Then use File, New Window to create a new program.

Type in the following program, or alternatively you can use File, Open to open the traffic1.py program in the python/traffic folder.

import RPi.GPIO as GPIO, time
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)

red=11
yellow=13
green=15

GPIO.setup(red, GPIO.OUT)
GPIO.setup(yellow, GPIO.OUT)
GPIO.setup(green, GPIO.OUT)

Use File, Save to save this program as traffic1.py. Here's what this program is doing:

import RPi.GPIO as GPIO, time

This command teaches the Raspberry Pi about its GPIO pins, so it can turn the LEDs on and off, and about time, so we can tell it to wait for a few seconds between each colour.

GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)

Here we’re telling the computer to use call the pins by the numbers in the order they are laid out on the board (there is an alternative way of numbering them called BCM). Next we tell it not to warn us if the GPIO pins have already been used.

red=11
yellow=13
green=15

Now we're telling the Raspberry Pi which pins are used for which coloured LEDs. Note that we don’t have to state that we're using pin 9 for ground; it doesn’t matter.

GPIO.setup(red, GPIO.OUT)
GPIO.setup(yellow, GPIO.OUT)
GPIO.setup(green, GPIO.OUT)

Finally we tell the Raspberry Pi to prepare the red, yellow and green pins for output. If we were getting input, such as reading a switch, then this bit would look different.

This part of the program just gets everything ready. It doesn’t actually turn any of the LEDs on. We'll do that next.

Use File, Save As to save the program as traffic1.py. Don't worry it it tells you that the program already exists – save it anyway.

Lighting up one LED[edit | edit source]

Let's start by lighting up the yellow LED. At the bottom of the program, add these lines:

GPIO.output(yellow, GPIO.HIGH)
time.sleep(2)
GPIO.output(yellow, GPIO.LOW)

HIGH turns a light on. LOW turns it off.

Save the program as traffic2.py.

Now leave the Python window open, and start a terminal session by going to the main desktop Menu - Accessories - Terminal. You should see a black window open.

In the terminal, type:

cd python/traffic
sudo python traffic2.py

You should see the yellow LED light up for two seconds, and then the LED will turn off and the program will end. You can repeat the program by entering sudo python traffic2.py again.

Try changing the program to light up the red or green LED.

Flashing an LED on and off repeatedly[edit | edit source]

Now let’s change the program so that the last lines read:

while (True):
  GPIO.output(yellow, GPIO.HIGH)
  time.sleep(2)
  GPIO.output(yellow, GPIO.LOW)
  time.sleep(2)

Save this program as traffic3.py. Go back to the black terminal window and run it with:

sudo python traffic3.py

The yellow LED should flash on and off every 2 seconds.

Exit the program by holding down the CTRL key and tapping the C key. This may leave the yellow light on! Don’t worry about that.

The full sequence[edit | edit source]

The full sequence for British traffic lights is:

  • Red (stop) — for a long time
  • Red and Yellow together (get ready to go) — for a short time
  • Green (go) — for a long time
  • Yellow on its own (get ready to stop) — for a short time

Let's change our program to do this full sequence:

while (True):
  GPIO.output(red, GPIO.HIGH)
  time.sleep(5)
  
  GPIO.output(yellow, GPIO.HIGH)
  time.sleep(2)
  
  GPIO.output(red, GPIO.LOW)
  GPIO.output(yellow, GPIO.LOW)
  GPIO.output(green, GPIO.HIGH)
  time.sleep(5)
  
  GPIO.output(green, GPIO.LOW)
  
  GPIO.output(yellow, GPIO.HIGH)
  time.sleep(2)
  
  GPIO.output(yellow, GPIO.LOW)

That's it! Save this program as traffic4.py. Go back to the terminal window and run it with:

sudo python traffic4.py

Exit the program by holding down the CTRL key and tapping the C key.

You can use the alloff.py program to turn all the lights off after you've stopped the program. Also there is the traffic5.py program which uses some advanced techniques to turn off the lights when the program is stopped.

Further adventures[edit | edit source]

Here’s some ideas for other things you could do:

Run two sets of lights from one Raspberry Pi[edit | edit source]

You could use pins 12, 16 and 18 (plus pin 14 for ground) to control another set of lights.

For a T-junction you need 3 sets of lights. For a crossroads, 4 sets[edit | edit source]

On a Model B+ or Pi 2 you could use pins 36, 38 and 40 (plus pin 34 for ground) to control a third set of lights, or you could use two Raspberry Pis.

If you had more than one Raspberry Pi, how could you synchronise the lights? How could two Raspberry Pis communicate between each other?

How could you detect a toy car waiting at the lights?[edit | edit source]

Does your strategy work if it is a plastic LEGO® car or a metal toy car, or both? Does it matter if the car is heavy or light?

What about if it was a bicycle or a horse? How do traffic lights in the real world detect cycles and horses – do they have another strategy, or do they ignore that problem?

How could you run your program automatically when you turn on your Raspberry Pi?[edit | edit source]

Try searching for information on the crontab @reboot command: https://www.adminschoice.com/crontab-quick-reference

Preparation[edit | edit source]

The files for this tutorial can be found at: http://www.cotswoldjam.org/downloads/2015-09/

Please create a python folder under the home/pi directory, then unzip the files into that python directory. This can be done in the LXTerminal:

mkdir python
unzip traffic.zip

Files[edit | edit source]

The original PDF for this tutorial is on Wikimedia Commons: Cjam-traffic-light-tutorial.pdf

alloff.py[edit | edit source]

#!/usr/bin/env python

import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)

red=11
yellow=13
green=15

GPIO.setup(red, GPIO.OUT)
GPIO.setup(yellow, GPIO.OUT)
GPIO.setup(green, GPIO.OUT)

GPIO.output(red, GPIO.LOW)
GPIO.output(yellow, GPIO.LOW)
GPIO.output(green, GPIO.LOW)

traffic1.py[edit | edit source]

import RPi.GPIO as GPIO, time
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)

red=11
yellow=13
green=15

GPIO.setup(red, GPIO.OUT)
GPIO.setup(yellow, GPIO.OUT)
GPIO.setup(green, GPIO.OUT)

traffic2.py[edit | edit source]

import RPi.GPIO as GPIO, time
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)

red=11
yellow=13
green=15

GPIO.setup(red, GPIO.OUT)
GPIO.setup(yellow, GPIO.OUT)
GPIO.setup(green, GPIO.OUT)

GPIO.output(yellow, GPIO.HIGH)
time.sleep(2)
GPIO.output(yellow, GPIO.LOW)

traffic3.py[edit | edit source]

import RPi.GPIO as GPIO, time
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)

red=11
yellow=13
green=15

GPIO.setup(red, GPIO.OUT)
GPIO.setup(yellow, GPIO.OUT)
GPIO.setup(green, GPIO.OUT)

while (True):

  GPIO.output(yellow, GPIO.HIGH)
  time.sleep(2)
  GPIO.output(yellow, GPIO.LOW)
  time.sleep(2)

traffic4.py[edit | edit source]

import RPi.GPIO as GPIO, time
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)

red=11
yellow=13
green=15

GPIO.setup(red, GPIO.OUT)
GPIO.setup(yellow, GPIO.OUT)
GPIO.setup(green, GPIO.OUT)

while (True):

  GPIO.output(red, GPIO.HIGH)
  time.sleep(5)

  GPIO.output(yellow, GPIO.HIGH)
  time.sleep(2)

  GPIO.output(red, GPIO.LOW)
  GPIO.output(yellow, GPIO.LOW)
  GPIO.output(green, GPIO.HIGH)
  time.sleep(5)

  GPIO.output(green, GPIO.LOW)
  GPIO.output(yellow, GPIO.HIGH)
  time.sleep(2)

  GPIO.output(yellow, GPIO.LOW)

traffic5.py[edit | edit source]

#!/usr/bin/env python
# GPIO traffic lights by Andrew Oakley for Cotswold Raspberry Jam
# http://www.cotswoldjam.org September 2015 Public Domain

# Start by reading the library about GPIO pins and timing
import RPi.GPIO as GPIO, time, signal, sys

# Set up the GPIO pins
# We're using board numbering as it works for all Pis
# including original Rev.1 boards
GPIO.setmode(GPIO.BOARD)

# Turn off warnings, notably if the pins are already set
GPIO.setwarnings(False)

# Turn off lights if process is killed
def signal_term_handler(signal, frame):
  GPIO.output(red, GPIO.LOW)
  GPIO.output(yellow, GPIO.LOW)
  GPIO.output(green, GPIO.LOW)
  print 'got SIGTERM'
  sys.exit(0)
signal.signal(signal.SIGTERM, signal_term_handler)

# Which colours are on which pins?
# You can use pin 9 for ground
# Attach ground to the shortest leg of the LED
red=11
yellow=13
green=15

# Set up the pins for output
GPIO.setup(red, GPIO.OUT)
GPIO.setup(yellow, GPIO.OUT)
GPIO.setup(green, GPIO.OUT)

# We use TRY and EXCEPT to allow us to
# turn the lights off after stopping the
# program using CTRL-C, or during shutdown
try:

  # Loop round forever, until stopped by CTRL-C
  while (True):

    # Start with Red
    GPIO.output(red, GPIO.HIGH)
    time.sleep(5)

    # Leave red on, and turn yellow on too
    # Red & yellow together is mostly a British thing
    # Countries like France and the USA don't have it
    # they go straight from red to green
    GPIO.output(yellow, GPIO.HIGH)
    time.sleep(2)

    # Turn off red and yellow
    GPIO.output(red, GPIO.LOW)
    GPIO.output(yellow, GPIO.LOW)
    # Turn on green
    GPIO.output(green, GPIO.HIGH)
    time.sleep(5)

    # Turn off green
    GPIO.output(green, GPIO.LOW)
    # Turn on yellow
    GPIO.output(yellow, GPIO.HIGH)
    time.sleep(2)
    GPIO.output(yellow, GPIO.LOW)

# If we have pressed CTRL-C, or if the computer
# is being shut down, then turn all lights off
except (KeyboardInterrupt, SystemExit):
  GPIO.output(red, GPIO.LOW)
  GPIO.output(yellow, GPIO.LOW)
  GPIO.output(green, GPIO.LOW)
  # Report the reason for stopping
  raise

# Now have a think about how you might expand this program
# A T-junction needs 3 sets of lights
# A crossroads needs 4 sets
# Could you wire all sets of lights from one Raspberry Pi?
# What about a left turn filter?
# At night some part-time lights just flash yellow
# If you had two Raspberry Pis, how could they communicate
# so that they could synchronise their lights?