Control Raspberry Pi GPIO with Java

There is some excellent Java examples at http://pi4j.com/ , but when I tried to pull together some prototypes I had some issues with:

  • Installing the Java GPIO library on my PI 3
  • Graphic interface examples for PI
  • Because of super user requirements the apps only worked locally

This write-up will hopefully address these issues.

Getting Started

Java is pre-installed on the Raspian image, so you will only need to install the pi4j java library and this is done by:

curl -s get.pi4j.com | sudo bash

Depending on your Pi setup you might be all good to go. However if you have problems see the section Workarounds at the end of this blog.

Java offers a lot of graphic library options. I used the swing library because it is built in and simple.

Hardware Setup

For the hardware setup I used a Pimoroni Explorer Hat because it offers 5V safe inputs and outputs, however this is not required. I wired a button switch into GPIO_22, and an LED into GPIO_04.

Java_setup

Simple Digital Output Example

A simple digital output example would be:


import com.pi4j.io.gpio.*;

public class gpio_do {

 public static void main(String[] args) throws InterruptedException {

System.out.println("GPIO Digital Output Example ... started.");

// get a handle to the GPIO controller
 final GpioController gpio = GpioFactory.getInstance();

 // creating the pin object
 final GpioPinDigitalOutput pin = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_22);

 // turn pin on and wait 2 seconds
 pin.high();
 System.out.println("Pin High");
 Thread.sleep(2000);

 // turn off and wait 2 seconds
 pin.low();
 System.out.println("Pin Low");
 Thread.sleep(2000);

// turn pin on for 2 second and then off
 System.out.println("Pin High for 2 seconds");
 pin.pulse(2000, true);

 // release the GPIO controller resources
 gpio.shutdown();
 }
}

To compile and run this example, you will need to reference the location of the pi4j class library, and this done by:

javac -classpath .:classes:/opt/pi4j/lib/'*' gpio_do.java
sudo java -classpath .:classes:/opt/pi4j/lib/'*'  gpio_do

It is important to note the supervisor rights are required to control the GPIO pins, so sudo is used when you run the java app.

Graphical Digital Output

java_gpio_out

The swing library has some basic labels and buttons that can be used to view and set a GPIO pin.


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

import com.pi4j.io.gpio.*;
import com.pi4j.io.gpio.event.*;

public class gpio_di_swg {

JFrame jtfMainFrame;
JLabel label1;
static JLabel labelin;
JPanel jplPanel;

public gpio_di_swg() {
jtfMainFrame = new JFrame("GPIO Input Demo");
label1 = new JLabel("Pin Status: ");
label1.setFont(new Font("Serif", Font.PLAIN, 24));
labelin = new JLabel("INPUT STUTUS ???? ");
labelin.setFont(new Font("Serif", Font.BOLD, 36));
jplPanel = new JPanel();

jplPanel.setLayout(new BorderLayout());
jplPanel.add(label1,BorderLayout.PAGE_START);
jplPanel.add(labelin,BorderLayout.LINE_START);

jtfMainFrame.getContentPane().add(jplPanel) ;
jtfMainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//jtfMainFrame.setSize(150, 50);
jtfMainFrame.pack();
jtfMainFrame.setVisible(true);

}

public static void main(String args[]) throws InterruptedException {
System.out.println("GPIO Digital Listen Example ... started.");

// create gpio controller and input button objects
final GpioController gpio = GpioFactory.getInstance();
final GpioPinDigitalInput myButton = gpio.provisionDigitalInputPin(RaspiPin.GPIO_04);
myButton.setShutdownOptions(true);

// create and register gpio pin listener
myButton.addListener(new GpioPinListenerDigital() {
@Override
public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) {
// display pin state on console
System.out.println(" --> GPIO PIN STATE CHANGE: " + event.getPin() + " = " + event.getState());
if (event.getState().toString() == "HIGH") {
labelin.setText("INPUT HIGH");
labelin.setForeground(Color.RED);
} else {
labelin.setText("INPUT LOW");
labelin.setForeground(Color.BLACK);
}
}

});

System.out.println(" ... complete the GPIO #04 circuit and see the listener feedback here in the console.");

// Set the look and feel to Java Swing Look
try {
UIManager.setLookAndFeel(UIManager
.getCrossPlatformLookAndFeelClassName());
} catch (Exception e) {
}
gpio_di_swg application = new gpio_di_swg();
}
}

Digital Inputs

java_gpio_input

 

The PI4J library has an event handler to catch digital state changes. An graphical example would be:


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

import com.pi4j.io.gpio.*;
import com.pi4j.io.gpio.event.*;

public class gpio_di_swg {

JFrame jtfMainFrame;
JLabel label1;
static JLabel labelin;
JPanel jplPanel;

public gpio_di_swg() {
jtfMainFrame = new JFrame("GPIO Input Demo");
label1 = new JLabel("Pin Status: ");
label1.setFont(new Font("Serif", Font.PLAIN, 24));
labelin = new JLabel("INPUT STUTUS ???? ");
labelin.setFont(new Font("Serif", Font.BOLD, 36));
jplPanel = new JPanel();

jplPanel.setLayout(new BorderLayout());
jplPanel.add(label1,BorderLayout.PAGE_START);
jplPanel.add(labelin,BorderLayout.LINE_START);

jtfMainFrame.getContentPane().add(jplPanel) ;
jtfMainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//jtfMainFrame.setSize(150, 50);
jtfMainFrame.pack();
jtfMainFrame.setVisible(true);

}

public static void main(String args[]) throws InterruptedException {
System.out.println("GPIO Digital Listen Example ... started.");

// create gpio controller and input button objects
final GpioController gpio = GpioFactory.getInstance();
final GpioPinDigitalInput myButton = gpio.provisionDigitalInputPin(RaspiPin.GPIO_04);
myButton.setShutdownOptions(true);

// create and register gpio pin listener
myButton.addListener(new GpioPinListenerDigital() {
@Override
public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) {
// display pin state on console
System.out.println(" --> GPIO PIN STATE CHANGE: " + event.getPin() + " = " + event.getState());
if (event.getState().toString() == "HIGH") {
labelin.setText("INPUT HIGH");
labelin.setForeground(Color.RED);
} else {
labelin.setText("INPUT LOW");
labelin.setForeground(Color.BLACK);
}
}

});

System.out.println(" ... complete the GPIO #04 circuit and see the listener feedback here in the console.");

// Set the look and feel to Java Swing Look
try {
UIManager.setLookAndFeel(UIManager
.getCrossPlatformLookAndFeelClassName());
} catch (Exception e) {
}
gpio_di_swg application = new gpio_di_swg();
}
}

 

Working Remotely

If you are working remotely from your Raspberry Pi with SSH, you will have a problem running the Java graphical applications. This problem is due to the fact that by default X windows applications requiring super user rights are not allowed to run remote over SSH.

By adding the sudo option XAUTHORITY=$HOME/.Xauthority  java X application can be run remotely. So an example would be:

sudo XAUTHORITY=$HOME/.Xauthority java -classpath .:classes:/opt/pi4j/lib/'*' myapp

Final Thoughts

The Pi4J library has a lot of examples to cover a good variety of Raspberry Pi I/O examples and TOPs, such as MCP3004 chips, LCD and PiFace Tops.

Workarounds

When I ran one of the examples I saw the message:

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 projects@drogon.net. If this is not a Raspberry Pi then you
are on your own as wiringPi is designed to support the
Raspberry Pi ONLY.
user@system ~> gpio -v
gpio version: 2.38

There were a lot of comments on how to fix the problem. I found that rolling back the kernel worked for me, and this is done by:

sudo rpi-update 52241088c1da59a359110d39c1875cda56496764

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s