Concepts
diozero is a multi-faceted library for interacting with low-level devices such as environmental sensors and GPIOs. It achieves this via object-oriented APIs that abstract developers from the complexities of low-level device interface code. An initial motivation to developing diozero was to provide a Java equivalent to the excellent Python gpiozero library having found that existing Java libraries didn’t offer such a developer-friendly experience.
The aim of this library is to encapsulate real-world devices (LEDs, buttons, sensors, motors, displays, etc) as classes with meaningful operation names, for example, LED (on / off), LDR (get luminosity), Button (pressed / released), Motor (forward / backwards / left / right).
This library is known to work on the following boards: all models of the Raspberry Pi, Odroid C2, BeagleBone (Green and Black), AllWinner H3 / H5 and H6 CPUs, Next Thing C.H.I.P and ASUS Tinker Board. It is portable to any Single Board Computer that can run Linux and Java 11 as well as any micro-controller with Firmata protocol support.
Pin Numbering
All pin numbers are device native, i.e. Broadcom for the Raspberry Pi, ASUS for the Tinker Board. Pin layouts:
diozero implements a layered architecture to provide maximum portability:
- Device API
- Refers to classes in the com.diozero.devices package that are designed to represent physical devices, such as an LED, and are to be used by diozero applications. All of the classes in com.diozero.devices rely exclusively on the com.diozero.api package for GPIO, I2C, SPI, and Serial communication.
- Base I/O API
- Classes and interfaces in the com.diozero.api package for doing GPIO, I2C, SPI, and Serial communication. These classes make use of the Service Provider Interface layer in the com.diozero.internal.spi package for actual device communication.
- Provider
- All GPIO, I2C, SPI, and Serial device communication is delegated to pluggable device providers for maximum compatibility across different boards. The Provider layer is split into two separate aspects (see the Providers section for further details):
- The Service Provider Interface (com.diozero.internal.spi), and
- Service provider implementations, e.g. the default built-in provider (com.diozero.internal.provider.builtin).
Package Heirarchy
This following image illustrates the relationships between the core packages within diozero.
Clean-up
The library makes use of try-with-resources - all devices implement AutoCloseable
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(18)) {
led.toggle();
SleepUtil.sleepSeconds(.5);
led.toggle();
SleepUtil.sleepSeconds(.5);
}
Turn on an LED when you press a button:
try (Button button = new Button(12); LED led = new LED(18)) {
button.whenPressed(nanoTime -> led.on());
button.whenReleased(nanoTime -> led.off());
SleepUtil.sleepSeconds(10);
}
Or a random LED flicker effect:
Random random = new Random();
try (PwmLed led = new PwmLed(18)) {
DioZeroScheduler.getNonDaemonInstance().invokeAtFixedRate(RANDOM::nextFloat, led::setValue, 50, 50, TimeUnit.MILLISECONDS);
}
Shutdown
To protect against unexpected shutdown scenarios, diozero implements a Shutdown Hook which will close all device factories and internal devices. Custom classes that implement AutoCloseable can also be registered by calling Diozero.registerForShutown() and will be called for shutdown prior to closing the device factories and internal devices.