IR-Fernbedienungen mit RC5

Fernbedienungen mit Infrarot

Die Anfänge der Fernsehns gehen bis in das ausgehende 19. Jahrhundert zurück, aber so richtig massentauglich wurde der Fernseher erst in den 1950er Jahren. Mit seinem Einzug in die heimischen Wohnzimmer muss auch der Wunsch entstanden sein, Lautstärke und Sender ändern zu können ohne den Sessel verlassen zu müssen. Dem Wikipedia-Artikel Fernbedienung lassen sich folgende Entwicklungsstufen entnehmen:

Philips und das RC5-Protokoll

Einer der Pioniere im Bereich Unterhaltungselektronik war Philips. Dort wurde unter anderem das Protokoll RC-5 entwickelt, um das es auf dieser Seite geht. Als Träger kommt Infrarotlicht zum Einsatz, das in Form eines Rechtecksignals mit einer Frequenz von 36 kHz ausgestrahlt wird, d.h. die IR-Lichtquelle wird 36000 mal pro Sekunde ein- und ausgeschaltet. Der große Vorteil davon ist, dass ein solches Signal nicht mit anderen Quellen verwechselt werden kann, die etwa wie Tageslicht kontinuierlich leuchten.

Das Trägersignal von 36 kHz wird mit den Datenbits der RC5-Telegramme moduliert, d.h. das Trägersignal wird seinerseits zu bestimmten Zeiten ein- und ausgeschaltet. Die einzelnen Bits werden aber nicht etwa durch an und aus dargestellt, sondern mittels des Manchester-Codes kodiert. Dabei ist der Wechsel zwischen an und aus entscheidend (die Flanke). Im Falle von RC5 ist ein Wechsel von an nach aus (fallende Flanke) ein 0-Bit und entsprechend der Wechsel von aus nach an (steigende Flanke) ein 1-Bit. Der Vorteil dieser Kodierung wird später noch erklärt.

Ein RC5-Telegramm besteht aus 14 Bits und hat eine zeitliche Ausdehnung von 24,889 ms. Die Telegramme werden alle 113,778 ms wiederholt, sodass eine kontinuierlich gedrückte Taste darstellbar ist. Um einen langen Tastendruck von mehreren kurzen Tastendrücken unterscheiden zu können wird bei jedem erneuten Tastendruck das sogenannte Toggle-Bit invertiert. Die merkwürdig krummen Zahlenwerte ergeben viel mehr Sinn, wenn man sie in Relation zur Trägerfrequenz setzt:

1/36000 Hz = ca. 27,778 µs Dauer einer Periode
64 * 27,778 µs = ca. 1,778 ms Länge eines Bits (bestehend aus 32 Perioden Signal + 32 Perioden Pause)
64 * 27,778 µs * 14 = ca. 24,889 ms Länge eines Telegramms (bestehend aus 14 Bits)
4096 * 27,778 µs = ca. 113,778 ms Wiederholungsrate der Telegramme

Die Telegramme selbst sind folgendermaßen aufgebaut:

S F T A1 A2 A3 A4 A5 C1 C2 C3 C4 C5 C6

Das Field-Bit verdient etwas mehr Aufmerksamkeit. Es war ursprünglich als zweites Start-Bit konzipiert, sodass der Empfänger immer von zwei 1-Bits zu Beginn eines jeden Telegramms ausgehen konnte. Später hat man aber bemerkt, dass die 64 Befehls-Codes, die mit dem 6 Bit breiten Command-Field dargestellt werden konnten, etwas knapp waren. Daraufhin wurde das Field-Bit als invertiertes 7. Befehls-Bit genutzt: steht es auf 1 gelten Befehls-Codes von 0 bis 63, steht es auf 0 gelten Befehls-Codes von 64 bis 127. Für ältere Geräte mit weniger als 64 Befehls-Codes sieht das Field-Bit also wie ein zweites Start-Bit aus, während neuere Geräte die Bedeutung eines auf 0 stehenden Field-Bits kennen und somit alle 128 Befehls-Codes auswerten können.

Untersuchung einer Fernbedienung

Um die von einer Fernbedienung gesendeten Signale sichtbar zu machen habe ich nebenstehende Testschaltung aufgebaut. Sie besteht aus einem Fototransistor und einem Widerstand. Als Fototransistor habe ich einen BPW40 benutzt, wobei der exakte Typ keine Rolle spielt. Wichtig ist nur, dass er auf Infrarotlicht reagiert und nicht etwa extra in einem abgeschirmten Gehäuse sitzt. Fällt Licht ein, fließt ein Strom durch den Transistor und den Widerstand, wodurch eine messbare Spannung abfällt.

Zur Darstellung benutze ich ein JOY-IT DSO-138, ein günstiges Oszilloskop (eigentlich ein Bausatz) mit Farbdisplay. Für ernsthafte Messaufgaben ist das Teil nur bedingt geeignet, aber wenn man recht genau weiß, was da sein müsste, eignet es sich ganz gut zum Nachweis und um Fotos zu machen.

