ReSpeaker 4 LEDs mit Pi4J steuern

ReSpeaker 4 LEDS ansteuern

Motivation

Für ReSpeaker im allgemeinen gibt es bereits zahlreiche Bibliotheken, auch einige die LEDs über die GPIO Pins ansteuern. Leider sind diese in Python geschrieben und somit wenig hilfreich für Java Projekte.Da die LEDs an verschiedenste Ereignisse gebunden werden sollen, habe ich mich zunächst auf die Suche gemacht, um eine geeignete Bibliothek für den ReSpeaker 4 zu finden.Für den Respeaker 2 wurde ich tatsächlich fündig, allerdings funktioniert dieser Code nicht mit dem ReSpeaker 4.So entstand diese Bibliothek, welche nachfolgend hier erläutert wird.

Technische Nebensachen – Pins usw.

Der ReSpeaker 4 wird bekanntlich über die GPIO Pins des Raspberry PIs verbunden, ob direkt oder über ein Flachbandkabel beeinflusst die Ansteuerung nicht.Standardmäßig werden dabei nachfolgende Pins verwendet:Data Pin – 12Clock Pin – 14Power Pin – 21Jetzt unterscheided die PI4J Bibliothek zwei unterschiedliche Setzstrukturen der Pins, nämlich Default aka wPi und Broadcom.Der nachfolgende Code geht vom Default aus. Um zu sehen, welcher Pin dem Broadcom- Muster gegenüber steht kann der Befehlgpio readall

verwendet werden.

GPIO all

Benötigte Komponenten

  1. PI4J
  2. ReSpeaker 4
  3. Raspberry Pi (gestet ab 3 b+, sollte aber auch mit Zero gehen)

Pi4J einbinden

Wie gewohnt, lässt sich die benötigte Bibliothek einfach über Maven einbinden.

<dependencies>
 <dependency>
  <groupId>com.pi4j</groupId>
  <artifactId>pi4j-core</artifactId>
  <version>1.2</version>
 </dependency>
</dependencies>

Allgemeiner Programmablauf

Zuerst benötigt der Speaker Power. Dafür muss der Power Pin (hier Pin 21) auf High gesetzt werden. Im Anschluss daran erfolgt die Festlegung des Datenpins und des Tacktpins (Pin 12 und 14) .
Die Farben der LEDs sind bytecodiert und müssen im entsprechenden Byte Muster übertragen werden.
Insgesammt besteht der übertragene Wert aus 32- Bits. Die ersten 8 Bits stehen für die Helligkeit, gefolgt von 8 Bits Rot-Anteil, 8 Bits Grün-Anteil und abschließend 8 Bits Blaue-Anteil. Im Code wird dies mit dem Shift-Operator umgesetzt:

data = ( brightness << 24 ) | ( redRatio << 16 ) | ( greenRatio << 8 ) | blueRatio

Finally Getting Started

Zunächst erfolgt eine Initiallisiering der PI4J Bibliothek. Dafür wird die zugehörige Factory-Methode verwendet. Wie bereits oben erwähnt, erfolgt alles mit der standard Default Pinbelegung. Ansonsten könnte in der Zeile 2 bei setDefaultProvider auch die Broadcom Belegung gewählt werden.

public void init(Pin data_pin, Pin clock_pin) {
    GpioFactory.setDefaultProvider(new RaspiGpioProvider());
    GpioController gpioController = GpioFactory.getInstance();
    setPowerToHigh(gpioController);
    dataPin = gpioController.provisionDigitalOutputPin(data_pin);
    clockPin = gpioController.provisionDigitalOutputPin(clock_pin);
    data = new int[numberOfLights];
    resetAllLights();
}

Nach dem holen der Instanz erfolgt das Aktivieren des Power Pins, das setzten des Daten- und Taktpins und das vorbereiten des Datenarrays. Abschließend werden alle LEDs auf den Auszustand gesetzt.

private void setPowerToHigh(GpioController gpioController) {
    gpioController.provisionDigitalOutputPin(RaspiPin.GPIO_21).high();
}
public void resetAllLights() {
    for (int i = 0; i < numberOfLights; ++ i) {
        data[i] = 0;
    }
    show();
}

Setzen der LED-Farben

Die übertragung der Farben erfolgt in drei Schritten über die Methode show():

  1. Preamble setzen
  2. Bits übertragen
  3. Abschluss setzen
public final void show() {
    sendPreamble();
    sendData();
    sendLatch();
}
private void sendPreamble() {
    for (int i = 0; i < numberOfLights; ++ i)
        writeByte(( byte ) 0);
}
private void sendData() {
    for (int i = 0; i < numberOfLights; ++ i)
        writeLedData(data[i]);
}
private void sendLatch() {
    dataPin.setState(false);
    for (int i = 0; i < 36; ++ i) {
        clockPin.setState(true);
        clockPin.setState(false);
    }
}
private void writeByte(byte out) {
    for (int i = 7; i >= 0; -- i) {
        dataPin.setState( ( out & ( 1 << i ) ) != 0);
        clockPin.setState(true);
        clockPin.setState(false);
    }
}
private void writeLedData(int data) {
    writeByte(( byte ) ( 0xe0 | ( ( data >> 24 ) & 0x1f ) ));
    writeByte(( byte ) ( data ));
    writeByte(( byte ) ( data >> 8 ));
    writeByte(( byte ) ( data >> 16 ));
}

