A Device I/O library written in Java that provides an object-orientated interface for a range of GPIO / I2C / SPI devices such as LEDs, buttons and other various sensors connected to intelligent devices like the Raspberry Pi. Actual GPIO / I2C / SPI device communication is delegated via a pluggable abstraction layer to provide maximum compatibility across devices.

This library makes use of modern Java 8 features such as automatic resource management, Lambda Expressions and Method References where they simplify development and improve code readability.

Created by Matt Lewis, inspired by GPIO Zero.


The aim of this library is to encapsulated real-world devices as classes with meaningful operation names, for example LED (on / off), LDR (analogue readings), Button (pressed / released), Motor (forward / backwards / left / right). All devices implement Closeable hence will get automatically closed by the try (Device d = new Device()) { d.doSomething() } statement. This is best illustrated by some simple examples.

LED control:

try (LED led = new LED(pin)) {
    led.blink(0.5f, 0.5f, 10, false);

Turn on an LED when you press a button:

try (Button button = new Button(buttonPin, GpioPullUpDown.PULL_UP); LED led = new LED(ledPin)) {

Or a random LED flicker effect:

try (PwmLed led = new PwmLed(pin)) {
    GpioScheduler.getInstance().invokeAtFixedRate(RANDOM::nextFloat, led::setValue, 50, 50, TimeUnit.MILLISECONDS, false);

All devices are provisioned by a Device Factory with a default NativeDeviceFactory for provisioning via the host board itself. However, all components accept an optional Device Factory parameter for provisioning the same set of components via an alternative method. This is particularly useful for GPIO expansion boards and Analogue-to-Digital converters.

The Raspberry Pi provides no analogue input pins; attempting to create an AnalogueInputDevice such as an LDR using the Raspberry Pi default native device factory would result in a runtime error (UnsupportedOperationException). However, ADC classes such as the MCP3008 have been implemented as analogue input device factories hence can be used to construct analogue devices such as LDRs:

try (MCP3008 mcp3008 = new MCP3008(chipSelect); LDR ldr = new LDR(mcp3008, pin, vRef, r1)) {

Repeating the previous example of controlling an LED when you press a button but with components connected via an MCP23017 GPIO expansion board:

try (MCP23017 mcp23017 = new MCP23017(intAPin, intBPin);
        Button button = new Button(mcp23017, inputPin, GpioPullUpDown.PULL_UP);
        LED led = new LED(mcp23017, outputPin, false, true)) {

Analogue input devices also provide an event notification mechanism. To control the brightness of an LED based on ambient light levels:

try (MCP3008 mcp3008 = new MCP3008(chipSelect); LDR ldr = new LDR(mcp3008, pin, vRef, r1); PwmLed led = new PwmLed(ledPin)) {
    // Detect variations of 5%
    ldr.addListener(.05f, (event) -> led.setValue(1-event.getScaledValue()));


TODO Describe getting started steps. Snapshot builds of the library are available in the Nexus Repository Manager. This library uses tinylog v1.0.



I've done some limited performance tests (turning a GPIO on then off, see GpioPerfTest) on a Raspberry Pi 2 using the various native device factory providers as well as a test using Pi4j's wiringPi JNI API directly without going via my DIO-Zero wrapper (see WiringPiRawPerfTest); here are the results:

Provider Iterations Frequency (kHz)
Pi4j 1.0 10,000 0.91
JDK DIO 1.1 100,000 8.23
Pi4j 1.1 10,000,000 622
wiringPi 5,000,000 1,683
wiringPi (direct) 10,000,000 2,137
pigpio 5,000,000 1,266
pigpio (direct) 10,000,000 1,649

For a discussion on why Pi4j 1.0 was so slow, see this issue. These results are in-line with those documented in the book "Raspberry Pi with Java: Programming the Internet of Things". For reference, the author's results were:

Library Frequency (kHz)
Pi4j 1.0 0.751
JDK DIO 1.0 3.048
wiringPi (direct) 1,662


This project is hosted on GitHub, please feel free to join in:

TODO Add something about Maven dependencies, setting up development environments.


There is still a lot left to do, in particular:



This work is provided under the MIT License.