Zunächst das Trägersignal. Der Ausschnitt zeigt die An-Phase eines Bits, bestehend aus 32 Perioden der Trägerfrequenz von 36 kHz. Leider ist die zeitliche Auflösung der Testschaltung und des Oszilloskops nicht groß genug um die einzelnen Flanken zu zeigen, aber die "Unebenheit" der Linie lässt sich genau in 32 einzelne Abschnitte zerlegen. Der nach rechts folgende Signalverlauf sieht in einem größeren Darstellungsbereich wie eine typische Entladekurve eines Kondensators aus und dürfte ebenfalls auf die primitive Testschaltung bzw. die fliegende Verdrahtung zurückzuführen sein.

Noch weiter rausgezoomt wird das gesamte Telegramm mit seinen 14 Bits sichtbar. Wie bereits erwähnt steht ein aus/an-Wechsel für ein 1-Bit und ein ein/aus-Wechsel für ein 0-Bit. Natürlich folgt auf einen aus/an-Wechsel immer irgendwann ein an/aus-Wechsel. Das Entscheidende ist, wo dieser Wechsel stattfindet: der für ein Bit maßgebliche Wechsel ist immer in der Mitte des Bits. Wechsel auf der Grenze zum nächsten Bit dienen quasi nur der Rückführung des Signals und haben zunächst keine Bedeutung.
Die Tatsache, dass die eine Flanke genau in der Mitte eines Bits liegt, begründet auch die vorhin angekündigte Eigenschaft des Manchester-Codes: er ist selbstsynchronisierend.

Die Länge eines Bits ist genau bekannt, aber in real existierenden Schaltungen kann sowohl die Uhr des Senders als auch die des Empfängers ungenau sein. Bei der Übertragung längerer Telegramme kann dies dazu führen, dass der Empfänger asynchron wird und die Bits an einer Stelle zu lesen versucht, die der Sender gar nicht vorgesehen hat. Da aber bekannt ist, dass eine der Flanken immer genau in der Mitte des jeweiligen Bits liegt, kann sich der Empfänger daran ausrichten und kommt mit einer ungefähr gleich laufenden Uhr zurecht. Die Abweichung darf nur nie so groß werden, dass die Flanken verwechselt werden.

Die in diesem Beispiel gezeigte Bitfolge ist 11000000001100. Auf die einzelnen Felder aufgedröselt ist dies:

S F T A1 A2 A3 A4 A5 C1 C2 C3 C4 C5 C6
1 1 0 0 0 0 0 0 0 0 1 1 0 0

Gesendet wird also der Befehls-Code 12 an das Gerät mit der Adresse 0. Im Web findet man viele Tabellen für die Bedeutung der RC5-Codes, so z.B. auch beim OpenDCC-Projekt. Dieser Tabelle zufolge wurde "An / Aus / Standby" an "TV1" gesendet, was stimmt. Um genau zu sein wurde eine Universalfernbedienung (Contour 8 von One For All) genutzt, eingestellt auf einen alten LG-Röhrenfernseher von dem ich wusste, dass er RC5 verwendet.

Der TSOP1736 und seine Verwandten

Im Zusammenhang mit RC5-Projekten wird sehr oft ein Bauteil mit der Bezeichnung TSOP1736 erwähnt. Dabei handelt es sich um einen integrierten Schaltkreis der Firma Vishay (ehemals Telefunken), der die Funktionen IR-Detektor, Signalverstärker und Demodulator kombiniert. Weiterhin besitzt der TSOP1736 ein gefärbtes Gehäuse, das bereits physikalisch als IR-Filter wirkt und Störlicht dämpft. Die 36 weist auf die Trägerfrequenz von 36 kHz hin, dementsprechend gibt es auch die Varianten TSOP1730, TSOP1738, etc. für andere Trägerfrequenzen. Die Baureihe ist mittlerweile abgekündigt, aber es gibt den Nachfolger TSOP31236 sowie ähnliche Bauteile von anderen Herstellern (z.B. SFH506/SFH5110 von Infineon/OSRAM).

Alle haben gemeinsam, dass sie das modulierte IR-Signal empfangen und das Nutzsignal in Form von Logik-Pegeln ausgeben, die dann z.B. mit einem Mikrocontroller weiter verarbeitet werden können. Dabei ist zu beachten, dass lediglich die Trägerfrequenz entfernt wird; die Bausteine interessieren sich kein Stück für das Protokoll, das auf die 36 kHz aufmoduliert wurde. Deshalb lassen sie sich universell einsetzen, z.B. wird beim ASURO ein SFH5110 benutzt der UART überträgt.

