Infrarot Empfänger

Funktionsweise

Mithilfe von Infrarot können über einige Meter Distanz digitale Informationen übertragen werden, was beispielsweise oft für die Fernbedienung eines Fernsehers genutzt wird. Die Übertragungsart gleicht hierbei dem Prinzip des Morsens, da die Infrarot-LED im Sendegerät eine Abfolge von Bits durch unterschiedlich lange Pausen zu dem Empfängergerät überträgt. Da jedoch auch viele andere Dinge in der Natur wie beispielsweise unsere Sonne ein Infrarot-Licht emittieren, wird für die elektronische Verwendung nur eine Frequenz von 38kHz verwendet.

Um zu vermeiden, dass eine Fernbedienung über eine oder gar mehrere Sekunden komplett still gehalten werden muss, werden die einzelnen Bits in sehr kurzen zeitlichen Abständen übertragen. Dies klingt im ersten Moment natürlich praktisch, bedeutet jedoch auch, dass das empfangende Gerät sehr präzise zeitliche Messungen durchführen können muss. Genau dies war jedoch beim CrowPi mit der Verwendung von Java in Kombination mit Pi4J nicht möglich, da eine Genauigkeit von rund 60 Mikrosekunden (0.00006 Sekunden) benötigt wird, was sich mit dem Design der Java Virtual Machine nicht umsetzen lässt.

Um diese Komponente jedoch trotzdem zur Verfügung zu stellen, nutzt diese Implementation eine vorinstallierte Applikation namens mode2 welche in C geschrieben wurde. Diese gibt die entsprechend erkannten Signale über die Konsole aus, welche dann automatisch in Java ausgewertet, geprüft und weitergegeben werden. Ein grosser Teil der Logik ist somit weiterhin innerhalb dieser Komponenten-Klasse aufzufinden, das Erkennen der Signale findet jedoch nicht mit Pi4J statt. Sollten sich hier in Zukunft neue Möglichkeiten ergeben, so würde sich die Komponente regulär via GPIO auslesen lassen.

Eine saubere Alternative, die sich weiterhin mit Pi4J umsetzen lässt, wäre einen dedizierten Mikrocontroller für das Empfangen der Infrarot-Signale zu verwenden, welcher dann über einen anderen Bus wie beispielsweise I²C oder SPI die Signale an den Raspberry Pi sendet. Auf dem CrowPi ist dies jedoch nicht vorhanden, sodass diese Möglichkeit nicht besteht.

Für die Verwendung dieser Komponente muss die beigelegte Infrarot-Diode auf dem CrowPi in die 3 Pin-Header eingesteckt werden, da sich diese nicht direkt auf dem CrowPi befindet. Auf dem nachfolgenden Foto ist angegeben, wo die Infrarot-Photodiode einzustecken ist:

Anschluss für Infrarot-Diode

Voraussetzungen

DIP Switches

Für diese Komponente werden keine spezifischen DIP-Switches benötigt, sodass diese in der Standardkonfiguration belassen werden können:

ON(links)12345678ON(rechts)12345678

Verwendung

Nachfolgend wird die Verwendung der Klasse com.pi4j.crowpi.components.IrReceiverComponent Javadoc beschrieben.

Konstruktoren

Konstruktor Bemerkung
IrReceiverComponent() Initialisiert einen Infrarot-Empfänger mit Standardeinstellungen für den CrowPi.
IrReceiverComponent(String mode2Binary, String devicePath) Initialisiert einen Infrarot-Empfänger mit benutzerdefiniertem Pfad zur mode2 Applikation sowie einem Gerätepfad.

Methoden

Methode Bemerkung
void onKeyPressed(EventHandler<Key> handler) Setzt den Event Handler, welcher gedrückte Tasten auf der Infrarot-Fernbedienung als ersten Parameter erhält. Durch die Angabe von null kann das Empfangen von Infrarot-Signalen deaktiviert werden.

Enumerationen

  • com.pi4j.crowpi.components.IrReceiverComponent Javadoc enthält alle unterstützten Tasten, welche sich auf der beigelegten Infrarot-Fernbedienung des CrowPi befinden. Diese Enumeration kann genutzt werden, um innerhalb eines Events die erhaltene Taste zu vergleichen und unterschiedliche Aktionen durchzuführen.

Beispielapplikation

Die Beispielapplikation initialisiert zuerst den Infrarot-Empfänger, wobei hier nicht einmal der übliche Pi4J-Kontext übergeben werden muss, da wie bereits weiter oben beschrieben, von dieser Komponente die Pi4J-Library nicht genutzt wird. Nach erfolgter Initialisierung wird ein Event Handler registriert, der jeden Tastendruck auf der Konsole ausgibt sowie beim Drücken der “CH” Taste eine zusätzliche Ausgabe vornimmt. Anschliessend wird 30 Sekunden gewartet, bevor der Event Handler wieder deaktiviert wird und die Applikation sich beendet.

Pfad zum Codebeispiel: src/main/java/com/pi4j/crowpi/applications/IrReceiverApp.java
Auf GitHub ansehen
package com.pi4j.crowpi.applications;

import com.pi4j.context.Context;
import com.pi4j.crowpi.Application;
import com.pi4j.crowpi.components.IrReceiverComponent;

/**
 * This example demonstrates the infrared receiver component on the CrowPi. Please note that the receiver LED must first be plugged into the
 * three small pinholes labelled as "IR" for this example to work. As Java does not allow for precise enough timings itself, this component
 * does not use Pi4J to retrieve the pulses of the GPIO pin for the IR sensor and instead relies on mode2, an executable provided as part of
 * LIRC for reading from an IR input.
 * <p>
 * A clean alternative would be using a separate microcontroller which handles the super precise timing-based communication itself and
 * interacts with the Raspberry Pi using I²C, SPI or any other bus. This would offload the work and guarantee even more accurate results. As
 * the CrowPi does not have such a dedicated microcontroller though, using `mode2` was the best available approach.
 */
public class IrReceiverApp implements Application {
    @Override
    public void execute(Context pi4j) {
        // Initialize the IR receiver component
        // We do not use Pi4J here at all, so there is no need to pass the context...
        final var ir = new IrReceiverComponent();

        // Register an event listener for key presses
        System.out.println("Welcome to the IR demo! An event listener for key presses will now be registered...");
        ir.onKeyPressed(key -> {
            // Print the key which just has been pressed
            System.out.println("Key on IR remote has been pressed: " + key);

            // It is also possible to check if a specific key was pressed
            if (key == IrReceiverComponent.Key.CH) {
                System.out.println("You pressed the super special CH key! (it is actually not special, sorry to disappoint)");
            }
        });

        // Give the user some time to press buttons
        System.out.println("Done! You now have 30 seconds to try out pressing various keys on the IR remote...");
        sleep(30000);

        // Cleanup the event listener
        ir.onKeyPressed(null);
    }
}

Weitere Möglichkeiten

  • Mit der beigelegten Fernbedienung lassen sich einwandfrei numerische Eingaben tätigen, z.B. um einen einfachen Taschenrechner mit Addition und Subtraktion zu bauen, wofür sich die Zahlentasten sowie Plus und Minus nutzen lassen würden.
  • Die Steuerungstasten für Previous, Next sowie Play/Pause könnten genutzt werden, um den Buzzer zu steuern und verschiedene Melodien damit abzuspielen.