Englisch version   English version


Version Anpassungen
1.0 (2020-05-15) Initiale Version

Motivation

Die Fernbedienung für meinen Fernsehapparat versteckt sich immer auf hinterlistige Weise. Mein Smartphone finde ich einfacher. Zur Not kann ich es anrufen, dann meldet es sich akustisch. Leider gibt es für meinen Fernseher, ein Apparat von Metz, keine App, die passende IR-Codes sendet :-(. Mit der unten beschriebenen Extension für den MIT App Inventor habe ich auf einfache Art selbst eine passende App entwickeln können.


In­halts­ver­zeich­nis

Download

Verwendung

Das Paket-Muster

Referenz

Blöcke

Fehler-Codes

Beispiel

Fernbedienung für Metz-Fernseher

Aufnahme von IR-Codes

Werkzeuge

Download

Das ZIP-Archiv UrsAI2IrXmitter zum Download. Das Archiv enthält den Quellcode, das kompilierte Binary zum Upload in den App Inventor und eine Beispiel-Anwendung.

Verwendung

Die Extension wurde so konstruiert, dass möglichst wenig Aufwand in den AI2-Blöcken notwendig ist. Umfangreiche Logik in den Blöcken führen bei der visuellen Programmierung schnell zu unübersichtlichen Anwendungen. Das wollte ich vermeiden.

Die Extension ist ein Wrapper für die Android Klasse ConsumerIrManager. Weitere Details können hier nachgelesen werden.

Die Extension kann Code-Pakete einzeln versenden (transmit) oder mit automatischer Wiederholung. Bei Wiederholungen kann man unterscheiden, ob das gleiche Code-Paket mehrfach versandt werden soll (RepeatedTransmit) oder, nach einem Startpaket, die Folgepakete eine andere Code-Sequenz besitzen sollen (RepeatedAlternateTransmit). Letztere Funktion findet zumeist bei der Ein/Aus-Sequenz Verwendung. Es wäre ansonsten ziemlich fatal, wenn das zu bedienende Gerät im Takt der Wiederholungen ein- und wieder ausschaltet. Wiederholungen können in der Anzahl beschränkt oder endlos versandt werden. In beiden Fällen unterbricht StopTransmit einen laufenden Übertragungsvorgang.

Die Pausen zwischen dem Startpaket und den Folgepaketen lässt sich über die Eigenschaft StartDelay einstellen, die Pause zwischen den Folgepaketen über die Eigenschaft RepetitionDelay.

Nach der Übertragung eines einzelnen Pakets wird das Ereignis PatternXmitted ausgelöst. Wenn die komplette Wiederholungsfolge abgearbeitet oder abgebrochen wurde, wird das Ereignis TransmitDone ausgelöst.

Beide Ereignisse werden auch beim Einzelversand ausgelöst, dann aber direkt hintereinander. Das ist nicht immer gewünscht. In der Beispiel-App signalisiert eine blinkendes Symbol die Übertragung eines Pakets. Beim Ereignis PatternXmitted wird die Farbe der blinkenden Fläche umgeschaltet, bei TransmitDone wieder farblos geschaltet. Beim Einzelversand würde die Signalfläche praktisch nie aufblinken. Stellt man die  Eigenschaft EventTransmitDoneDelay auf einen Wert größer als Null ein, wird in diesem Fall zwischen beiden Ereignissen die angegebene Verzögerung eingebaut.

Man kann die Extension dazu veranlassen, selbständig auf das Drücken und Loslassen von Tasten (Button) zu reagieren. Über die Funktionen RegisterButtonForSinglePattern, RegisterButtonForRepeatedPattern und  RegisterButtonForRepeatAltPattern lassen sich Schaltflächen mit der angegebenen Funktionalität verknüpfen. Beim TouchDown-Ereignis der Schaltfläche wird die angegebene Funktion ausgelöst, beim TouchUp-Ereignis wieder gestoppt (bei Wiederholungen). Dadurch reduziert sich die Programmierung einer Taste auf eine einzelne Anweisung, z.B.:

Die Extension lässt sich über eine Reihe von Eigenschaften konfigurieren. HasIrEmitter gibt an, ob  das Gerät überhaupt über einen IR-Sender verfügt. Ist das nicht der Fall, führen alle anderen Funktionen zu Fehlern. Über die Eigenschaft CarrierFrequency wird die Trägerfrequenz des IR-Signals eingestellt. Am Häufigsten wird 38 kHz verwandt. Es lässt sich jedoch nicht jede beliebige Frequenz einstellen. Welche möglich sind, kann über CarrierFrequencies bzw. CarrierFrequencyList abgerufen werden.

Die Extension besitzt keine Fehlermeldungen, auf die ein Anwender reagieren könnte. Auf diesem Grunde wird das AI2-Standard-Fehlerereignis ErrorOccurred zur Fehlermeldung benutzt.

Zum Schluss (s. Bespiele) gibt es noch ein kleines Arduino-Programm, mit dem man die Muster der IR-Codes ermitteln kann.

Das Paket-Muster

Der IR-Code, der gesendet werden soll, wird durch eine Liste von Zahlen repräsentiert, die jeweils abwechselnd die Dauer von Mark (es wird ein IR-Signal mit der eingestellten Frequenz gesendet) und Space (Pause zwischen den Signalen) in μs angeben. Der Code beginnt immer mit einem Mark.

mark-space

Referenz

Blöcke

Block Funktion Anmerkung
Konfiguration
HasIrEmitter  Gibt an, ob das Gerät einen Infrarot-Sender besitzt. Der Rückgabewert ist true oder false.
CarrierFrequencies Liefert die unterstützten Träger-Frequenzen als komma-separierten String. Nur diese Frequenzen können der Eigenschaft CarrierFrequency zugewiesen werden.
CarrierFrequencyList Liefert die unterstützten Träger-Frequenzen als Liste.  
CarrierFrequency Stellt die zu benutzende Trägerfrequenz ein oder ruft sie ab. Die Angabe erfolgt in Hertz (Hz). Der Standardwert ist 38.000 (38 kHz). Es können nur solche Werte eingestellt werden, die von CarrierFrequencies bzw. CarrierFrequencyList ausgewiesen werden.

Diese Eigenschaft ist auch im Designer verfügbar.

Bei der Angabe von nicht unterstützen Werten wird Screen.ErrorOccurred mit Fehlercode 17302 ausgelöst.
StartDelay StartDelay legt bei automatischer Wiederholung die Pause zwischen dem ersten und den Folgepaketen in Millisekunden (ms) fest. Gültige Werte sind 0..1000. Der Standardwert ist 500 ms.

Diese Eigenschaft ist auch im Designer verfügbar.

Bei der Angabe von nicht unterstützen Werten wird Screen.ErrorOccurred mit Fehlercode 17308 ausgelöst.
RepetitionDelay RepetitionDelay legt bei automatischer Wiederholung die Pause zwischen den  Folgepaketen in Millisekunden (ms) fest. Gültige Werte sind 0..1000. Der Standardwert ist 500 ms.

Diese Eigenschaft ist auch im Designer verfügbar.

Bei der Angabe von nicht unterstützen Werten wird Screen.ErrorOccurred mit Fehlercode 17309 ausgelöst.
EventTransmitDoneDelay (Zusätzliche) Verzögerung für das Ereignis TransmitDone nach dem Versenden eine einzelnen Pakets. Gültige Werte sind 0..1000. Nach dem Versenden eines Pakets wird zunächst das Ereignis PatternXmitted ausgelöst und, am Schluss einer Wiederholungssequenz, das Ereignis TransmitDone. Beim Versenden eines einzelnen Pakets würden beide Ereignisse direkt aufeinander ausgelöst. Für manche Anwendungen, z.B. wenn das Versenden mit einem optischen Signal verknüpft ist, ist es passender, wenn zwischen beiden Ereignissen eine gewisse Zeitspanne vergeht.

Der Standardwert ist 0 ms.

Diese Eigenschaft ist auch im Designer verfügbar.

Bei der Angabe von nicht unterstützen Werten wird Screen.ErrorOccurred mit Fehlercode 17307 ausgelöst.
Pakete versenden
Transmit Versendet ein einzelnes Paket.

Pattern: Das abwechselnde Ein- / Aus-Muster in Mikrosekunden zum Senden.
Die Methode wird synchron ausgeführt. Sie kehrt erst zurück, wenn das Paket versandt wurde.

Nach Beendigung des Versands werden die Ereignisse PatternXmitted und TransmitDone ausgelöst (s. auch EventTransmitDoneDelay).

Pattern ist entweder ein String mit einer komma-separierten Liste von Ganzzahlen (z.B. "300, 800, 300, ...") oder eine List mit Ganzzahlen. Das abwechselnde Ein/Aus-Muster in Mikrosekunden für die Übertragung.

Intern wird die Android-Methode ConsumerIrManager.transmit() aufgerufen.

Verschachtelte Übertragungen sind nicht möglich. Wenn bereits ein Versand statt findet (ausgelöst durch eine der Repeated...-Methoden), wird Screen.ErrorOccurred mit Fehlercode 17305 ausgelöst.

Wenn Pattern nicht in ein Integer-Array konvertiert werden kann, wird das Ereignis Screen.ErrorOccurred mit Fehlercode 17303 ausgelöst.
RepeatedTransmit Versendet das Paket mehrfach.

Repetitions: Anzahl der Wiederholungen. -1 versendet endlos, solange bis StopTransmission ausgerufen wird.

Pattern: Das abwechselnde Ein- / Aus-Muster in Mikrosekunden zum Senden.
Der Versand erfolgt asynchron. Die Methode kehrt sofort zurück.

Pattern ist entweder ein String mit einer komma-separierten Liste von Ganzzahlen (z.B. "300, 800, 300, ...") oder eine List mit Ganzzahlen. Das abwechselnde Ein/Aus-Muster in Mikrosekunden für die Übertragung.

Intern wird die Android-Methode ConsumerIrManager.transmit() aufgerufen.

Nach dem Versand jedes Pakets wird das Ereignis PatternXmitted ausgelöst, nachdem der komplette Versand beendet oder abgebrochen wurde, wird TransmitDone ausgelöst.

Verschachtelte Übertragungen sind nicht möglich. Wenn bereits ein Versand statt findet (ausgelöst durch eine der Repeated...-Methoden), wird das Ereignis Screen.ErrorOccurred mit Fehlercode 17305 ausgelöst.

Wenn Pattern nicht in ein Integer-Array konvertiert werden kann, wird das Ereignis Screen.ErrorOccurred mit Fehlercode 17303 ausgelöst.
RepeatedAlternateTransmit Versendet ein Start-Paket und mehrfach ein Folgepaket.

Repetitions: Anzahl der Wiederholungen für das Folgepaket. -1 versendet endlos, solange bis StopTransmission ausgerufen wird.

Pattern: Start-Paket, ein abwechselndes Ein- / Aus-Muster in Mikrosekunden zum Senden.

AltPattern: Folgepaket, ein abwechselndes Ein- / Aus-Muster in Mikrosekunden zum Senden.
Der Versand erfolgt asynchron. Die Methode kehrt sofort zurück.

Die Angabe zu Pattern oder AltPattern ist entweder ein String mit einer komma-separierten Liste von Ganzzahlen (z.B. "300, 800, 300, ...") oder eine List mit Ganzzahlen. Das abwechselnde Ein/Aus-Muster in Mikrosekunden für die Übertragung.

Intern wird die Android-Methode ConsumerIrManager.transmit() aufgerufen.

Nach dem Versand jedes Pakets wird das Ereignis PatternXmitted ausgelöst, nachdem der komplette Versand beendet oder abgebrochen wurde, wird TransmitDone ausgelöst.

Verschachtelte Übertragungen sind nicht möglich. Wenn bereits ein Versand statt findet (ausgelöst durch eine der Repeated...-Methoden), wird das Ereignis Screen.ErrorOccurred mit Fehlercode 17305 ausgelöst.

Wenn Pattern nicht in ein Integer-Array konvertiert werden kann, wird das Ereignis Screen.ErrorOccurred mit Fehlercode 17303 ausgelöst, bzw. 17304 bei AltPattern.
StopTransmission  Beendet einen Wiederholungsversand. Der Abbruch der Sequenz erfolgt nach dem ein Paket komplett übertragen wurde oder die jeweilige Pausenzeit abgelaufen ist. Einzelne Pakete oder Pausen werden nicht unterbrochen.
Ereignisse
PatternXmitted Das Ereignis PatternXmitted wird nach dem Versandt eines jeden Pakets ausgelöst.  
TransmitDone Das Ereignis wird ausgelöst, wenn eine Übertragungssequenz beendet oder unterbrochen wurde. Bei dem Versand von Einzelpaketen besteht die Möglichkeit das Ereignis verzögert auszulösen (s.o.).
ErrorOccurred Meldung bei Fehlern in der Ansteuerung der Extension. Es gibt keine Fehler, auf die ein Anwender reagieren könnten. Fehler in werden deshalb über das zentrale Fehler-Ereignis ausgesteuert.
Automatik
RegisterButtonForSinglePattern Registriert die angegebene Button-Komponente für den automatischen Einzelpaket-Versand. Bei Button.TouchDown wird Transmit (s.o) mit dem angegebenen Pattern ausgeführt.
RegisterButtonForRepeatedPattern  Registriert die angegebene Button-Komponente für den automatischen Paket-Versand mit Wiederholungen. Bei Button.TouchDown wird RepeatedTransmit (s.o) mit dem angegebenen Pattern ausgeführt.

Bei Button.TouchUp wird StopTransmission (s.o)  ausgeführt.
RegisterButtonForRepeatAltPattern Registriert die angegebene Button-Komponente für den automatischen Paket-Versand mit Wiederholungen. Bei Button.TouchDown wird RepeatedAlternateTransmit (s.o) mit dem angegebenen Pattern und AltPattern ausgeführt.

Bei Button.TouchUp wird StopTransmission (s.o)  ausgeführt.

Fehler-Codes

Code Meldung Bedeutung
117301 Carrier frequency is not supported Die übergebene Trägerfrequenz wird nicht unterstützt.
17302 Device does not have an IR transmitter Das Gerät besitzt keinen Infrarot-Sender.
17303 Cannot convert pattern to integers Der Parameter Pattern hat einen nicht konvertierbaren Inhalt.
17304 Cannot convert pattern to integers Der Parameter AltPattern hat einen nicht konvertierbaren Inhalt.
17305 Nested transmits are not allowed Verschachtelte Sendeaufrufe können nicht ausgeführt werden.
17306 Component is not a Button Die übergebene Komponente ist nicht vom Typ Button.
17307 Invalid value for EventTransmitDoneDelay Ungültiger Wert für die Eigenschaft EventTransmitDoneDelay. Der Wertebereich ist 0..1000.
17308 Invalid value for StartDelay Ungültiger Wert für die Eigenschaft StartDelay. Der Wertebereich ist 0..1000.
17309 Invalid value for RepetitionDelay Ungültiger Wert für die Eigenschaft RepetitionDelay. Der Wertebereich ist 0..1000.

Beispiel

Fernbedienung für Metz-Fernseher

Eine kleine Beispiel-App zeigt die Verwendung der Extension (s. Download). Es emuliert die Metz-Fernbedienung RM18.

Screenshot Screenshot

Der notwendige Code für den Kern der App ist zwar lang, weil es viele Tasten zu bedienen gibt, aber ganz einfach strukturiert.

Blocks

Aufnahme von IR-Codes

Wiring

Zur Aufnahme der IR-Codes habe ich einen IR-Receiver an einen Arduino angeschlossen. Dabei ist zu beachten, dass der Empfänger auch für die richtige Trägerfrequenz ausgelegt ist.

Das Programm zur Aufnahmen von IR-Codes (s. Download) basiert auf dem Beispiel IRrecord der Bibliothek IRremote von Ken Shirriff. Für den Zweck, Code-Sequenzen für die Extension zu liefern, habe ich das Programm ein wenig angepasst. Zunächst habe ich nur den Teil des Codes behalten, der für den Empfang der Signale notwendig ist.

Nach ersten Versuchen habe ich festgesellt, das die Fernsteuerung mit folgen Signallängen arbeitet:

Der Code berücksichtigt dies und versucht, die Zeiten auf diese Werte zu abzubilden (abschaltbar). Man erhält Ausgaben in der Form

800,2400,400,1000,400,1000,400,1700,400,1700,400,1000,400,1700,400,1000,400,↵
1000,400,1700,400,1000,400,1000,400,1000,400,1700,400,1000,400,1700,400,↵
1000,400,1700,400,1700,400,1700,400,1000,400,1700,400,1000,400,1700,400↵

Den Output kann man direkt in die Eigenschaft Pattern der Transmit-Funktionen der Extension kopieren.

Für diejenigen, die sich näher mit der Funktionsweise beschäftigen wollen: Die zu Grunde liegende Bibliothek initialisiert einen Timer auf eine Periodenlänge von 50 μs. Im der Timer-Interrupt-Service-Routine wird dann das Eingangssignal abgetastet und an einen Zustandsautomaten weiter gereicht.

ISR-State

Werkzeuge

Für die Erstellung eigener Extensions habe ich einige Tipps zusammengestellt: AI2 FAQ: Extensions entwickeln.