Reading an IR Remote on a Raspberry Pi Stretch with LIRC (Shallow Thoughts)

Akkana's Musings on Open Source Computing and Technology, Science, and Nature.

Sun, 26 Nov 2017

Reading an IR Remote on a Raspberry Pi Stretch with LIRC

I wrote earlier about how to use an IR remote on Raspbian Jessie.

It turns out several things have changed under Raspbian Stretch.

Update, August 2019:
Apparently these updated instructions don't work any more either. What apparently works now:

In /boot/config.txt, add:

dtoverlay=gpio-ir,gpio_pin=18

In /etc/lirc/lirc_options.conf, add:

driver=default
device = /dev/lirc0

/etc/modules and /etc/lirc/hardware.conf/ don't need to be changed. Thanks to Sublim21 on #raspberrypi for the tip.

Here's the older procedure and discussion.

Here's the abbreviated procedure for Stretch:

Install LIRC

$ sudo apt-get install lirc

Enable the LIRC Overlay

Eedit /boot/config.txt as root, look for this line and uncomment it:

# Uncomment this to enable the lirc-rpi module
dtoverlay=lirc-rpi
Or if you prefer to use a pin other than 18, change the pin assignment like this:
# Uncomment this to enable the lirc-rpi module
dtoverlay=lirc-rpi,gpio_in_pin=25,gpio_out_pin=17

See /boot/overlays/README for more information on overlays.

Fix the LIRC Options

Edit /etc/lirc/lirc_options.conf, comment out the existing driver and device lines, and add:

driver    = default
device = /dev/lirc0

Reboot and stop the daemon

Reboot the Pi.

Now a bunch of LIRC daemons will be running. You don't want them while you're configuring, and if you're eventually going to be reading button presses from Python, you don't want them at all.

Disable them temporarily with

sudo systemctl stop lircd
which seems to be shorthand for
sudo systemctl stop lircd.socket
sudo systemctl stop lircd.service

Be sure to check with ps aux | grep lirc to make sure you've turned them off.

If you want to disable them permanently,

sudo systemctl disable lircd.socket lircd.service lircd-setup.service lircd-uinput.service lircmd.service
I got that list from:
systemctl list-unit-files | grep lirc

But you need them if you want to read from the /var/run/lirc/lircd socket.

Use mode2 to verify it sees the buttons

With the daemons not running, a program called mode2 can verify that your device's buttons are being seen at all. I have no idea why it's named that, or what Mode 1 is.
mode2 -d /dev/lirc0

You should see lots of output. If you don't, double-check your wiring and everything else you've done up to now.

Set up an lircd.conf

Here's where it gets difficult. On Jessie, you could run irrecord -d /dev/lirc0 ~/lircd.conf as described in my earlier article.

However, that doesn't work on stretch. There's apparently a bug in the irrecord in stretch that makes it generate a file that doesn't work. If you try it and it doesn't work, run tail -f /var/log/messages | grep lirc and you may see Info: Cannot configure the rc device for /dev/lirc0 and when you press buttons you'll see Notice: repeat code without last_code received but you won't get any keys.

If you have a working lirc setup from a Jessie machine, try it first. If it doesn't work, there's a script you can try that converts older lirc conf files to a newer format. The safest way to try it is to copy (with cp -a) the whole /etc/lirc directory to a local directory and run:

/usr/share/lirc/lirc-old2new your-local-copy
Or if you feel brave, back up /etc/lirc and run sudo /usr/share/lirc/lirc-old2new with no arguments. Either way, you should get an lirc.conf that has a chance of working with stretch.

If you don't have a working Jessie config, you're in trouble. You might be able to edit the one from irrecord to make it work. Here's the first part of my working Jessie lircd.conf:

begin remote

  name  /home/pi/lircd.conf
  bits           16
  flags SPACE_ENC|CONST_LENGTH
  eps            30
  aeps          100

  header       9117  4494
  one           569  1703
  zero          569   568
  ptrail        575
  repeat       9110  2225
  pre_data_bits   16
  pre_data       0xFD
  gap          108337
  toggle_bit_mask 0x0

      begin codes
          KEY_POWER                0x00FF
          KEY_VOLUMEUP             0x807F
          KEY_STOP                 0x40BF
          KEY_BACK                 0x20DF
          KEY_PLAYPAUSE            0xA05F
          KEY_FORWARD              0x609F
          KEY_DOWN                 0x10EF
and here's the corresponding part of the nonworking one generated on Stretch:
begin remote

  name  DingMai
  bits           32
  flags SPACE_ENC|CONST_LENGTH
  eps            30
  aeps          100

  header       9117  4494
  one           569  1703
  zero          569   568
  ptrail        575
  repeat       9110  2225
  gap          108337
  toggle_bit_mask 0x0
  frequency    38000

      begin codes
          KEY_POWER                0x00FD00FF 0xBED8F1BC
          KEY_VOLUMEUP             0x00FD807F 0xBED8F1BC
          KEY_STOP                 0x00FD40BF 0xBED8F1BC
          KEY_BACK                 0x00FD20DF 0xBED8F1BC
          KEY_PLAYPAUSE            0x00FDA05F 0xBED8F1BC
          KEY_FORWARD              0x00FD609F 0xBED8F1BC
          KEY_DOWN                 0x00FD10EF 0xBED8F1BC

It looks like setting bits to 16 and then using the second quartet from each key might work. So try that if you're stuck.

Once you get irw working, you're home free. The Python modules probably still won't do anything useful, but you can use my pyirw.py script as a model for a simple way to read keys from the lirc daemon.

In case you hit problems beyond what I saw, I found this discussion useful, which links to a complete GitHub gist of instructions for setting up lirc on Stretch. Those instructions have a couple of extra steps involving module loading that it turned out I didn't need, and on the other hand it doesn't address the problems I saw with irrecord. It looks like lirc configuration is a black art, not a science. See what works for you. Good luck!

Tags: , ,
[ 12:00 Nov 26, 2017    More hardware | permalink to this entry | ]

Comments via Disqus:

blog comments powered by Disqus