RPi & Pi4J: Tutorial 2: GPIO Output

In the first installment of this series, we saw how we could quickly set up a Java development environment on the RPi, and wrote a simple program to demonstrate how easy it is to configure GPIO using Pi4J.

Let us now dive a little deeper into Pi4J, and understand how we can use the GPIO pins as output pins.

In order to demonstrate the Pi4J APIs that control pin output, we will use the circuit in the figure below.


The circuit is simple – it connects three GPIO pins (GPIO_01, GPIO_04 and GPIO_06) to an LED each (LED1 through LED3) through a current limiting resistor (R1 through R3). In our next article, we will discuss the function of the current limiting resistor, and figure out how we can calculate a reasonable value for it.

As you probably know by now, LEDs are diodes that emit light when a current flows through them (hence the term “Light Emitting Diode”). We drive a current through them by turning the corresponding GPIO pin high.

The Code

Source code for all the tutorials on this site is available at BitBucket.

We initialize each of the GPIO pins by making a call such as the one below:

final GpioPinDigitalOutput led1 = gpio.provisionDigitalOutputPin (

Notice how the last argument for the call sets the pin state to LOW. This ensures that the pins are set to a known state when they are initialized.

Blocking vs. Non-Blocking Calls

Some of the methods in Pi4J have the ability to be either blocking or non-blocking. What is the difference?

When a method is specified as a “blocking” method, execution of that thread is halted until the method returns. If the method is specified as “non-blocking” (which is the default), the thread continues past that method call even if that method has not returned.

Another way to think about this is that “blocking” methods are synchronous while “non-blocking” methods are asynchronous.


The pulse method does what it says – it sends out a pulse on the GPIO pin once. The simplest form of the pulse method takes one argument – a time in milliseconds – for which the pulse is active. So, specifying pulse(1000); causes the pin to be pulsed for 1 second (1000 ms = 1 s).


A slightly more complicated form of this method is one which allows you to specify whether the method should be blocking or non-blocking. This is specified by providing a second argument to the method – a boolean value where true implies a blocking method whereas a false implies a non-blocking method.

led2.pulse(1000, true);   // Blocking call
led3.pulse(1000, false);  // Non-blocking call


The blink method sends out a periodic stream of pulses to a GPIO pin, raising it high and then low again.

led1.blink(500, 10000); // blinks LED1 once a second 
                        // (500ms on, 500ms off) for a 
                        // total of 10 seconds.

Sample Program

A sample program to demonstrate the API methods mentioned in this tutorial is given below. You can download the source code from BitBucket.

 * The MIT License (MIT)
 * Copyright (c) 2014 Charathram Ranganathan
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.

package org.calpilot;

/* Required imports for Pi4J */
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.RaspiPin;

 * Created by calpilot on 5/14/2014.
public class Tutorial2 {
	public static void main(String[] args) {

		boolean BLOCKING = true;
		boolean NONBLOCKING = false;

		System.out.println("===== Starting Tutorial 2 =====");

		final GpioController gpio = GpioFactory.getInstance();

		 * Initialize all the pins as outputs, and pull them to a LOW on
		 * startup.
		final GpioPinDigitalOutput led1 = gpio.provisionDigitalOutputPin(

		final GpioPinDigitalOutput led2 = gpio.provisionDigitalOutputPin(

		final GpioPinDigitalOutput led3 = gpio.provisionDigitalOutputPin(

		 * Add a shutdown hook so that the application can trap a Ctrl-C and
		 * handle it gracefully by ensuring that all the LEDs are turned off
		 * prior to exiting.
		Runtime.getRuntime().addShutdownHook(new Thread() {
			public void run() {
				System.out.println("\n\nPROGRAM WAS INTERRUPTED. SHUTTING " +

		System.out.println("Pins initialized. All LEDs should be off.");

		 * Starting the main loop of our program. We put it in a try-catch
		 * since the various sleep's throw an exception and we need to catch
		  * those exceptions.
		try {
			System.out.println("Blocking Call: Each LED will be on for 1 sec" +
					" one after another.");

			 * Blocking call: Execution proceeds to next line only after current
			 * line is finished. LEDs will blink one after the other.
			led1.pulse(1000, BLOCKING);
			led2.pulse(1000, BLOCKING);
			led3.pulse(1000, BLOCKING);

			System.out.println("Non-Blocking Call: Each LED will be on for 1 " +
					"sec, but simultaneously.");

			 * Non-blocking call: Each LED should turn on and off
			 * simultaneously. Execution does not wait for a statement to finish
			 * before moving to next statement.
			led1.pulse(1000, NONBLOCKING);
			led2.pulse(1000, NONBLOCKING);
			led3.pulse(1000, NONBLOCKING);

			System.out.println("Blinking LED2 for 10 seconds, " +
					"every second.");

			 * Blink LED2 for a total of 10 seconds, with each cycle being 1 sec
			 * long. LED2 will be on for 500 ms and off for 500 ms.
			led2.blink(500, 10000);

			System.out.println("Blinking LED3 forever, every 2 seconds. Press" +
					" Ctrl-C to abort the program.");

			 * Another way to blink a GPIO pin is to set it high and low
			 * alternately, with a sleep.
			for (; ; ) {
				System.out.print(" ");
		} catch (InterruptedException ie) {
			System.out.println("Execution Interrupted.");

RPi Pins & Pin Numbering

In the first installment of this series we wrote a simple Java program that used the Pi4J library to set one of the RPi’s GPIO ports low and reads its status. Before we go any further with our tutorials, let us take a quick look at what GPIO is, and what it offers.

Pi4J provides a class RaspiPin to give you an abstraction of the GPIO pins on the board. We used the following snippet of code to set the pin low:

GpioPinDigitalInput myButton = gpio.provisionDigitalInputPin(RaspiPin.GPIO_00, 

Notice how we used RaspiPin.GPIO_00 to refer to the pin that we wanted to set as an input pin.

What is GPIO?

GPIO stands for “General Purpose Input Output” and, as the name suggests, it refers to a set of pins that provide generic input and output capabilities for the RPi. While most of the pins are truly “general purpose” pins, a few pins can be used for specific purposes (such as I2C communication, Serial communication, etc.) Obviously, when those pins are being used for their specific functions, they cannot be used as general purpose pins.

Pin Numbering

Pin numbering has been the subject of much debate and angst among the Raspberry Pi community for a while now. Since I’m not exactly a fan of angst and/or controversy, let us stay out of the debate and just state that we will use the WiringPi numbering scheme from here on out.

Pi4J is based on a project called WiringPi, which is a set of native libraries that provide access to the RPi’s GPIO ports. The pin numbers and their mapping to the actual pins on the RPi header are given in the picture below.

RPi Pin Out

The numbers in bold will be used as our GPIO pin numbers. In Pi4J, the pin numbers are prefixed by GPIO_ and are zero-padded. So, the pins are referred to as GPIO_00, GPIO_01, and so on through GPIO_20.

In all circuit diagrams going forward, I will be using the image below to represent the RPi header and the pin out. The pin numbers on the outside of the diagram are the physical pin numbers on the header while the textual descriptions within the rectangle are those of the corresponding Pi4J equivalents.

RPi Header Circuit Schematic

Source Code is Available

All the source code for my Raspberry Pi / Java / Pi4J tutorials are available from my BitBucket Repository.

If you want to download a zip file of the most current release, click here. If you want to clone the repository, please use:

$ git clone https://bitbucket.org/calpilot/rpi-tutorials.git

All the code is licensed under the MIT License.

Raspberry Pi and Pi4J: Tutorial 1

This is part 1 of a multi-part series on programming the Raspberry Pi (abbreviated to “RPi”) with Java using the Pi4J programming library.


One of the things I love about the RPi is the fact that it can be a full-fledged Linux-based computer with the ability to function as a development system as well. If you add a JDK to the mix, you can actually use the RPi as a Java development environment.

What I wanted to achieve with my RPi was the following:

  • Set up Java SE.
  • Install Maven
  • Use the Pi4J libraries to interact with “low-level” features such as GPIO, I2C, etc.

Let’s look into how I set up each of these.


Oracle has been working very closely with the RPi community to make builds of Java SE available on the RPi. The end result is that the JDK is pre-installed with the stock Raspbian distribution. Updating to newer versions of Java SE is as simple as using apt-get on the RPi to update to the newer version.

$ sudo apt-get update
$ sudo apt-get install oracle-java8-jdk

Make Java 8 the default

Run the update-alternatives command to bring up a list of installed Java versions, and to select the default.

$ sudo update-alternatives --config java
There are 3 choices for the alternative java (providing /usr/bin/java).

  Selection    Path                                                 Priority   Status
  0            /usr/lib/jvm/java-6-openjdk-armhf/jre/bin/java        1057      auto mode
  1            /usr/lib/jvm/java-6-openjdk-armhf/jre/bin/java        1057      manual mode
  2            /usr/lib/jvm/jdk-7-oracle-armhf/jre/bin/java          317       manual mode
* 3            /usr/lib/jvm/jdk-8-oracle-arm-vfp-hflt/jre/bin/java   318       manual mode

Press enter to keep the current choice[*], or type selection number:

Type “3” and hit enter to make Java 8 the default.


For a long time, I resisted the move to Maven. I was uncomfortable with setting up the pom.xml file. I could never understand how things worked, etc.

To make a long story short, I recently solicited the help of a friend and actually set up a simple development environment using Maven. He helped me create my first pom.xml. Once that was done, I was astounded by the simplicity of the tool and its abilities. The dependency management, by itself, blew my mind away. Let’s just say I will not be using Ant any more.

Installing Maven on the RPi is as simple as running apt-get again.

$ sudo apt-get install maven


The Pi4J library is a Java wrapper around a native library for the RPi. It provides a set of Java classes to abstract access to the RPi’s ports, specifically the GPIO, SPI and I2C ports. The easiest way to use Pi4J in an application is to include the repository into the project’s pom.xml file.



Here are the steps we will take to create our first Java / Pi4J application on the RPi.

  • Set up the project layout.
  • Create the pom.xml.
  • Create the Java source file(s).
  • Build and run the application.

Let us go through each of these steps in detail.

Set up the project layout

All Maven projects follow a standard directory layout as summarized below. More details can be obtained from the Maven documentation.

Remember to replace PROJECT_HOME with the name of your project.

+-- src
      +-- main
      |      |
      |      +-- java
      |      |
      |      +-- resources
      +-- test
             +-- java
             +-- resources

So, set up this standard layout in your project’s home.

$ mkdir ~/PROJECT_HOME
$ mkdir -p ~/PROJECT_HOME/src/main/java
$ mkdir -p ~/PROJECT_HOME/src/resources
$ mkdir -p ~/PROJECT_HOME/test/java
$ mkdir -p ~/PROJECT_HOME/test/resources

Obviously, you will create the appropriate “Java-specific” directory structure withing the src/main/java directory. For example, if your code were to be a part of the org.calpilot package, you would create an org/calpilot directory under src/main/java.

Create the POM

I, personally, like to use the Maven assembly plugin in my build to build what is called a jar-with-dependencies, i.e. a jar file with all the dependencies baked into it. This way, you just copy the jar file where you want to and execute the main class with a java -jar JAR_FILE command.

Notice how we mark the Pi4J library as a dependency. We exclude the pi4j-native POM because it includes the .so files for the native library and that causes issues with the build targets.

Also, note how we specify the class name of the “main” class in the pom.xml.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">


    <name>Testing Pi4J and Maven</name>




Create the Java Source File(s)

For our first example, we will

  • Initialize the Pi4J library.
  • Set one of the GPIO pins to a “low” state using its internal pull-down resistor.
  • Read, and print, the status of that pin.

It’s very simple, but all we want to do at this stage is to make sure that we can build our project and that we can load the Pi4J library in our code.

Here’s the Java source file.

package org.calpilot;

/* Pi4J imports */
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalInput;
import com.pi4j.io.gpio.PinPullResistance;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.RaspiPin;

public class Pi4jTest {

    public static void main(String[] args) {
        System.out.println("Hello, Raspberry Pi!");

        /* Initialize pi4j */
        final GpioController gpio = GpioFactory.getInstance();
        /* Initialize GPIO 0 as an input pin called "MyButton" and set
           it low using the pull-down resistor.
        GpioPinDigitalInput myButton =

        /* Read the state (high or low) of the pin. Remember, it should be "low" */
        PinState pinState = myButton.getState();
        System.out.println("GPIO 0 is set to " + pinState.getName());

        /* Close all open connections. */

Build and Run the Application

$ mvn compile package

This compiles the project and creates the jar with dependencies in a PROJECT_HOME/target directory. The jar file is named Pi4jTest-1.0-SNAPSHOT-jar-with-dependencies.jar.

To run the application, just type

$ sudo java -jar Pi4jTest-1.0-SNAPSHOT-jar-with-dependencies.jar

at the command prompt. Remember that you need to run the code as root (or a superuser) since access to GPIO ports is a superuser privilege.

You should see the following output:

Hello, Raspberry Pi!
GPIO 0 is set to LOW


This brings us to the end of this first tutorial. I hope you have as much fun as I did in setting up my first RPi/Java/Pi4J application. In subsequent tutorials, we will start looking at interfacing real hardware to the RPi, and controlling that hardware. Keep your soldering irons handy!

Six aviation rules for the real world!

As everyone who knows me knows, I’m a stark, raving, aviation and flying addict. Fortunately, I have a “real world” job that enables me to indulge in my lunacy. So, while thinking about what to post next on this blog, I figured a post that connects my “hobby” and my real job is warranted.

So, read on, dear reader…

Always have a backup plan

One of the first things that pilots are taught is to always assume that every takeoff may result in an engine failure and, therefore, an emergency landing. One of the requirements that the FAA has for flights “away from the home airport” is for the pilot to plan for an alternative airport and to be prepared to divert there, if needed.

The takeaway is simple: Always have an alternative in mind and be ready to use that alternative, if the situation demands it.

You are (or should be) always learning

There is a saying in the aviation community that your pilot’s license is a “license to learn.” In fact, many pilot examiners will actually say this to a pilot who has just earned his/her wings. This is very true. Flying is about continually learning. The reality is that you embark upon the path of mastery of your “craft” only after you’ve actually earned your wings. You learn new, and more efficient ways of doing things; you learn how your fellow pilots perform certain maneuvers; you probably decide to do your instrument rating to learn how to fly through clouds; every two years, you go through a learning exercise to pass what’s called a “BFR” – a Biennial Flight Review.

In real life, too, it is imperative for a person to be continuously learning. New technologies come up, the world creates new ways of solving old problems; and even new urban slang is developed every day. A savvy person will ensure that he or she stays abreast of what is new and exciting in his or her chosen career path.

Know your limitations

A common phrase you will hear among pilots is “personal minimums”. While this can refer to the state of a pilot’s bank balance, it really refers to the fact that each pilot needs to understand his or her limitations and establish a set of criteria that they will meet before decided to take off. Very often, these “personal minimums” are more conservative than what the FAA prescribes and, more often than not, flying only after meeting these personal minimums is what has kept a pilot alive.

In real life, too, it is important, nay imperative, for a person to understand his or her limitations. While it is good to challenge oneself in order to grow, it is also important not to “bite off more than you can chew”. If a task is too challenging, remember that you can always ask for help, or assemble a team that has complimentary skills to yours so that you can, together, obtain a successful outcome.

It’s OK to ask for help. Or, “the man” isn’t evil

As a student pilot, you’re taught two simple words that ensure that every controller, in every air traffic control facility, falls over themselves to help you stay out of trouble – “Student Pilot”. All you do is to say “Student Pilot” and, miraculously, irate controllers start speaking to you like they would have to their 4 month toddler. Of course, I exaggerate, but you get the point, I hope!

Once you earn your pilot’s license, you no longer have the “Student Pilot” safety net to save you. You are now licensed, and are expected to know the rules and obey them. The sweet controller who was your ally as a student pilot has now become “the man” – one who is out to ensure that you follow the rules, or there will be hell to pay. Or so you’re told. I have heard of pilots who are so terrified of even talking to ATC that they fly without ATC (this is legal, BTW), or go to extreme lengths to avoid any ATC conversation.

As a pilot, I have found that the contrary is true… If you’re in trouble, there’s no one who will do their best to save your empennage (that’s the rear end of an airplane) than the controller with whom you’re in conversation. There may be consequences for you if you ended up in a sticky situation because you broke a rule, but at least you will live to tell the tale.

This is true in the real world too. When you have a problem, you probably have a better chance of solving it if you confide in others – maybe your peers, maybe your team or maybe your superior. If the problem was the result of something that you did wrong, you may have some consequences, but at least you would have solved the problem and lived to tell the tale.

Brevity is, often, a good thing

As a student pilot, your instructors will drill two things into your mind about radio communication. Firstly, radio time is expensive, and if you hog the airwaves, other pilots cannot even get a word in. And, as a corollary, think of what you are going to say before keying the microphone.

In real life, just as in flying, these two rules are very important. The first, and probably most important, rule of business communication is to know what you want to say, to whom you’re going to say it, and the context in which the recipient will read your message. A close second is to be clear and concise in your communications.

Checklists are mandatory

Aviation is full of checklists and mnemonics – strange sounding ones like “GOOSE A CAT” or “DEC A RAT” or “GUMPS”. On every practical test one of the areas of assessment is “checklist usage.” The idea is simple – no matter how well you know your aircraft, or how well you know to fly, it is always possible to forget something. When you do forget, the cost could be significant. So, it’s drilled into you – use a checklist, or else…

In real life, many of us are loathe to use checklists. If we’re new to business, we’re afraid that using a checklist will be judged as a sign of weakness. If we’re experienced, we worry that using a checklist may make our juniors feel that we’re either turning senile or that we are incompetent. There have been many occasions where a whole website has gone down because the release engineer (or DevOps for the “cool” people) forgot to push a file, or change a configuration setting. A simple checklist could have avoided the drama and, more importantly, the economic impact.

French (not Death) Valley Flyout: March 31, 2013

Talk about the need to be flexible when flying – well, more than when flying a commercial airline, at least!

David Werntz, one of the instructors at the Caltech Aero Club, had tried to arrange a flyout to the Furnace Creek Airport (L06) in Death Valley, CA. Over the last few days, we had noticed that the weather in and around the SoCal area was steadily deteriorating, and last night we realized from the weather forecasts that not only was the cloud cover over SoCal going to make it difficult for us but that the winds in the desert were going to be picking up pretty bad. For example, current (at the time of this post) winds at Edwards Air Force Base are from the West-Southwest (240 degrees) 19 knots with gusts of up to 25 knots.

KEDW 312258Z 24019G25KT 80SM FEW040 SCT080 BKN250 20/08 A2999 RMK AO2A PK WND 22027/45 SLP145 T01960075

To make a long story short, most of us were uncomfortable with flying in such high winds and, potentially, the associated turbulence. So, this morning, we met up at El Monte to figure out what to do. Now, as any one who knows pilots will admit, when the best laid plans of pilots are defeated by weather pilots (akin to toddlers) are bound to sulk, mope and, in occasional cases, throw a tantrum – the primary objective being a flight somewhere 🙂

Thankfully, there were no tantrums this morning, but we all figured we should fly somewhere closer than Furnace Creek so that we could return to El Monte if the weather started taking a turn for the worse. After a little bit of discussion, consensus was arrived upon in favor of flying to French Valley Airport (F70) near Murietta. The airport restaurant was open and that’s all that we needed.

So, off we went – a crew of 16 club members in 5 aircraft – 3 C172s, a C152 and a Piper Archer.

Flying to French Valley was relatively uneventful. We headed east from El Monte, found the I-15 just southeast of Chino and followed it all the way to Murietta close to where it merges with the I-215. SoCal Approach informed us that the Lake Elsinore parachute drop zone was active and so we stayed east of the 15 freeway. On seeing so many aircraft heading from El Monte to French Valley the controller at March AFB approach (rather wistfully, in my opinion) asked us whether we were part of a flying club. I replied with the affirmative and that was that. Weather at French Valley was excellent – sunny skies, a little windy, but just amazing.

Here’s a picture of our flight path to French Valley.


Brunch at French Valley was excellent. I particularly loved my veggie burger, which seemed custom made as opposed to the Boca Burger junk that many restaurants seem to peddle.

Flying back from French Valley was not as uneventful as I’d hoped. The clouds were moving in from the west and the cloud base was at 5,000 feet on departure from French Valley. I wanted to go to 4,500 feet, but decided to only climb to 4,200 feet to avoid getting too close to the clouds. As we cleared Lake Matthews and started to have a better look at the LA Basin, we noticed the cloud base had dropped even further, with El Monte reporting cloud bases at 3,400 feet. We dropped to 2,500 feet near Chino airport, after letting SoCal Approach know. I followed the I-10 all the way back to Chino, was cleared left base for runway 19 and landed. Not my best landing, but as they say, “any landing that you can walk away from is a good landing :-)”

Here’s a picture of our flight path from French Valley.


All in all, it was an excellent flyout. A lot of fun and camaraderie with a bunch of great people.

I’m still sulking about not making it to Death Valley, but as all toddlers (and pilots) do, I’ll get over it 🙂

Happy Easter!

Night Flight to Chino and Ontario 3/30/2013

I had to get checked out in the Caltech Aero Club‘s C172 (N54678) and so, my instructor, Russell Thomas and I decided to do some night flying as part of the checkout. Since I had told Russ that I’ve never landed at Ontario, he figured why not do some pattern work at Ontario (KONT). What a trip!

We took off from El Monte (KEMT), headed east towards Chino (KCNO) and did one full stop landing at Chino. After a taxi back we took off from Chino, got an early frequency change to Ontario Tower and asked for clearance to land with the option.

Ontario Tower cleared us immediately to land on 26L (their shorter runway). Of course, as we headed in, there was an A320 coming in for landing on 26R and we were asked to do a left 360 for spacing in order to avoid wake turbulence. Once the A320 touched down, we were cleared to enter base and a short final later we were on 26L. Full stop. Taxi back for takeoff. We then asked for a couple of touch-and-go’s, but on the second approach, Russ asked me if I wanted to do the VOR-A approach to El Monte. How could I, in good conscience, say no 🙂

For quick reference, here is the VOR-A approach into KEMT. Russ worked the radios, and instructed while I flew the approach. A lot of fun.

Here’s a GPS track of my flight path (click on the image to go to the actual Google Map). Note the left 360 on the leg from Chino to Ontario. By the way, I use this really cool app called MotionX GPS for this flight track (more on apps in another post).


%d bloggers like this: