Having written guides describing how to use the Low Voltage Labs traffic lights with the Raspberry Pi for Python (read Python article), Node.js (read Node.js article), Node RED (read Node RED article), C (read C article), Bash scripting (read Bash article), Swift (read Swift article), Go (read Go article), Rust, .NET/C# and even Arduino, it’s definitely time to check out how to access the GPIO pins from the Java programming language.
To make this a standalone guide, there will be some re-use of content from the prior articles in this one.
- 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!
As we used the minimal Stretch Lite OS, there’s no Java runtime or compiler installed by default. Oracle’s Java 8 can be added very easily:
$ sudo apt-get update $ sudo apt-get install oracle-java8-jdk
Confirm that you do indeed wish to add Java to your system then wait while
apt-get fetches and installs it for you.
apt-get is done, check that we have a Java runtime and compiler installed:
$ java -version java version "1.8.0_65" Java(TM) SE Runtime Environment (build 1.8.0_65-b17) Java HotSpot(TM) Client VM (build 25.65-b01, mixed mode) $ javac -version javac 1.8.0_65
We also need to install 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 Java code to demonstrate running the traffic lights in the UK light sequence (red, red + amber, green, amber, red):
To get the example source code from GitHub:
$ git clone https://github.com/simonprickett/javapitrafficlights.git
For convenience, set an environment variable to contain the path to the source code repo:
$ cd javapitrafficlights $ PROJECTDIR=`pwd`
We’ll use that later…
Java Programming with Pi4J
Pi4J is a library for working with GPIO pins on the Raspberry Pi from Java. Using this allows us to get straight down to the business of controlling the lights without having to worry about lower level concerns. In turn, Pi4J depends on the WiringPi C library. WiringPi isn’t installed with the “lite” Raspbian operating system, but it’s easy to fix that:
$ git clone git://git.drogon.net/wiringPi $ cd wiringPi $ ./build
Having completed that step, we can then install Pi4J:
$ curl -s get.pi4j.com | sudo bash
This will produce a lot of output as it installs Pi4J, we’re looking for something like this to indicate that this process completed successfully:
==================================================== Pi4J INSTALLATION COMPLETE ==================================================== The Pi4J JAR files are located at: /opt/pi4j/lib Example Java programs are located at: /opt/pi4j/examples You can compile the examples using this script: sudo /opt/pi4j/examples/build Please see http://www.pi4j.com for more information.
We can now go ahead and compile the Java code using a script included in the GitHub repo:
build.sh we need to
cd back to the folder that we cloned the GitHub repo into:
$ cd $PROJECTDIR $ ./build.sh
build.sh script will create a folder named
classes and place the compiled Java
.class files in there.
Running the code is as simple as invoking a second script included in the GitHub repo:
If the lights are connected to the correct GPIO pins, they should start to flash on and off. If you don’t see anything, make sure that you have the lights connected to the right pins. To exit, press Ctrl + C. This will cause all of the lights to turn off, and the program will terminate.
When I first tried this, I was unable to get the code to run properly, as something in WiringPi was failing when run on the Raspberry Pi 3. The program would quit and output the following:
Unable to determine hardware version. I see: Hardware : BCM2835 - expecting BCM2708 or BCM2709. If this is a genuine Raspberry Pi then please report this to [email protected] If this is not a Raspberry Pi then you are on your own as wiringPi is designed to support the Raspberry Pi ONLY.
After some Googling, I found out that this is due to Pi4J shipping with an older version of WiringPi that dates from before the BCM2835 hardware in newer Raspberry Pi models was available. There’s a GitHub issue against the Pi4J project that describes this problem, and suggests a workaround. That involves configuring Pi4J to disregard the WiringPi version that it comes with and instead use the newer version that we installed earlier.
This workaround is implemented in
run.sh through the addition of:
which is an additional flag when starting the Java runtime.
How it Works
Here’s the code, contained in
src/TrafficLights.java in the GitHub repo:
- Lines 1–5 import the Pi4J library classes that we need to manage GPIO pins.
- Lines 8–11 declare variables that we’ll use to control the GPIO pins and to represent each LED in the traffic lights.
- Lines 14–24 implement a shutdown hook: this is run when the user wants to exit the program by pressing Ctrl-C.
- The code here ensures that all three of the traffic light LEDs are turned off before quitting back to the operating system.
- At line 26, we create a
GpioFactoryinstance, that we’ll use to gain access to the pins that we need.
- Lines 28–30 associated our
greenvariables with pins 13, 12 and 14 respectively as well as setting their initial states to
low(off). Note because Pi4J uses WiringPi underneath, we are using WiringPi’s pin numbering scheme rather than the more common BCM one. This means that GPIO 9 (Red) becomes pin 13 for example. This mapping diagram shows the WiringPi pin numbers and their corresponding BCM mode pin numbers that are used in my other Pi Traffic Light articles for other programming languages.
- Lines 32–50 create an infinite
whileloop that turns the red light on, sleeps for 3 seconds, turns the yellow light on then after 1 second turns off red and yellow, illuminating green. It then cycles through the remainder of the traffic light sequence until returning to the original red light only when it starts again. This will continue indefinitely until the user presses Ctrl-C, invoking the shutdown hook (code at line 14–24).
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 — get in touch via the Contact page. If you enjoyed this article, please share it far and wide!
(Main photo: Nighthawks — Edward Hopper, 1942)