Infrared Remote Control (lirc)

Doing something useful with an infrared port under Linux...

My laptop (from the Acer Aspire 5670 series) has an infrared port at the front side. After several attempts to use it under Linux, I finally got it right. In my current configuration, I can use a remote control (any remote control) to control applications like vlc (a media player). In fact, it is possible to execute any command you like.

Note: the purpose of this page is not to give complete instructions, but rather to write about the problems I encountered. Refer to the following pages for more information:

 


 

Loading the hardware driver

The main piece of software needed is lirc (http://www.lirc.org/). Follow the installation instructions provided with the package, or alternatively, use the installation method provided with your Linux distribution.

Both for manual installation, as for the installation in Gentoo Linux, you will need to select the correct infrared driver. For my infrared port, I could simply select the 'sir' (Serial Infrared) driver, which is a standard protocol. This may work for other devices as well. For a homebrew IR transceiver, select 'serial'. For some specific hardware transceivers, there are separate drivers.

Note: Initially, I had identified the type of infrared chip in my laptop by looking at some of the files that came with the Windows driver for this device (e.g. readme.txt, setup.ini, the .inf file, ...). It turned out to be an SMSC SIO1000 chip. In the Linux kernel, there is an SMSC driver, which I had selected. It is located under the following options:

[*] Networking support  --->
    <M> IrDA (infrared) subsystem support  --->
        Infrared-port device drivers  --->
            <M> SMSC IrCC (EXPERIMENTAL)

However, this driver is not the correct one. IrDA (Infrared Data Association) is a standard for infrared communication, but it is different from CIR (Customer Infrared) that is used for remote control. To be able to control your Linux pc with a remote control, you do not need an IrDA kernel driver.

In order to load the lirc_sir driver successfully, I had to alter some of its parameters. Take a look at the possibilities using the 'modinfo' command (which comes with the modutils package).

# modinfo lirc_sir
filename:       /lib/modules/2.6.28-tuxonice-r4/misc/lirc_sir.ko
license:        GPL
author:         Milan Pikula
description:    Infrared receiver driver for SIR type serial ports
depends:        lirc_dev
vermagic:       2.6.28-tuxonice-r4 SMP preempt mod_unload PENTIUMM 4KSTACKS
parm:           io:I/O address base (0x3f8 or 0x2f8) (int)
parm:           irq:Interrupt (4 or 3) (int)
parm:           threshold:space detection threshold (3) (int)
parm:           debug:Enable debugging messages (bool)

The only parameters that I had to change, were 'io' and 'irq'. Luckily, there are only 4 possible combinations, and only one of them worked for me. The main test to see if you picked the right combination, is the 'mode2' program. If you start the program from the command line, and then press some buttons on any (functioning) remote control while pointer to the receiver, you should see output like:

# mode2
space 16777176
pulse 781
space 933
pulse 1766
space 883
pulse 937
space 905
pulse 869
...

For my infrared chip, I had to use the following combination to lirc_sir to get this output in mode2.

modprobe lirc_sir io=0x2f8 irq=3

One of the problems I faced was the following error message that appeared after loading the driver:
FATAL: Error inserting lirc_sir (/lib/modules/2.6.28-tuxonice-r4/misc/lirc_sir.ko): Device or resource busy
FATAL: Error running install command for lirc_sir

More information can be obtained from the kernel log and by using the debug parameter to lirc_sir.

The problem is that the standard serial ports (/dev/ttySx) use the same IRQ numbers and/or I/O regions:

/dev/ttyS0, UART: unknown, Port: 0x03f8, IRQ: 4
/dev/ttyS1, UART: unknown, Port: 0x02f8, IRQ: 3
/dev/ttyS2, UART: unknown, Port: 0x03e8, IRQ: 4
/dev/ttyS3, UART: unknown, Port: 0x02e8, IRQ: 3

Even though my laptop does not have a (physically accessible) serial port, this was a problem. Therefore, I had to use the setserial application (which I installed) to disable the offending serial port:

setserial /dev/ttyS1 uart none

All of this (the parameters to the lirc driver and disabling of the serial ports) can be automated using the modprobe configuration files. In my (Gentoo-based) system, /etc/modprobe.d/lirc contains the following lines:

options lirc_sir irq=3 io=0x2f8
install lirc_sir    setserial /dev/ttyS1 uart none; modprobe --ignore-install lirc_sir

After modifying this file, I have to run a certain command (update-modules) to apply the modifications.

Creating the necessary configuration files

Ok, so at this point you should have the driver loaded correctly, and you should see pulse/space messages using the mode2 command. If you got this far, you know that the hardware is working.

The remaining steps to being able to control your laptop with a remote are:

  • Creating an /etc/lircd.conf file that describes the remote of your choice
  • Creating an ~/.lircrc file to map certain commands to certain buttons

Describing remotes

The file /etc/lircd.conf contains a list of all the buttons on your remote and how they can be recognized by the hardware. You can either download this file from the LIRC website (at http://lirc.sourceforge.net/remotes/), or you can create your own using the 'irrecord' program. I used the last method and obtained the following file for the remote of my television:

begin remote

  name  TV_remote
  bits           13
  flags RC5|CONST_LENGTH
  eps            30
  aeps          100

  one           864   910
  zero          864   910
  plead         827
  gap          113547
  toggle_bit_mask 0x800

      begin codes
          Power                    0x100C
          Resolution               0x003E
          Menu                     0x0012
          Left                     0x0015
          Right                    0x0016
          Up                       0x0010
          Down                     0x0011
          Teletext                 0x103C
          VolDown                  0x1011
          VolUp                    0x1010
          ProgDown                 0x1021
          ProgUp                   0x1020
          Mute                     0x100D
          Record                   0x002B
          Rewind                   0x002C
          Stop                     0x002D
          Play                     0x002E
          1                        0x1001
          2                        0x1002
          3                        0x1003
          4                        0x1004
          5                        0x1005
          6                        0x1006
          7                        0x1007
          8                        0x1008
          9                        0x1009
          0                        0x1000
          AUX                      0x1038
          NumDigits                0x1023
      end codes

end remote

After you saved this file, you can load the lirc daemon to have it parsed:

/etc/init.d/lircd start

Note: you can add several remote definitions to that file, and you can include other files with the 'include' command. This allows for a clean and simple 'main' configuration file:

include "/etc/lirc/lircd.conf.tv"
include "/etc/lirc/lircd.conf.hifi"

where each of these files contains a 'begin remote / end remote' statement.

You can use the 'irw' command to test the setup. If you start the application and press some buttons on your remote, you should see the names of the buttons you assigned.

Map commands to buttons

Finally, you can create the file ~/.lircrc that will determine the actions for certain buttons. A very simple file that will print 'something' on the console, is:

begin
        button=Power
        prog=irexec
        config=echo something
end

'irexec' acts as a client to lirc, and can execute any command you specify. For example, the below configuration will launch the application 'kcalc' when pressing button '2' on the remote:

begin
        button=2
        prog=irexec
        config=kcalc
end

To test it out, run the lirc client:

irexec

on the command line and press the buttons on your remote. When everything works, you can call it from a startup script with the --daemon parameter.

Remote controlling the VLC media player

vlc can act as an lirc client itself and does not need the 'irexec' client. Enable the lirc control interface via Tools - Preferences - (show all settings) - Interface - Control interface - Infrared remote control interface. You can verify this setting in the vlc configuration file (which used to be ~/.vlc/vlcrc but is now ~/.config/vlc/vlcrc):

control=lirc

Alternatively, you can specify the control parameter explicitly when running vlc:

vlc --control lirc

Here is the ~/.lircrc file that I use to control the VLC media player:

begin
        button=Power
        prog=vlc
        config=key-quit
end
begin
        button=TV-VCR
        prog=vlc
        config=key-toggle-fullscreen
end
begin
        button=VolDown
        prog=vlc
        config=key-vol-down
        repeat=1
end
begin
        button=VolUp
        prog=vlc
        config=key-vol-up
        repeat=1
end
begin
        button=Play
        prog=vlc
        config=key-play-pause
end
begin
        button=Stop
        prog=vlc
        config=key-stop
end
begin
        button=Prev
        prog=vlc
        config=key-prev
end
begin
        button=Next
        prog=vlc
        config=key-next
end
begin
        button=Rewind
        prog=vlc
        config=key-jump-short
end
begin
        button=FastForward
        prog=vlc
        config=key-jump+short
end
begin
        button=Pause
        prog=vlc
        config=key-pause
end
begin
        button=Left
        prog=vlc
        config=key-nav-left
end
begin
        button=Right
        prog=vlc
        config=key-nav-right
end
begin
        button=Up
        prog=vlc
        config=key-nav-up
end
begin
        button=Down
        prog=vlc
        config=key-nav-down
end
begin
        button=Teletext
        prog=vlc
        config=key-nav-activate
end
begin
        button=Resolution
        prog=vlc
        config=key-toggle-fullscreen
end
begin
        button=Mute
        prog=vlc
        config=key-vol-mute
end
begin
        button=Menu
        prog=vlc
        config=key-disc-menu
end
begin
        button=ProgUp
        prog=vlc
        config=key-jump+short
        repeat=2
end
begin
        button=ProgDown
        prog=vlc
        config=key-jump-short
        repeat=2
end

Use the command 'vlc --help' to see all possible commands.

If you now start vlc and load an audio or video file, you should be able to use your remote to control it.

Troubleshooting

If something does not work, verify the following:

  • Is the lirc driver loaded correctly? Use the 'lsmod' and 'mode2' commands.
  • Is the lirc daemon loaded correctly? Try restarting it using '/etc/init.d/lircd restart'
  • Do you have a valid /etc/lircd.conf file describing your remote? Use the 'irw' command.
  • Verify whether an lirc client is running (either irexec, or vlc, or...). The lirc daemon prints the following message when a new client presents itself: "accepted new client on /var/run/lirc/lircd" (see /var/log/messages or the appropriate log file for your system)
  • Do you have a valid ~/.lircrc file? Try a simple 'echo' command with irexec first
  • If you can print something with the echo command, but do not get vlc remote control working, verify whether the lirc control interface is correctly loaded. Use vlc's verbosity parameter to see what's going on (vlc -v2)