Version | Anpassungen |
---|---|
1.0 (2020-05-15) | Initiale Version |
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.
Inhaltsverzeichnis
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.
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.
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.
Block | Funktion | Anmerkung |
---|---|---|
Konfiguration | ||
Gibt an, ob das Gerät einen Infrarot-Sender besitzt. | Der Rückgabewert ist true oder false. | |
Liefert die unterstützten Träger-Frequenzen als komma-separierten String. | Nur diese Frequenzen können der Eigenschaft CarrierFrequency zugewiesen werden. | |
Liefert die unterstützten Träger-Frequenzen als Liste. | ||
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 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 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. |
|
(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 | ||
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. |
|
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. |
|
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. |
|
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 | ||
Das Ereignis PatternXmitted wird nach dem Versandt eines jeden Pakets ausgelöst. | ||
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.). | |
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 | ||
Registriert die angegebene Button-Komponente für den automatischen Einzelpaket-Versand. | Bei Button.TouchDown wird Transmit (s.o) mit dem angegebenen Pattern ausgeführt. | |
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. |
|
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. |
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. |
Eine kleine Beispiel-App zeigt die Verwendung der Extension (s. Download). Es emuliert die Metz-Fernbedienung RM18.
Der notwendige Code für den Kern der App ist zwar lang, weil es viele Tasten zu bedienen gibt, aber ganz einfach strukturiert.
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.
Für die Erstellung eigener Extensions habe ich einige Tipps zusammengestellt: AI2 FAQ: Extensions entwickeln.