打造增强型Raspberry Pi-红外遥控篇

上一期介绍了怎么给Raspberry Pi加上一个液晶屏,这期该介绍红外遥控了。

需要的硬件:

  • 一个红外接收管,型号可以是TSOP1238/TSOP2238等可以3.3V电压下工作的38KHz红外接收管。
  • 一个红外遥控器,可以是电视机、机顶盒等的遥控器。但别拿空调遥控器这种自带状态逻辑的遥控器来折磨自己。

连接红外接收管:

不同的红外接收管连线可能不太一样,需要参考相应的Datasheet。以TSOP 1238为例的话,当红外线接收窗朝向自己时,从左到右三个引脚分别为:

1. GND,接地,RPi PIN 6
2. VS,电源,接3.3V电源,RPi PIN 17
3. OUT,数据输出,接GPIO 24,RPi PIN 18

由于Raspberry Pi的GPIO只能接收3.3V的输入,所以红外接收管的电源务必要接3.3V的供电。我自己用的红外接收管的型号是TSOP 1838(引脚顺序是OUT, GND, VS),按lirc_rpi项目页面的说法,这个管子应该在5V供电下才能正常工作,不过我还是只接了3.3V,发现也能用。

系统软件安装:

lirc_rpi项目为Linux内核提供了支持GPIO口的红外接收管的驱动,在最新的Raspbian系统中应该已经包含。如果你的系统中没有这个模块,也许需要自己重新编译内核。具体可以参考lirc_rpi项目主页。

然后需要安装用户态的服务进程:

sudo apt-get install lirc

加载lirc_rpi内核模块:

sudo modprobe lirc_rpi gpio_in_pin=24 gpio_out_pin=23

注意,在加载lirc_rpi时必须指定输入端口是GPIO 24,跟实际接线一致。输出端口设为GPIO 23,是因为我不需要这个输出端口,而目前我们GPIO 23口是空着的。

测试红外接收是否正常:

sudo mode2 -d /dev/lirc0

如果按遥控器上的键,屏幕上能显示出一串pluse和space值的话,多半就是正常了。

配置下/etc/lirc/hardware.conf:

...
LIRCD_ARGS="--uinput"
...
DRIVER="default"
...
DEVICE="/dev/lirc0"

让lirc学习一下你遥控器上的按键,在我的例子中,请至少学习5个按键,分别做为上(up)、下(down)、左(left)、右(right)、选择(sel):

sudo /etc/init.d/lirc stop
#学习按键
irrecord -n -d /dev/lirc0 ~/lircd.conf
#把学习后生成的配置文件作为lircd的配置文件
sudo mv ~/lircd.conf /etc/lirc/lircd.conf
sudo /etc/init.d./lirc start

配置完后,可以用irw命令测试遥控器是否工作正常。

配置~/.lircrc.conf文件,把按键与需要触发的行为进行关联:

begin
    prog = lcdmenu 
    button = up
    config = up
end
begin
    prog = lcdmenu
    button = right
    config = right
end
begin
    prog = lcdmenu
    button = left
    config = left
end
begin
    prog = lcdmenu
    button = down
    config = down
end
begin
    prog = lcdmenu
    button = sel
    config = sel
end

为Raspberry Pi添加液晶屏控制菜单,我参考了Github上的RaspberryPiLcdMenu,这个项目实现了使用一个带五个小按钮的液晶屏套件作为硬件基础来显示与操作一个菜单的系统,我没有这个套件,而且我是用红外遥控器而不是小按钮来操作,所以需要重写跟按钮有关的代码,通过lirc提供的接口去获取遥控器的按键信息,很容易,可以参考我已经实现好的代码,在Buttons.py中:

git clone https://github.com/lifanxi/rpimenu.git

RaspberryPiLcdMenu项目提供了一个很灵活的菜单配置系统可以很方便的添加新的菜单项,我给它添加了遥控fmd播放豆瓣FM的菜单功能项(参考lcdmenu.xml)。

一切就绪,启动lcdmenu.py程序:

sudo python lcdmenu.py

如果你的配置没有问题,这时就可以在液晶屏上看到定制后的菜单,并可以用遥控器来遥控操作了,按上下键选项不同的菜单项,向右键进入子菜单,向左退回上一级菜单,选择键用于根据屏幕提示确定某些特定的操作。

添加了Douban.fm的菜单

添加了Douban.fm的菜单

豆瓣FM播放中,可以显示曲名和播放进度

豆瓣FM播放中,可以滚动显示曲名和播放进度

一切调试完成后,您还可以把加载lirc_rpi模块和启动lcdmenu.py的命令加到Raspberry Pi的启动脚本中,这样系统一启动就可以让液晶显示和菜单自动生效,菜单操作中已经预设了关机、重启、设置IP地址等功能,这对于headless使用Raspberry Pi的同学来说,是一件非常方便的事情。

参考资料:

  1. 红外遥控器lirc配置
  2. RaspberryPiLcdMenu
  3. lirc_rpi项目
  4. 用Raspberry Pi打造真正的“豆瓣FM”