Nebenstehend habe ich das Ausgangssignal eines TSOP1730 abfotografiert. Zunächst fällt auf, dass die Logik-Pegel genau invers zum Infrarot-Signal sind: im Ruhezustand ist der Pegel HIGH, wenn der Sensor "belichtet" wird zieht der IC den Pegel nach LOW. Das ist eine typische Konfiguration die sich teilweise aus der Historie der Digitallogik ergibt (Stichworte: TTL, Active Low, Wired OR). Das Foto zeigt die Bitfolge 11100000001100 (also wieder TV1/Standby, aber diesmal mit Toggle-Bit = 1).

Umsetzung als Mikrocontroller-Anwendung

Um so ein RC5-Telegramm auszuwerten lohnt es sich noch mal einen genauen Blick auf den Signalverlauf zu werfen. Weil der Ausgang des Empfänger-ICs logisch invertiert zum ursprünglichen Infrarot-Signal ist, gilt jetzt: fallende Flanken zeigen ein 1-Bit an, steigende Flanken zeigen ein 0-Bit an. Kann man sich ganz leicht herleiten, wenn man im Hinterkopf behält, dass der Pegel im Ruhezustand HIGH ist und das Start-Bit des Telegramms eine 1 darstellt.

Auf den ersten Blick mag es verlockend wirken die unterschiedlichen Breiten der HIGH- und LOW-Phasen auszuwerten. Dies kann man machen, aber schon beim Definieren des Regelwerks stellt man fest, dass diese Herangehensweise unpraktisch ist:

Man benötigt also einen Merker für den aktuellen Wert sowie zwei Timer. Der Merker steht zu Beginn auf 1 und wird bei jeder langen Phase invertiert. Einer der Timer überwacht die Länge der aktuellen Phase um zu entscheiden, ob es eine lange Phase ist. Der zweite Timer stellt fest, wann das nächste Bit beginnt, damit der aktuelle Wert des Merkers dem Telegramm-Puffer hinzugefügt werden kann. Der große Nachteil ist, dass man bei ungenauen Timern über die Bitgrenzen hinweg driften kann und irgendwann nur noch Quatsch einliest.
Dies vermeidet man, indem man die Flanken zur Synchronisation nutzt:

Hier reicht ein Timer, dessen Laufzeit im Bereich zwischen 0,889 ms und 1,778 ms liegt, und idealerweise mit 1,3 ms genau in der Mitte der abzutastenden Signal-Phase liegt. Der Nachteil ist, dass eine Leitung mit Interrupt-Funktion benötigt wird. [Der Vollständigkeit halber sei darauf hingewiesen, dass man eine fehlende Interrupt-Funktion auch durch deutlich häufigeres Abtasten emulieren kann.]

Bei meinem Beispiel-Programm habe ich mich für die zweite Variante mit einer Interrupt-Leitung entschieden.

Auch das Senden von RC5-Telegrammen ist relativ einfach. Alles was dazu benötigt wird ist eine IR-LED und (je nach Leistung) eine geeignete Treiber-Schaltung. Um das Trägersignal zu erzeugen kann man entweder auf externe Hardware zurückgreifen (z.B. einen NE555 wie im ASURO-Beispiel), oder dies ebenfalls vom Mikrocontroller erledigen lassen. Eher zufällig bin ich über die Application Note AVR415 gestolpert, die einen ATtiny28 mit einem speziellen Hardware-Modulator beschreibt. Da der ATtiny28 gleichzeitig über einen kräftigen LED-Treiber verfügt liegt der Verdacht nahe, dass dieser Controller speziell für den Bau von IR-Fernbedienungen gedacht ist. Allerdings ist es scheinbar der einzige Vertreter der AVR-Familie, der diese speziellen Features besitzt, was die ganze Sache schon wieder weniger attraktiv werden lässt. Wer sich nicht an spezielle Hardware binden will, der kann die Trägerfrequenz auch prima mit einem PWM-Kanal erzeugen.

Das Beispiel-Programm "rc5demo"

Für mein Beispiel-Programm habe ich einen ATmega32A und einen TSOP1730 verwendet, der trotz seines leicht abweichenden Frequenzbands bestens mit der bereits erwähnten Universalfernbedienung zusammenarbeitet. Das Programm empfängt die Signale und gibt sie via USART an einen PC weiter, an dem die Ausgaben direkt mit einem Terminal-Programm dargestellt werden können (ASCII-Text).

Neben ein paar Hilfsklassen zur Speicherung der Telegramme, Sammlung der Datenbits, etc. besteht das Programm im wesentlichen aus den drei Hauptkomponenten:

Eine umfangreichere Dokumentation inkl. Klassendiagramm und Erläuterung der Zustandsmaschinen ist im Projekt enthalten (Doxygen) bzw. separat verfügbar (HTML).

Hinweis: das Projekt setzt auf avr-classes auf.

Downloads

Datum Version Datei Beschreibung
2020-01-02 1.0 rc5demo-1.0.zip Demo-Programm (Atmel Studio 7, C++)
rc5demo-doc-1.0.zip Doxygen-Dokumentation (HTML)

Zurück zur Hauptseite