In diesen Methoden erfolgt neben dem Übertragen der Lichtbits, auch das setzten des Clock Pins auf die notwendigen Zustände.

Während die writeByte() Methode die entsprechenden Bits an die GPIO-Schnittstelle überträgt, beendet die sendLatch()  Methode die Übertragung. In dieser Methode werden 36 Nullen gesendet, um das Ende zu signalisieren.

Verwendung

Nach dem Instanziieren der Class muss zuerst der Data und Clock Pin gesetzt werden, anschließend lässt sich über die setLight() Methode jede der verfügbaren LEDs auf die gewünschte Farbe setzen. Während die erste Variable für den LED Index steht, folgen danach die RGB Werte. Zuletzt steht der Helligkeitsfaktor mit einem Maximalwert von 31.
Über die Show() Methode erfolgt dann die letztendliche Übertragung an den ReSpeaker.

GPIOLEDController t = new GPIOLEDController(12);
t.init(RaspiPin.GPIO_12, RaspiPin.GPIO_14);
//Setzt die erste LED auf rot
t.setLight(0, 255, 0, 0, 31);
t.show();

ReSpeaker 4 LEDS in grün

Fazit

Der ReSpeaker ist ein sehr schöner Baustein um Zustände zu visualisieren. Neben der offensichtlichen Funktion als 4-fach Lautsprecher, eignet er sich mit seinen 12 LEDs auch perfekt um die gängigen Sprachassistenten nachzuempfinden und deren Muster nachzubauen.
Für Java bestehen nach meinem Kenntnisstand noch nicht viele Anwendungen, da die Mehrheit doch Python verwendet. Für Python stellt der Hersteller bereits Bibliotheken auf seinem Github zur Verfügung.

Ich hoffe mit dieser Bibliothek auch die Java Entwicklung zu ermutigen und gleichzeitig zu unterstützen.

Die ganze Java Bibliothek befindet sich auf meinem Github.

Interne Schulungen in Cucumber & Selenium


In geschützter Umgebung lernt und festigt Ihr Team individuelles Wissen für Ihre aktuellen Anforderungen. Damit Ihr Projekt erfolgreich und wie geplant abgeschlossen wird.

Das könnte Sie auch interessieren

Licht steuern mit Java und Philips Hue

Licht steuern mit Java und Philips Hue Motivation Für meinen selbstprogrammierten Sprachassistenten wollte ich ein Modul für die Lichtsteuerung entwickeln. Ziel war es,...

API Testing mit Java und WireMock

API Testing mit Java und WireMock Motivation Ein bekanntes Problem: Öffentliche APIs werden abgefragt und liefern Daten in Form von JSON oder anderen Formaten zurück....

Apple Kalender auslesen mit Java

Apple Kalender mit Java auslesen Motivation Apple Kalender-Einträge sollen synchron auf meinem Java-Dashboard sowie auf sämtlichen anderen Geräten im Haus gepflegt...

Sealed Classes mit Java JDK 17

Sealed Classes mit Java JDK 17 Was sind Sealed Classes? Mit dem kommenden Java Release 17 werden sogenannte Sealed Classes eingeführt. Diese waren zuvor bereits seit...

Rolladensteuerung mit Loxone und Java

Automatische Rolladensteuerung mit Java und Loxone Motivation Loxone ist ein bekannter Anbieter für Smarthome Rolläden. Während sich über die mitgelieferte Oberfläche...

Behaviour Driven Development (BDD) mit Cucumber und Gherkin Schulung

Behaviour Driven Development (BDD) mit Cucumber Schulung Schulungsbeschreibung In dieser Schulung lernen Teilnehmer*innen den sicheren Umgang mit BDD, Cucumber und...

Unit Tests mit AI – Machinet Testfallerstellung

Unit Tests mit AI - Machinet Testfallerstellung Werden Tester bald durch KIs ersetzt? Spoiler: Nein In diesem Blogbeitrag möchte ich auf ein paar Grundlagen der KI...

Erinnerungsassistent für Medikamente mit Sprachausgabe

Erinnerungsassistent für Medikamenteinnahme mit Sprachausgabe Motivation Bevor Corona began, besuchten Ich und meine Familie meine Großeltern regelmäßig. Dabei...

Devops mit Cucumber, Jira und Xray

Devops mit Cucumber, Jira und Xray "Hat auf meiner Maschine funktioniert, ist jetzt Operating Problem“ Diese oder vergleichbare Aussagen sind nicht neu und...