Controlling Raspberry Pi GPIO Pins from Bash Scripts: Traffic Lights

Simon Prickett
Oct 13, 2018 · 7 min read
Image for post
Image for post

I’ve previously produced guides describing how to use the Low Voltage Labs traffic lights with Raspberry Pi single board computers for Python (read Python article), Node.js (read Node.js article), Node RED (read Node RED article), Java (read Java article), C (read C article), Swift (read Swift article), Go (read Go article) and also for Arduino (read Arduino article). This time, I’ll look at using a Bash script to do the same thing without employing a traditional programming language.

To make this a standalone guide, there will be some re-use of content from the prior articles here.

Shopping List

To try this out, you will need the following (links here mostly go to Adafruit, UK customers may want to consider Pimoroni as a UK based alternative, Amazon has most if not all of this stuff too):

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.

Image for post
Image for post

Before powering up the Pi, attach the traffic lights so that the pins connect to the GPIO pins highlighted in red:

Image for post
Image for post
Raspberry Pi GPIO Pinout by pinout.xyz

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).

Image for post
Image for post
Image for post
Image for post

Don’t turn the Pi on yet, you’ll need to prepare an operating system image for it first…

Operating System Setup

Install the Raspbian Stretch Lite OS which can be downloaded from the official Raspberry Pi site. You can also find an excellent installation guide there should you need help. I found the free Etcher tool from Resin.io helpful when transferring the operating system image to the micro SD card.

Once you’ve got the operating system installed make sure you can login, and have a working wired or wifi internet connection configured.

Now you can go ahead and start turning lights on and off!

Installing Dependencies

As Bash comes with the operating system, the only thing left to install is git so we can download the sample code from GitHub:

$ sudo apt-get install git
$ git --version
git version 2.11.0

Downloading the Sample Code

I’ve written some sample C code to demonstrate running the traffic lights in the UK light sequence (red, red + amber, green, amber, red):

Image for post
Image for post

To get the source code for this example from GitHub:

$ git clone https://github.com/simonprickett/bash-traffic-lights-pi.git

Accessing the GPIO Pins from a Bash Script

Without adding further dependencies, Bash scripts can access and control the Pi’s GPIO pins using sysfs. This presents as a set of filesystem paths which can be manipulated to configure individual pins as inputs or outputs and to set and read their values. On the Pi, these paths look like:

/sys/class/gpio/gpio<pin_number>

and each has a /direction and /value, for example for GPIO 11:

/sys/class/gpio/gpio11/direction
/sys/class/gpio/gpio11/value

As we will see later in this article, the direction and value can be set by writing values to these “paths” as the root user on the Pi.

The pin numbering scheme used by sysfs is the Broadcom (BCM) one, so the pin numbers that you need to use will match those in the diagram earlier in this article.

Running the Demo

Starting the demo is as simple as executing the script as root:

$ cd bash-traffic-lights-pi
$ sudo ./trafficlights.sh

To stop the demo, press Ctrl-C at any time.

Note the use of sudo when starting the script. This allows it to run as the root user with access to write the file paths needed to control the GPIO pins using sysfs.

How it Works

Here’s the code, contained in trafficlights.sh in the GitHub repo:

Lines 1–13 set up some variables so that things we need have more meaningful names. The red LED is on GPIO 9, yellow on 10 and green on 11. We also abstract out the common base path /sys/class/gpio as we will be using that a lot. ON and OFF are used as they are more meaningful than the actual 1 and 0 values that the script will use.

Exporting Pins

In order to use a GPIO pin through sysfs, we first have to “export” each one to make the appropriate paths available. The function exportPin at lines 16–21 does this. For example to export pin 9 it will use the following command (once all variables have been resolved to their values):

echo "9" > /sys/class/gpio/export

This creates paths in /sys/class/gpio for pin 9 but will error if those paths exist already. To overcome this the exportPin function checks first and will only export a pin if the path to it does not yet exist.

Setting Pin Direction

Pins can be used for input or output. In this case we need to use them as outputs to control each of the three LEDs on the traffic lights. The function setOutput (lines 24–27) does this by sending “out” to the “direction” path for the pin. Example for GPIO 9:

echo "out" > /sys/class/gpio/gpio9/direction

Turning Lights On and Off

Function setLightState at lines 30–33 handles turning one of the lights on and off by setting its GPIO pin to high (1 — on) or low (0 — off). It does this by writing either 1 or 0 to the “value” path for the pin. Example for GPIO 9:

echo "1" > /sys/class/gpio/gpio9/value

Turning Everything Off on Exit

The code’s going to run in an infinite loop exiting when Ctrl-C is pressed and the SIGINT signal is sent. In order to tidy up and turn all three of the lights off when this happens we need to trap and handle the SIGINT signal. This is achieved with lines 44–50 which define a function shutdown and register it as the handler for SIGINT.

shutdown calls another utility function that in turn calls setLightState for each of the three lights to switch them off. It then uses exit to cleanly stop the script, returning control to the shell.

The Main Code Loop

The main code entry point starts at line 52 and uses the functions we defined earlier to export each of the three required pins and to set them as outputs. It then calls the utility function allLightsOff which ensures that all three of the traffic light LEDs are turned off so that we are in a known state to begin from.

Lines 66–89 are an infinite loop in which we use setLightState to turn individual traffic light LEDs on and off in the correct order for a UK traffic light (red, red + yellow, green, yellow, red, repeat…). The built in sleep command allows the code to stay in each state for a few seconds before moving to the next.

The source code for this project is freely available on GitHub. I’d love to hear what you’re up to with the Raspberry Pi, Bash scripting or a combination of the two. I’ll try and write more as time allows.

Also, Read

Get Best Software Deals Directly In Your Inbox

Image for post
Image for post

Coinmonks

Coinmonks is a non-profit Crypto educational publication.

Sign up for Coinmonks

By Coinmonks

A newsletter that brings you week's best crypto and blockchain stories and trending news directly in your inbox, by CoinCodeCap.com Take a look

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Simon Prickett

Written by

Software Professional, builder of things with Arduino and Raspberry Pi. San Diego CA.

Coinmonks

Coinmonks

Coinmonks is a non-profit Crypto educational publication. Follow us on Twitter @coinmonks Our other project — https://coincodecap.com

Simon Prickett

Written by

Software Professional, builder of things with Arduino and Raspberry Pi. San Diego CA.

Coinmonks

Coinmonks

Coinmonks is a non-profit Crypto educational publication. Follow us on Twitter @coinmonks Our other project — https://coincodecap.com

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store