JavaFX mit selbst entwickelter Hardware ergänzen

GPIOs und Java

Wir erstellen ein neues Maven-Projekt und fügen die Abhängigkeiten zu Pi4J sowie JavaFX hinzu (Listing 1).

Listing 1
com.pi4jpi4j-core0.0.5-SNAPSHOTcom.oraclejavafx-runtime2.0system${java.home}/lib/jfxrt.jar

Da wir mit der Snapshot-Version von Pi4J arbeiten, müssen wir auch das Snapshot Repository bekannt machen (Listing 2).

Listing 2
oss-snapshots-repoSonatype OSS Maven Repositoryhttps://oss.sonatype.org/content/groups/publictruealways

Die JavaFX-Abhängigkeit kann nicht aus einem Maven Repository geladen werden. Darum verweisen wir auf unsere bestehende Java-Installation. Für unser Programm genügt übrigens eine aktuelle Java-7-Installation, falls es Java 8 noch nicht auf Ihre Maschine geschafft hat. Danach bereiten wir unser Projekt mit mvn eclipse:eclipse für Eclipse vor.

Gemäß dem Schaltplan haben wir unseren Taster über das gelbe Kabel an den Pin #17 angeschlossen. Für die Kommunikation mit Pin #17 verwenden wir Pi4J. Leider verwendet diese Bibliothek eine andere Nummerierung. Gemäß [4] entspricht der verwendete Pin dem Pi4J Pin 0.

Abb. 2: Die Nummerierung der GPIO Pins (Quelle:pi4j.com)

Unsere Applikation soll den Status des Tasters ausgeben. Dazu teilen wir den Code in die Hardwareanbindung und die Ausgabe auf. Da wir Pi4J mangels GPIO Pins auf der Entwicklungsmaschine nicht testen können, empfiehlt es sich, hier ein Java-Interface (z. B. HwController) zu erstellen, damit wir zur Entwicklungszeit die GPIO Pins einfach simulieren können. Um unseren Beispielcode kurz zu halten, verzichten wir aber jetzt bewusst darauf. Der Status des Tasters wird innerhalb der Applikation in einem Model gehalten. Für unser extrem einfaches Model begnügen wir uns mit der Klasse BooleanProperty aus JavaFX.

Das Schöne an Pi4J ist, dass es unter anderem auch Listeners anbietet. Anstelle eines Pollings auf unseren Pin werden wir über Statusveränderungen informiert. Die Interaktion mit den Hardware-Interrupts übernimmt Pi4J. Wir Softwareentwickler fühlen uns also sofort wieder heimisch, und die Hardware ist schon beinahe vergessen. Die Implementierung der Hardwarekommunikation gestaltet sich wie in Listing 3.

Listing 3
public class Pi4JController {
  private BooleanProperty model;
  private GpioController gpio;
  public Pi4JController() {
    this.gpio = GpioFactory.getInstance();
    GpioPinDigitalInput input = gpio.provisionDigitalInputPin(RaspiPin.GPIO_00, PinPullResistance.PULL_DOWN);
    input.addListener(new GpioPinListenerDigital() {
      @Override
      public void handleGpioPinDigitalStateChangeEvent(
          GpioPinDigitalStateChangeEvent event) {
        model.set(PinState.HIGH.equals(event.getState()));
      }
    });
  }
  public void setModel(BooleanProperty model) {
    this.model = model;
  }
}

Unser Pi4JController initialisiert im Konstruktor die benötigten GPIO-Pins. Im Speziellen wird der Pin 00 als digitaler Input Pin aufgeschaltet. Anschließend registrieren wir auf dem Pin einen Listener, der bei einer Statusänderung unser Model aktualisiert. PinState.HIGH bedeutet, dass Strom fließt bzw. der Taster gedrückt wurde.

Damit ist der hardwarenahe Teil bereits abgeschlossen. Mit einem einfachen Programm wie dem in Listing 4 könnte nun der Controller bereits angesprochen werden.

Listing 4
public class CliApp {
  public static void main(String[] args) throws InterruptedException {
  BooleanProperty model = new SimpleBooleanProperty();
    Pi4JController hwController = new Pi4JController();
    hwController.setModel(model);
    model.addListener(new ChangeListener() {
      @Override
      public void changed(ObservableValue extends Boolean> observable, Boolean oldValue, Boolean newValue) {
        System.out.println("Der Taster ist " + (newValue ? "an" : "aus"));
      }
    });
    while(true) {
      Thread.sleep(2000);
    }
  }
}
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.