While LIRC could be useful for some, many will just want to use an IR
remote control with software designed for that purpose such as Kodi. In that case, LIRC will not be needed if the remote
control uses one of the following IR protocols: rc-5, rc-5-sz, jvc, sony,
nec, sanyo, mce_kbd, rc-6, sharp, and xmp. The ir-keytable
utility contains over 130 remote control definitions and can be used to craft
one if the IR remote is not among that list.
Table of Contents
- Media Centre Remote
- The
ir-keytable
utility. - Managing Key Tables
- The Broken
udev
Rule - The ir-keytable Configuration File
rc_maps.cfg
- Automatic Configuration
- Conclusion
Media Centre Remote
In a pile of old IR remote controls I found a Window Media Centre
remote from HP along with a USB IR receiver. Of course there is no need for
the latter given that the Orange Pi Zero has an IR receiver. Inside the
battery compartment of the remote control, it says that it uses IR protocol
RC6 which I believe is the case for all remotes used with WMC.
Time to test that it works after many years of disuse. First I checked
that the input event is still event0
. Then I set the protocol to
RC-6, and checked for events as I pressed a key on the remote.
So the scan code of button "1" is 0x800f0401. There are numerous buttons
on that remote, I would not relish mapping all of them to key codes. Enter
ir-keytable
, "a swiss-knife tool to handle Remote Controllers"
as its man page says.
Installation and Use of ir-keytable
The package is not present in the Armbian image but is easily added in the usual fashion since it is in the repository.
In addition to the program itself, numerous files were installed including
remote definitions in /lib/udev/rc_keymaps
, associated kernel objects in
/lib/modules/4.19.17-sunxi/kernel/drivers/media/rc/keymaps/
,
a udev
rule, a configuration file and an empty directory.
That is a bit overwhelming but it is manageable with the help of
many documents found on the Web and the utility's man
page. As an initiation, let us look at interactive use of the utility.
Running the program without any command line parameters displays information about the current drivers, devices, protocols and so on.
IR protocols can be set.
Note the need for root
privileges. The -p
(long
form: --protocol
) does not have the flexibility of my
irp
bash script but it does have the ability to set all
protocols at once which is good to test the compatibility of an unknown
remote control.
While one would not want to do this for all the keys on a MCE remote, it
is possible to set the key codes for scan codes with
ir-keytable
and then to display received scan codes and
corresponding key codes if available.
The "1", "2" and "3" buttons were pressed in succession. The
-k
option was used to set key codes (strings such as "KEY_1"),
for the first two buttons and these are echoed by the utility. Only the scan
code is shown for the third button. Note also how key_down
and
key_up
events of type EV_KEY
are reported with the
translated key codes.
In this mode, ir-keytable
can be seen as the replacement of
the LIRC irw
program.
The HP remote control sends a scan code repeatedly if a button is held down for any length of time. The "3" button was held down for a relatively long period and as can be seen the scan code were repeated at a very steady frequency of 10 per second.
Independently of the remote control repeat capabilities, the kernel
repeats key codes if they are defined with ir-keytable
. It does
not repeat scan codes. The default values are a 1/2 second (500 ms) delay and
a 1/8 second (125 ms) repeat period. These are typical keyboard delays. The
following table shows the time intervals between scan codes and key codes when
the "1" button was held down for 3 seconds. The synchronization events
EV_SYN
were removed to obtain a clearer picture. The first
column is the ir-keytable
time stamp. The fifth column
EV_* delta
is the time interval in milliseconds between
successive events whether they are scan codes from the remote control or key
codes. The last column, EV_KEY delta
contains the time intervals
between EV_KEY
codes. Since the repeat period of the key codes
is 125 ms and the repeat period of the remote control is 100 ms, most times
there is only one scan code between two key codes, but occasionnaly there are
two. The exception is at the start because of the 500 ms delay before the
first time the key code is repeated.
Timestamp | Event | Type | Code | Delta EV_* | Delta EV_KEY |
---|---|---|---|---|---|
1549903838.71569 | EV_MSC(0x04) | scancode | 0x800f0401 | ||
1549903838.71569 | EV_KEY(0x01) | key_down | KEY_1(0x0002) | ||
1549903838.82179 | EV_MSC(0x04) | scancode | 0x800f0401 | 106 | |
1549903838.92789 | EV_MSC(0x04) | scancode | 0x800f0401 | 106 | |
1549903839.03404 | EV_MSC(0x04) | scancode | 0x800f0401 | 106 | |
1549903839.14021 | EV_MSC(0x04) | scancode | 0x800f0401 | 106 | |
1549903839.24636 | EV_MSC(0x04) | scancode | 0x800f0401 | 106 | |
1549903839.24705 | EV_KEY(0x01) | key_down | KEY_1(0x0002) | 1 | 531 |
1549903839.35254 | EV_MSC(0x04) | scancode | 0x800f0401 | 105 | |
1549903839.37905 | EV_KEY(0x01) | key_down | KEY_1(0x0002) | 27 | 132 |
1549903839.45869 | EV_MSC(0x04) | scancode | 0x800f0401 | 80 | |
1549903839.51104 | EV_KEY(0x01) | key_down | KEY_1(0x0002) | 52 | 132 |
1549903839.56487 | EV_MSC(0x04) | scancode | 0x800f0401 | 54 | |
1549903839.64305 | EV_KEY(0x01) | key_down | KEY_1(0x0002) | 78 | 132 |
1549903839.67109 | EV_MSC(0x04) | scancode | 0x800f0401 | 28 | |
1549903839.77505 | EV_KEY(0x01) | key_down | KEY_1(0x0002) | 104 | 132 |
1549903839.77717 | EV_MSC(0x04) | scancode | 0x800f0401 | 2 | |
1549903839.88333 | EV_MSC(0x04) | scancode | 0x800f0401 | 106 | |
1549903839.90704 | EV_KEY(0x01) | key_down | KEY_1(0x0002) | 24 | 130 |
1549903839.98951 | EV_MSC(0x04) | scancode | 0x800f0401 | 82 | |
1549903840.03905 | EV_KEY(0x01) | key_down | KEY_1(0x0002) | 50 | 132 |
1549903840.09567 | EV_MSC(0x04) | scancode | 0x800f0401 | 57 | |
1549903840.17105 | EV_KEY(0x01) | key_down | KEY_1(0x0002) | 75 | 132 |
1549903840.20184 | EV_MSC(0x04) | scancode | 0x800f0401 | 31 | |
1549903840.30305 | EV_KEY(0x01) | key_down | KEY_1(0x0002) | 101 | 132 |
1549903840.30798 | EV_MSC(0x04) | scancode | 0x800f0401 | 5 | |
1549903840.41415 | EV_MSC(0x04) | scancode | 0x800f0401 | 106 | |
1549903840.43504 | EV_KEY(0x01) | key_down | KEY_1(0x0002) | 21 | 127 |
1549903840.52032 | EV_MSC(0x04) | scancode | 0x800f0401 | 85 | |
1549903840.56705 | EV_KEY(0x01) | key_down | KEY_1(0x0002) | 47 | 132 |
1549903840.62648 | EV_MSC(0x04) | scancode | 0x800f0401 | 59 | |
1549903840.69904 | EV_KEY(0x01) | key_down | KEY_1(0x0002) | 73 | 132 |
1549903840.73265 | EV_MSC(0x04) | scancode | 0x800f0401 | 34 | |
1549903840.83105 | EV_KEY(0x01) | key_down | KEY_1(0x0002) | 98 | 132 |
1549903840.83879 | EV_MSC(0x04) | scancode | 0x800f0401 | 8 | |
1549903840.94495 | EV_MSC(0x04) | scancode | 0x800f0401 | 106 | |
1549903840.96304 | EV_KEY(0x01) | key_down | KEY_1(0x0002) | 18 | 124 |
1549903841.05119 | EV_MSC(0x04) | scancode | 0x800f0401 | 88 | |
1549903841.09505 | EV_KEY(0x01) | key_down | KEY_1(0x0002) | 44 | 132 |
1549903841.15729 | EV_MSC(0x04) | scancode | 0x800f0401 | 62 | |
1549903841.22704 | EV_KEY(0x01) | key_down | KEY_1(0x0002) | 70 | 132 |
1549903841.26346 | EV_MSC(0x04) | scancode | 0x800f0401 | 36 | |
1549903841.35905 | EV_KEY(0x01) | key_down | KEY_1(0x0002) | 96 | 132 |
1549903841.3696 | EV_MSC(0x04) | scancode | 0x800f0401 | 11 | |
1549903841.47578 | EV_MSC(0x04) | scancode | 0x800f0401 | 106 | |
1549903841.49105 | EV_KEY(0x01) | key_down | KEY_1(0x0002) | 15 | 121 |
1549903841.58194 | EV_MSC(0x04) | scancode | 0x800f0401 | 91 | |
1549903841.62306 | EV_KEY(0x01) | key_down | KEY_1(0x0002) | 41 | 132 |
1549903841.75504 | EV_KEY(0x01) | key_down | KEY_1(0x0002) | 132 | 173 |
1549903841.81905 | EV_KEY(0x01) | key_up | KEY_1(0x0002) | 64 |
The key code delay and repeat period can be modified with the
-D
and -P
options.
Finally, evdev
reports both scan codes and key codes
when the latter are defined. In the session shown below, first the
"3" button is pressed. Recall its key code has not been defined. Then
the "2" and "1" button are pressed, and their key code is reported
in addition to the scan code.
Managing Key Tables
Perhaps the main function of ir-keytable
is its ability
to manage translations from scan code to key codes stored in files.
As stated above, quite a few IR remote definitions were included in
the ir-keytable
package. They are found in the
/lib/udev/rc_keymaps
directory. Among them there is one for
RC6 remotes: rc6-mce
. The command to load that scan to key code
translation file is simple.
The key codes contained in the file were added to those already used
by the kernel. To see the current entries use the -r
(long form: --read
) option.
The KEY_COFFEE
entry is not part of the rc6_mce
definition. There is a clear option (-c
or --clear
)
which can be used alone for the obvious purpose of removing all current
scan to key code entries from the kernel module. In combination with
the write option (-w
or --write
) we have an
replace operation.
The utility knows which IR protocol to set because it is specified in the first line of remote definition file.
It is possible to override the protocol definition with the -p
(long form: --protocol
) command line parameter. We shall see that
this is quite useful later on. The sudo
prefix must be used when
the -w
or -p
option is used since the protocol
is being set.
It is bad form to load the remote definition file directly from the
/lib/udev/rc_keymaps/
directory. Instead, for good reasons, it
should be done from the /etc/rc_keymaps
directory. If the file
included in the ir-keytable
package contains a correct
definition, create a symbolic link in the /etc/rc_keymaps
directory.
If the original keymap needs to be changed, copy the file to the
/etc/rc_keymaps
directory, modify it as needed and load its
modified content with the same command as above. If a new keymap file is to
be created for an IR remote, place it in the /etc/rc_keymaps
directory. That is precisely what I did to use the KEYES remote.
The following command adds that definition so that both remotes
can be used. Note how two IR protocols were specified on the
command line. That was necessary because without the -p
option, ir-keytable
would have set the protocol to
nec
only based on the first line of the keyes
file.
As can be seen, key code KEY_NUMERIC_1
is transmitted by
the kernel, first in response to the scan code 0x800f0401
from the HP remote using the RC-6 protocol and again after receiving the
0x16
scan code via the NEC protocol from the KEYES remote.
The Broken udev Rule
The installation of ir-keytable
included a udev
rule. If like me you are not familiar with udev
, I recommend the
Debian documentation udev - the Linux dynamic
device management module which I found surprisingly understandable. Kudos
to the author. Here is the rule which in effect loads a configuration file.
The rule is broken at least on the Orange Pi Zero.
I take this to mean that the IR receiver is recognized by
udev
but ir-keytable
raises a segmentation error
which is sometimes indicative of a missing file. This can be checked by
modifying the rule.
After rebooting
It looks like the symbolic link rc0
is not yet created when
the rule is executed. Perhaps the directory /sys/devices/platform/soc/1f02000.ir/rc/rc0
does exist, so I renamed the rule so that it be the last to be executed
and changed it slightly.
The result was just as disappointing. It looks like it will be necessary
to resort to a task
at boot time to initialize the IR driver
properly.
The ir-keytable Configuration File rc_maps.cfg
The -a
option is used to load a configuration file,
rc_maps.cfg
as found in the udev
rule. Just how the
configuration file is supposed to work is mysterious for some including me.
Here is part of it.
A simple try will show that, contrary what is written in the header,
ir-keytable -a will not run. The full path to
the configuration file must be specified. And
ir-keytable -a /etc/rc_maps.cfg (with or
without the sudo
prefix) does nothing.
To experiment, I removed all entries in the driver table except for the one for the RC6 remote. Trying ir-keytable -a /etc/rc_maps.cfg did nothing with that single entry, but changing the entry to
or
does work.
That is progress. Note that anything where a kernel object, with or
without the .ko
extension and with or without a full path does
not work. However it does not seem to be possible to load two remote control
definitions with the configuration file. I tried listing the desired
translation files (with or without sunxi-ir
driver specified).
This does not work, ir-keytable
stops as soon as it has
loaded the first file.
Automatic Configuration
Given the last two sections, here is how the IR stack is initialized
when the Orange Pi Zero is booted if only one remote control is used. First
add the name of the definition file in /etc/rc_keymaps
to the
/etc/rc_maps.cfg
file as shown below.
Then create a task to be performed at boot time by cron
.
That should work!
If two or more IR remote definitions are to used then it will be
necessary to forego the rc_maps.cfg
file all together. The
task to perform at boot time will be a bit more complex.
This might seem like a strange thing, but it appears that the commands
are executed in reverse order. The second line adds the keyes
table and writes any output or error to the temporary log file. After, the
command in the first line is executed. It adds the rc6_mce
table, sets both needed IR protocols and appends any output or error message
to the log file.
I am a bit uncomfortable with that situation, so I prefer creating a simple bash script where the order of execution is clear.
The .profile
configuration file will add the ~/bin
directory to the search path, so bash
will find the script
file. Here is its content.
Do not forget the "shebang" (the first comment) is mandatory if the file is to be self executing. But it is also necessary to mark it as an executable.
Now all that needs to be done is to add it to the crontab
file.
Conclusion
I am sorry that these three notes on IR remotes with the Orange Pi Zero are a bit of a mess. This one should really have been the second, as many will never have to use LIRC.
Hopefully, when I translate these posts into French, I will clean up the mess. Then I can translate that text back into English coming up with something perhaps more coherent.
Here are some of the documents consulted to get here.
- Infrared Remotes
- LibreELEC, last modified 5 weeks ago
- MythTV: Use All Buttons of Your Remote Control - Without LIRC
- Richard Atterer, 2013-04-21
- ir-keytable or: How I Learned to Stop Worrying about the LIRC Kernel
- dakscout on Ubuntu forums, May 2009
- 3.3. Remote Control
- in yaVDR Documentation, Marcus Zurhost, October 2012