PC fernsteuern mittels alter Fernbedienung und LIRC

Das Projekt LIRC (http://www.lirc.org) (Linux InfraRed Control) erlaubt das Fernsteuern des PCs mittels einer alten Fernbedienung. Dazu benötigt man etwas Hardware, die das IR-Signal aufbereiten und an den PC weitergibt sowie die Software, die aus dem Signal die Tastendrücke auf der Fernbedienung erkennt und auf irgendwelche Kommandos (Programmaufrufe, GUI-Steuerungen von Programmen) abbildet.

Die Hardware kann ganz unterschiedlich sein, je nachdem, über welche Schnittstelle man gehen will (seriell, parallel, USB). Die meiner Meinung nach einfachste Schaltung ist die serielle Anbindung, die auch unter www.lirc.org abgebildet ist. Leider haben neuere Notebooks und sogar Desktop-Rechner oft nur noch USB …

Hardware

Die oben erwähnte einfachste Schaltung habe ich nachgebaut. Nach einer dort genannten Idee habe ich die Schaltung in einer alte Maus eingebaut, die nun auf meinem Computer steht. Man entfernt die alte Elektronik und bricht alle Plastikstege etc. weg, die stören. Vorne wird ein Loch eingefeilt, in welches man den Sensor stecken und hinten ankleben kann.


Der Sensor (rechts) sowie die serielle Anbindung im Mausgehäuse

Bei der Hardware ist zu beachten, dass die Versorgungsspannung vom RTS-Signal der RS232-Schnittstelle abgeleitet wird. Unterschiedliche PCs geben da aber unterschiedliche Spannungen ab, insbesondere bei Notebooks kann es sein, dass die Spannung nicht ausreicht. Ich habe verschiedene Messungen gemacht:

Die Schaltung wurde testweise an ein regelbares Netzteil angeschlossen (RTS als +, GND für 0V) und der Signalausgang (DCD) an ein Oszilloskop. Ich habe die Spannung dann variiert und geschaut, was die Schaltung tut:

  1. Die Schaltung arbeitet bei +5V Signalhöhe an RTS nicht. D.h. ein Drücken einer Taste auf der Fernbedienung führt zu keinerlei Reaktion am Signalausgang DCD.
    Die Schaltung arbeitet unzuverlässig bei +6V Signalhöhe an RTS. D.h. ein Drücken einer Taste auf der Fernbedienung führt zu Signalausschlägen am Signalausgang DCD, die man im Oszilloskop sehen kann (Zeitbasis auf 2 Mikrosekunden eingestellt, Y auf 2 Volt pro Skalenstrich).
    Die Schaltung arbeitet zuverlässig bei +7V Signalhöhe an RTS. Dann stehen am Ausgang des Regel-ICs 78L05 4,5 Volt an.
  2. Die Schaltung arbeitet zuverlässig bei +7,5V Signalhöhe an RTS. Ab dieser Spannung stehen am Ausgang des Regel-ICs 78L05 4,98 Volt an, d.h. der Regler kann ab hier die Spannung nicht nur durchleiten, sondern auch regeln.

Ein Anschluss an ein Motherboard ASRock P4V88 bringt 8,49V an RTS, damit ist der Betrieb der Schaltung also sehr gut möglich. Ein Anschluss an ein Notebook Dell Latitude C600 bringt 5,49V an RTS, damit ist der Betrieb nicht möglich (habe es erfolglos probiert).

Software

Das lirc-Paket war unter Suse 10.0 bereits installiert, desweiteren ein lirc-fähiger mplayer/gmplayer. Unter OpenSuese musste ich die Kernel-Module für den seriellen Port (in Yast nach lirc suchen) installieren. Der gmplayer muss u.U. erst mit lirc-Support übersetzt werden. Wenn mplayer/gmplayer mit lirc support compiliert wurde kommt folgende Ausgabe beim Start:

— Setting up LIRC support… —

In der Datei /etc/lircd.conf müssen Daten zur Fernbedienung abgelegt werden. Diese müssen mittels irrecord ermittelt werden. Ausgangsbasis für die eigene Fernbedienung sollte eine ähnliche Fernbedienung sein, denn unter www.lirc.org sind für viele Fbs schon passende Dateien vorhanden. Diese als Inputdatei für irrecord nehmen. Nach „Anlernen“ der Fernbedienung dann die Datei unter /etc/lircd.conf ablegen.

Unter /etc/sysconfig/lirc sind die grundlegenden Infos für lirc abzulegen, bei mir z.B.:

LIRCD_DRIVER="default"
LIRCD_DEVICE="/dev/lirc"
COM_PORT=/dev/ttyS0
LIRC_MODULE="lirc_dev lirc_serial"

Unter /etc/init.d/boot.local kann lirc dann bei jedem Booten initialisiert werden:

setserial /dev/ttyS0 uart none
modprobe lirc_serial sense=1
rclirc start

Die Daten müssen durch Probieren ermittelt werden, diverse Tutorials im Netz helfen hier etwas. setserial kann bei openSuse mittels Yast nachinstalliert werden.

Fürs Probieren gilt:

Bevor man in den genannten Dateien was ändert, alles per Hand solange ausprobieren bis es funktioniert. Erst dann das Ergebnis in /etc/sysconfig/lirc und /etc/init.d/boot.local verewigen.

  1. Zuerst die korrekte Schnittstelle für setserial ermitteln.
  2. Dann das passende Modul (passend zur Hardware) auswählen, bei mir lirc_serial und lirc_dev. Bei modprobe muss ein active low-Receiver als active low erkannt werden, statt active high. Der aus der Nachbauanleitung bei www.lirc.org ist active low. Die Ausgabe beim Laden des Moduls ist bei mir:
    lirc_dev: IR Remote Control driver registered, at major 61
    lirc_serial: Manually using active low receiver
    lirc_dev: lirc_register_plugin: sample_rate: 0
  3. Grundlegenden Test mittels xmode2 oder mode2. Hiermit werden empfangene Signale (Highs und Lows) ausgegeben. Wenn da etwas kommt, klappt die physikalische Anbindung. Wenn der lircd läuft, funktionieren diese beiden Testprogramme nicht.
    Dateien unter /etc anpassen, testen ob nach boot mode2 noch tut.
  4. lircrc erweitern für eigene Anwendungen, testen

Ausgabe von mode2 als root beim Drücken irgendwelcher Tasten:

soc:/home/dennis # mode2
 space 16777215
 pulse 972
 space 810
 pulse 1861
 space 813
 pulse 970
 space 811
 pulse 971
 space 1700
 pulse 1861
 space 1703
 pulse 1861
 space 813
 pulse 967
 space 812
 pulse 970
 space 1702
 pulse 972
 space 812
 pulse 1860
 space 90778
 pulse 972
 space 812
 pulse 1862
 space 809
 pulse 973
 space 809

Die graphische Ausgabe von xmode2:


Ausgabe von xmode2 beim Drücken von Tasten der Fernbedienung

Ein simpler Eintrag für lircrc ist

begin
remote = philips_rt150-211
button = Select
prog = irexec
repeat = 0
config = echo "Hello world!"
end

wobei remote Ihre Fernbedienung wie in lircd.conf bezeichnet, button den Namen eines Buttons wie in lircd.conf genannt ist. irexec ist Teil des lirc-Pakets. In der Shell, in der der lircd gestartet wurde, wird nun der String „Hello world!“ ausgegeben.

Ein konkretes Kommando für meine Fernbedienung und das Programm mplayer ist z.B.:

begin
remote = philips_rt150-211
button = Still
prog = mplayer
repeat = 0
config = pause
end

wobei pause ein Kommandoname ist, der durch das mplayer-Team so vorgegeben wurde. Mplayer besitzt noch dutzende andere solche Kommandos (siehe Dokumentation Mplayer).

LIRC auf neuem Gigabyte Motherboard (Gigabyte GA-G33-DS3R)

Dieses neuere Motherboard (2007) besitzt keine serielle Buchse an der Rückseite. Es hat aber immerhin einen „Header“ auf dem Board, an den man ein hinzugekauftes RS232 Slotblech mit Kabel anschließen kann.

Tests mit diesem Motherboard haben bisher allerdings ergeben, dass das oben beschriebene Gerät nicht funktioniert, da das Motherboard die serielle Schnittstelle seltsam ansteuert: An RTS liegen immer ~11 Volt negativ an, sie werden auch nicht vom lirc_serial Treiber auf einen positiven Wert (wie das eigentlich sein sollte) umgeschaltet. Mit einer negativen Spannung funktioniert die Elektronik natürlich nicht. Ich habe probeweise externe +10V angelegt, dann funktioniert der Empfänger wieder. Leider wird mittels mode2 aber nichts erkannt. Also auch am Eingangspin geschehen merkwürdige Sachen. Googeln im Internet zeigt, dass das bei manchen Boards vorkommt.

Update: Nach ausführlichem Suchen habe ich das Problem lösen können: Das hinzugekaufte RS232 Slotblech (von Conrad) ist nicht 1:1 beschaltet. Durch Messen hat sich folgende Beschaltung ergeben:

RS 232 Buchse (male) am Slotblech  Buchse des Slotblechkabels
1 1
2 3
3 5
4 7
5 9
6 2
7 4
8 6
9 8

Das kann natürlich nicht funktionieren. Die Verpackung des Slotblechs gab darauf keinerlei Hinweise, eine Gebrauchsanweisung war ohnehin nicht dabei. Das Kabel lässt sich aber einfach umlöten, so dass 1 an 1, 2 an 2, 3 an 3 etc. hängt. Das habe ich gemacht, und der Anschluss funktioniert jetzt wunderbar.

Serielle und parallele PCI-Karte unter Linux (OpenSuse)

Neuere Computer haben oft weder serielle noch parallele Anschlüsse.

Zum Teil kann man sich mit Kabel behelfen, die USB auf den passenden Port umsetzen.

Das USB-Seriell-Kabel ist für „normale“ Nutzung des seriellen Anschlusses gut geeignet. Eine Nutzung zur Übertragung von Programmierdaten zur Programmierung von Atmel Microcontrollern ist mit diesen Kabeln nicht zu empfehlen. Außerdem braucht man, wenn man zusätzlich RS232 braucht, schon mal zwei Kabel…

Bleibt die Alternative PCI-Karte. Diese gibts für seriell, parallel und gemischt. Sie bieten z.B. 1-4 serielle Anschlüße oder 1 seriellen und 1 parallelen Anschluß. Die PCI-Karten werden typischerweise sauber vom Standard-Linux-Kernel erkannt. möglicherweise gibt es mittlerweile auch PCIe-Karten, habe dies aber nicht untersucht.

Im folgenden beschreibe ich die etwas holprige Inbetriebnahme meiner Billigkarte, die ich für 15 Euro bei www.pollin.de bezogen habe. Name: LogiLinkPCI Multi I/O Controller Card. Sie besitzt zwei serielle Schnittstellen.

Diese Karte besitzt einen MosChip 9835 Chip. Dieser kann von Linux angesprochen werden. Viele heutige Chips sind zum Ur-Standard 16550 Chip kompatibel.

Wenn die Karte eingebaut wurde, kann man in /var/log/boot (neuer: /var/log/boot.msg) oder auch in der Ausgabe von dmesg nach dem String „tty“ suchen, bei mir kam nach dem Einbau der Karte folgende Ausgabe:

socraggio:/home/dennis # grep tty /var/log/boot.msg
 <6>[    0.000102] console [tty0] enabled
 <6>[    0.652034] serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
 <6>[    0.652421] 00:06: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
 <6>[    0.652743] 0000:05:00.0: ttyS4 at I/O 0xd000 (irq = 20) is a 16550A
 <6>[    0.652854] 0000:05:00.0: ttyS5 at I/O 0xd100 (irq = 20) is a 16550A

Die erste erkannte Schnittstelle (ttyS0) ist die des Motherboards. Diese habe ich über ein Slotblech von außen erreichbar gemacht, denn das Gigabyte-Motherboard hat hierfür keinen Stecker mehr, sondern nur einen „Header“, also einen 10-poligen Anschluss auf dem Board. An diesen kann man dann einen Stecker, der in einem Slotblech montiert ist und mit einem passenden Kabel geliefert wird, anschließen. Achtung, es gibt Kabel mit unterschiedlichen Belegungen. Bei meinem Board wird eine 1:1 Belegung verlangt. Das Slotblech+Kabel habe ich bei www.conrad.de für ca. 5 Euro erstanden. Genaueres zu diesem Slotblech habe ich hier beschrieben.

Die Ports der PCI-Karte werden als ttyS4 und ttyS5 eingebunden.

Die PCI-Karte sollte nun mittels „lspci“ zu finden sein. In folgender Ausgabe weiß der Kernel nichts mit der Karte anzufangen:

lspci -v
 ....
 04:01.0 Class Class ffff: Illegal Vendor ID Unknown device ffff (rev ff) (prog-if ff)
 !!! Unknown header type 7f
 ...

Ich wechsle den PCI-Port und entferne eine überflüssige Soundkarte. Zunächst gibts noch Probleme, die Karte wird nur zum Teil erkannt:

lspci -v
 ...
 04:01.0 Serial controller: NetMos Technology PCI 9835 Multi-I/O Controller (rev ff) (prog-if ff)
 !!! Unknown header type 7f
 ...

Ich update das File /usr/share/pci.ids. Unter OpenSuse geht dies mittels update-pciids. In diesem File findet sich nach dem Update folgender Eintrag:

 ...
 9710  NetMos Technology
 9250  PCI-to-PCI bridge [MCS9250]
 9805  PCI 1 port parallel adapter
 9815  PCI 9815 Multi-I/O Controller
 1000 0020  2P0S (2 port parallel adaptor)
 9820  PCI 9820 Multi-I/O Controller
 9835  PCI 9835 Multi-I/O Controller
 1000 0002  2S (16C550 UART)
 1000 0012  1P2S
 9845  PCI 9845 Multi-I/O Controller
 ...

Die 9835 steht also drin und Linux weiß, dass die Karte 16550-kompatibel ist.
(Ich habe hier auch noch die NetMos 9845 herumliegen, mit 4 seriellen Ports, die ist wunderbarerweise auch in der pci.ids enthalten).

Nun geht es besser:

lspci -v
 ...
 04:01.0 Serial controller: NetMos Technology PCI 9835 Multi-I/O Controller (rev 01) (prog-if 02 [16550])
 Subsystem: LSI Logic / Symbios Logic 2S (16C550 UART)
 Flags: medium devsel, IRQ 19
 I/O ports at d500 [size=8]
 I/O ports at d600 [size=8]
 I/O ports at d700 [size=8]
 I/O ports at d800 [size=8]
 I/O ports at d900 [size=8]
 I/O ports at da00 [size=16]
 ...

Ein lspci -vv bringt noch mehr Infos, u.a. den verwendeten Kernel-Treiber (Hinweis: lspci wurde auf einer anderen Maschine ausgeführt, daher leichte Abweichungen zu oben):

...
 04:01.0 Serial controller: NetMos Technology PCI 9835 Multi-I/O Controller (rev 01) (prog-if 02 [16550])
 Subsystem: LSI Logic / Symbios Logic 2S (16C550 UART)
 Control: I/O+ Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
 Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
 Interrupt: pin A routed to IRQ 20
 Region 0: I/O ports at d000 [size=8]
 Region 1: I/O ports at d100 [size=8]
 Region 2: I/O ports at d200 [size=8]
 Region 3: I/O ports at d300 [size=8]
 Region 4: I/O ports at d400 [size=8]
 Region 5: I/O ports at d500 [size=16]
 Kernel driver in use: serial
...

Die Karte wird in voller Schönheit erkannt.
Danach kann man über /dev/ttyS* die Ports ganz normal ansprechen. Ich hänge an das ttyS0 den AVR Programmer und an das ttyS4 den RS232 Anschluss des AVR Experimentierboards.

Das RS232-Kabel muss bei der Verbindung mit einem AVR-Microcontroller  wie folgt beschaltet werden:
Pin 2 – RxD <-> Pin 2 RxD
Pin 3 – TxD <-> Pin 3 TxD
Pin 5 – Gnd <-> Pin 5 Gnd
also kein Kreuzkabel, sondern eine 1:1-Verbindung.

Nutzung von kermit

Mittels kermit (http://www.columbia.edu/kermit, unter OpenSuse 11.0 per YasT installierbar, ab 11.1 muß man sich das Paket woanders beschaffen, z.B. hier: http://fr2.rpmfind.net//linux/RPM/opensuse/11.1/x86_64/ckermit-8.0.211-95.58.x86_64.html) kann man nun mit dem Board kommunizieren. Kermit hatte ich zuletzt etwa 1995 verwendet, der Methusalem läuft aber immer noch…
Ich habe übrigens auch minicom probiert, die seltsame Oberfläche hat mich aber vertrieben.

Die Initialisierung von Kermit kann man per Hand machen oder auch in der Datei ~/.kermrc:

dennis@soc:~> cat .kermrc
 set line /dev/ttyS2
 set speed 19200
 set carrier-watch off
 set handshake none
 set flow-control none
 robust
 set file type bin
 set file name lit
 set rec pack 1000
 set send pack 1000
 set window 5

Mir gelingt es bisher nicht das BREAK-Signal in der Kermit-Session zu senden, was aber zu verschmerzen ist.

Parallele PCI-Karte unter Linux

Hier habe ich ebenfalls eine NoName-Karte mit einem NetMos-Chip verwendet. Die Karte beherrscht alle üblichen Betriebsmodi (SPP, EPP, ECP) und wird von Linux ebenfalls sauber erkannt und eingebunden.
Mittels dmesg findet man folgende Zeilen:

...
 [    2.598317] PCI parallel port detected: 9710:9805, I/O at 0xc150(0xc140), IRQ 19
 [    2.598394] parport0: PC-style at 0xc150 (0xc140), irq 19, using FIFO [PCSPP,TRISTATE,COMPAT,ECP]
 [    2.681695] ppdev: user-space parallel port driver
 ...

Das Port ist dann unter /dev/parport0 ansprechbar.

Berechtigungen

Für die verwendeten Devices muss der ansprechende Nutzer die passenden Rechte verfügen. Z.B. gehört /dev/parport0 bei mir root und der Gruppe lp. Ich habe daher meinen User der Gruppe lp hinzugefügt.
Je nach Linux-Flavour (OpenSuse, Redhat,…) können die Gruppen anders heißen, also selbst nachsehen.

Besonderheit mit kermit: Mit OpenSuse 11.3 (und wohl auch bei neueren Versionen)  es beim unbedarften Start von kermit eine Fehlermeldung der Art
„/var/lock
Sorry, write access to UUCP lockfile directory denied.“
Dies ist ein Rechteproblem, das Verzeichnis /var/lock gehört User root und Gruppe root. Vermutlich kann man kermit dazu überreden, keinen Lock erzeugen zu wollen o.ä. Ich habe mir es einfach gemacht und die Situation mittels „chown -R root:users /var/lock“ geklärt.