7

Getting started with Java and Pi4J (V.2) on the Raspberry Pi

 1 year ago
source link: https://devm.io/iot/java-raspberryp-pi4j
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

In the previous article “The state of Java on the Raspberry Pi” of this series, we learned already Java, JavaFX and Visual Studio Code are all perfect matches with the Raspberry Pi. And by adding Pi4J in the mix, we can build Java applications which can talk to electronic components connected to the GPIO pins of the Raspberry Pi.

In this article were going to build our very first project to control a LED and handle the state changes of a physical button.

Pi4J version 2

In the beginning of 2021 the Pi4J project has taken a few big steps into the future. The final version of the first generation were released. V1.3 (aimed at Java 8) brought in support for the newer Raspberry Pi-boards (4, 400 and CM4), while V1.4 moved the code to Java 11.

But in this series we are going to use the version 2, which is – at this moment – only available in a snapshot-version. The team working on this project has grown and work is ongoing to speed up the development and delivery of new (test) versions. As one of the first steps, the website pi4j.com was totally reworked. By adding a full new „Getting Started“ section to the site [1], it should become much easier to learn how to build Java projects for the Raspberry Pi. The minimal example is further explained in this article, and the other ones are currently being worked on, with the support of students of the University of Applied Sciences and Arts Northwestern Switzerland (FHNW [2]).

The project

In the “pi4j-example-minimal” GitHub project[3], you can find a project which contains the example code to control a digital input and output with Pi4J. The application will toggle an LED on/off and each time you press the button, the toggling speed increases. When you have pushed the button 5 times, the application stops.

Wiring

This minimal example application uses this wiring scheme with a button and a LED:

Bild1.png

In this image a so-called “T-Cobbler” with a breadboard is used. This makes it very easy to change the wiring and setup an experiment as you get a clear view of the GPIO pin numbers. The same setup can of course be made with direct connections to the Raspberry Pi as you can see in this picture:

Bild2.jpg

Building the application

The main build tool used by the Pi4J project is Maven. But this example project also includes a build configuration in the GitHub sources for Gradle.

Maven

This project can be built with Apache Maven 3.6 (or later) and Java 11 OpenJDK (or later). These prerequisites must be installed prior to building this project as described on the previous pages. The following command can be used to download all project dependencies and compile the Java module. You can build this project directly on a Raspberry Pi with Java 11+.

mvn package

Gradle

You can also use the Gradle Build Tool from these same sources. Use version 6.6 (or later) and Java 11 OpenJDK (or later). The Gradle wrapper is used as described on docs.gradle.org. The Gradle configuration file build.gradle-file is included in the sources.

On Linux:

./gradlew build

On Windows:

gradlew.bat build

Defining the dependencies

For the Maven approach, a pom.xml file defines all the dependencies, and the build process.

At this moment Pi4J V.2 is not yet released, so you’ll need to add the snapshot repository.


<repositories>

    <repository>

        <id>oss-snapshots-repo</id>

        <name>Sonatype OSS Maven Repository</name>

        <url>https://oss.sonatype.org/content/groups/public</url>

        <releases>

            <enabled>false</enabled>

        </releases>

        <snapshots>

            <enabled>true</enabled>

        </snapshots>

    </repository>

</repositories>

In this project we will be using slf4 for logging, pi4j-core and the pi4j-plugins for the Raspberry Pi and PiGPIO. To make the versions easy to update, we add those numbers as properties.

<properties>

    <!-- DEPENDENCIES VERSIONS -->

    <slf4j.version>2.0.0-alpha0</slf4j.version>

    <pi4j.version>2.0-SNAPSHOT</pi4j.version>

</properties>

These are the dependencies we need:

<dependencies>

    <dependency>

        <groupId>org.slf4j</groupId>

        <artifactId>slf4j-api</artifactId>

        <version>${slf4j.version}</version>

    </dependency>

    <dependency>

        <groupId>org.slf4j</groupId>

        <artifactId>slf4j-simple</artifactId>

        <version>${slf4j.version}</version>

    </dependency>

    <!-- include Pi4J Core -->

    <dependency>

        <groupId>com.pi4j</groupId>

        <artifactId>pi4j-core</artifactId>

        <version>${pi4j.version}</version>

    </dependency>

    <!-- include Pi4J Plugins (Platforms and I/O Providers) -->

    <dependency>

        <groupId>com.pi4j</groupId>

        <artifactId>pi4j-plugin-raspberrypi</artifactId>

        <version>${pi4j.version}</version>

    </dependency>

    <dependency>

        <groupId>com.pi4j</groupId>

        <artifactId>pi4j-plugin-pigpio</artifactId>

        <version>${pi4j.version}</version>

    </dependency>

</dependencies>

Pi4J code blocks which are used

Please check out the GitHub project for the sources. In this post we are only highlighting some parts of it. As you will see, a lot of comments are added in this project to make it as easy as possible to understand and use.

Initialization

Before you can use Pi4J you must initialize a new runtime context.

The ‘Pi4J’ static class includes a few helper context creators for the most common use cases. The ‘newAutoContext()’ method will automatically load all available Pi4J extensions found in the application’s classpath which may include ‘Platforms’ and ‘I/O Providers’.

var pi4j = Pi4J.newAutoContext();

Output Pi4J Context information

The library contains helper functions to output info about the available and used platforms and providers. To keep the example code clean, these are part of the “PrintInfo.java” class. For example to print the loaded platforms:

public static void printLoadedPlatforms(Console console, Context pi4j) {

        Platforms platforms = pi4j.platforms();

        console.box("Pi4J PLATFORMS");

        console.println();

        platforms.describe().print(System.out);

        console.println();

    }

