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.
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
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
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
This is wow, I will be giving it a trial soon
LikeLike
This project is ideal for me. I have been learning Java’s SWING and AWT and have just got my RPi 4B running with all the libraries needed.
I am having a little trouble understanding the wiring and parts layout. Is there a basic schematic?
LikeLike
Hi, sorry that I didn’t get back to you earlier. For the Pi button input and LED output, I used the standard setup. For example if you Google “raspberry pi button input” you’ll see lots of examples. Please note not all the Google examples are 100% recommended. For example you should always use a resistor on your button input and LED output, otherwise you’ll potentially damage your hardware. Good luck on your projects. Pete
LikeLike