打造增强型Raspberry Pi-红外遥控篇》上有28条评论

  1. Pingback引用通告: 树莓派 Raspberry Pi 相关文章 | 胖朱

  2. 博主,请问我输入mode2 -d /dev/lirc0后,用遥控器对着红外接收头按按钮没有反应没有输出,这是怎么回事,同样的操作环岛b+版上就有输出,我是不是需要给b版重装系统?

    • 我是这样的情况,第一次是按照教程走的gpio_in_pin=23,等我第二天再用的时候,mode2 -d /dev/lirc0后按下遥控器就没有输出。
      后来我改成GPIO18后,按下遥控器就有输出了,不知道为什么,博主可以告知吗?

  3. 博主请问我执行modprobe lirc_rpi,显示Error: could not insert ‘lirc_rpi’:No such device,这是怎么回事?是没有这个模块还是缺少什么文件?我用的是pi 2,raspbian最新的系统……

    • 这个问题我没遇到过,不过稍微搜索一下就可以找到答案,请参考:https://github.com/raspberrypi/firmware/blob/master/boot/overlays/README

      简单说就是在config.txt中加这么一行:
      dtoverlay=lirc-rpi
      另外,有别的贴子上有人说还需要把lirc-rpi-overlay.dtb文件放到/boot/overlays中才行,您可以自己试试。

      我暂时没有条件帮您试验,抱歉。

      • 确实,由于是新手,不知道应该去哪找需要的资料。现在我在尝试编写python的脚本读取红外遥控器,但是btn.readButton()的输出一直是none,不知道怎么回事。我看了Buttons.py,感觉看不懂,尤其是那句pylirc.init(app, conf, 1)。请问在哪里能看到pylirc的各种用法呢?

        • 好吧,找到实例了,原来那个文件是用来对应各个按键的名称和意义的。打扰了

  4. 电压有变化,2.7—2.46V,但mode2 -d /dev/lirc0,无输出,我用的是SSH,你所说的显示只能在专门的液晶显示器上?还是运行mode2 -d /dev/lirc0就有输出?

    • 电压有变化是啥?这个红外管应该给的是数字信号啊,测电压不太科学吧。

      mode2就是在终端是直接执行的,会输出在标准输出上,与液晶屏无关。

      • 没有错误提示,但也无输出,在哪里可以配置lirc呢?另:接收到信号,即使是数字信号,还是有电压变化的,相对于初始电压,有遥控信号,OUT脚位电压有变化,说明,传感器收到信号并输出到系统,只是不知道这信号咋个取出来。

    • 你检查下modprobe以后dmesg中的输出,看看GPIO端口的设置与你实际的接线是不是一致。

      mode2 -d /dev/lirc0后面这个/dev/lirc0就是对应的设备结点,应该跟你modprobe后出现的结点一致。

  5. root@jemy-pi:~# dmesg | grep -i lirc
    [ 4.165380] lirc_dev: IR Remote Control driver registered, major 246
    [ 4.250114] lirc_rpi: module is from the staging directory, the quality is unknown, you have been warned.
    [ 5.247653] lirc_rpi: auto-detected active high receiver on GPIO pin 18
    [ 5.256891] lirc_rpi lirc_rpi: lirc_dev: driver lirc_rpi registered at minor = 0
    [ 5.268084] lirc_rpi: driver registered!
    root@jemy-pi:~#

    • 这里提示检测到接收器在Pin 18上,也就是GPIO 24,但你说你是接在GPIO 9上的,你看看这个不一致是什么原因造成的?

      另外再确认一下你的红外接收管的型号和接脚定义,1238和1838的定义是不同的。

  6. 我用的扩展板是瑞士军刀,我运行modprobe lirc_rpi gpio_in_pin=9 gpio_out_pin=12 mode2 -d /dev/lirc0

  7. root@jemy-pi:~# sudo modprobe lirc_rpi gpio_in_pin=9 gpio_out_pin=12
    root@jemy-pi:~# mode2 -d /dev/lirc0
    ^Z
    [1]+ Stopped mode2 -d /dev/lirc0
    root@jemy-pi:~# dmesg | grep -i lirc
    [ 3.711402] lirc_dev: IR Remote Control driver registered, major 244
    [ 3.752250] lirc_rpi: module is from the staging directory, the quality is unknown, you have been warned.
    [ 4.763031] lirc_rpi: auto-detected active high receiver on GPIO pin 18
    [ 4.772060] lirc_rpi lirc_rpi: lirc_dev: driver lirc_rpi registered at minor = 0
    [ 4.783371] lirc_rpi: driver registered!

  8. 我的是1838T,都是按照说明书插的,我也直接接18脚,按照相应的参数实验过。

  9. 我已经搞定,不过不是用lirc的方法,而是用一段程序来实现的。简单有效,感觉尽量不要用库,用成品,用程序来调,还可以修改里面参数,会更灵活,特别对初学来说还是有效的,不过虽然是初学,但还得有电子及编程基础才是。

    • 看到跟我碰到一样问题的人了。我感觉这个是driver的bug,不知道从哪个版本开始的,insmod给的PIN参数完全不认。
      我去看了driver,它好像直接就找了个可用的pin覆盖设定的参数,我把那一段修改了一下就好了

发表评论

电子邮件地址不会被公开。 必填项已用*标注

This site uses Akismet to reduce spam. Learn how your comment data is processed.