„console.box“ which is used in the above code snippit, is a helper method which is also provided by Pi4J to output text to the logger with some additional „make-up“. For example for this piece of code:

[main] INFO com.pi4j.util.Console - --------------------

[main] INFO com.pi4j.util.Console - | Pi4J PLATFORMS |

[main] INFO com.pi4j.util.Console - --------------------

[main] INFO com.pi4j.util.Console -

PLATFORMS: [1] "Pi4J Runtime Platforms" <com.pi4j.platform.impl.DefaultPlatforms>

└─PLATFORM: "RaspberryPi Platform" {raspberrypi} <com.pi4j.plugin.raspberrypi.platform.RaspberryPiPlatform>

[main] INFO com.pi4j.util.Console -

Handle the button presses

To handle digital input events we first need a configuration for it. Using that configuration, Pi4J can create the object for us and the state changes can be handled with a listener.

private static int pressCount = 0;

private static final int PIN_BUTTON = 24; // PIN 18 = BCM 24

var buttonConfig = DigitalInput.newConfigBuilder(pi4j)

      .id("button")

      .name("Press button")

      .address(PIN_BUTTON)

      .pull(PullResistance.PULL_DOWN)

      .debounce(3000L)

      .provider("pigpio-digital-input");

      

var button = pi4j.create(buttonConfig);

button.addListener(e -> {

       if (e.state() == DigitalState.LOW) {

              pressCount++;

              console.println("Button was pressed for the " 

			+ pressCount + "th time");

       }

});

Toggle a LED

For the LED we use a similar approach with a configuration. The created led-object can be used to toggle its state. In this example the toggling of the LED speeds up depending on the number of times the button has been pressed.

private static final int PIN_LED = 22; // PIN 15 = BCM 22

var ledConfig = DigitalOutput.newConfigBuilder(pi4j)

      .id("led")

      .name("LED Flasher")

      .address(PIN_LED)

      .shutdown(DigitalState.LOW)

      .initial(DigitalState.LOW)

      .provider("pigpio-digital-output");

      

var led = pi4j.create(ledConfig);

while (pressCount < 5) {

      if (led.equals(DigitalState.HIGH)) {

           led.low();

      } else {

           led.high();

      }

      Thread.sleep(500 / (pressCount + 1));

}

Closing the application

Before the application quits, we need to call the ‘shutdown()’ function on the Pi4J static helper class. This will ensure that all I/O instances are properly shutdown, released by the system and shutdown in the appropriate manner. Terminate will also ensure that any background threads/processes are cleanly shutdown and any used memory is returned to the system.

pi4j.shutdown();

Steps to run this application on your Raspberry Pi

  • Attach a LED and button as shown in the image above
  • Use a recent Raspbian OS image which has Java 11. To check if you have the correct Java version in the terminal:
$ java -version
openjdk version "11.0.6" 2020-01-14
OpenJDK Runtime Environment (build 11.0.6+10-post-Raspbian-1deb10u1)
OpenJDK Server VM (build 11.0.6+10-post-Raspbian-1deb10u1, mixed mode)
•	Download the project from GitHub and build it:
$ git clone https://github.com/Pi4J/pi4j-example-minimal.git
$ cd pi4j-example-minimal/
$ mvn package
•	Change to the distribution directory where you can find the generated package and required Java-modules. Start it with the provided run.sh script:
$ cd target/distribution
$ ls -l
total 644
-rw-r--r-- 1 pi pi 364456 Jun 19 10:04 pi4j-core-2.0-SNAPSHOT.jar
-rw-r--r-- 1 pi pi   7243 Jun 19 10:04 pi4j-example-minimal-0.0.1.jar
-rw-r--r-- 1 pi pi 142461 Jun 19 10:04 pi4j-library-pigpio-2.0-SNAPSHOT.jar
-rw-r--r-- 1 pi pi  37302 Jun 19 10:04 pi4j-plugin-pigpio-2.0-SNAPSHOT.jar
-rw-r--r-- 1 pi pi  26917 Jun 19 10:04 pi4j-plugin-raspberrypi-2.0-SNAPSHOT.jar
-rwxr-xr-x 1 pi pi    101 Jun 19 10:04 run.sh
-rw-r--r-- 1 pi pi  52173 Jun 19 10:04 slf4j-api-2.0.0-alpha0.jar
-rw-r--r-- 1 pi pi  15372 Jun 19 10:04 slf4j-simple-2.0.0-alpha0.jar
$ sudo ./run.sh
•	The output will first show you some info about the platforms and providers. Then the LED starts blinking and shows how much times you pushed the button:
LED high
LED low
LED high
Button was pressed for the 1th time
LED low
LED high
Button was pressed for the 2th time
LED low
LED high
...
Button was pressed for the 4th time
LED low
LED high
LED low
LED high
Button was pressed for the 5th time

Conclusion

Agree, this wasn’t rocket science! But is was fun, isn’t it? When the LED lights up for the first time when you start your application, you get that same wonderful feeling of reaching a new milestone. Yes, you made your first application that controls physical components!

But all this is just a preparation! In the next articles we are going to extend and use this new knowledge to build more complex applications on the Raspberry Pi. Stay tuned!

Links & Literature

[https://pi4j.com/getting-started/]

[https://www.fhnw.ch/en/]

[https://github.com/Pi4J/pi4j-example-minimal]

[https://leanpub.com/gettingstartedwithjavaontheraspberrypi/]

[https://www.elektor.com/getting-started-with-java-on-the-raspberry-pi]


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK