长久以来一直从事嵌入式硬件开发工作,使用C语言编写单片机程序也很长时间。近期对Linux下的python编程比较感兴趣…… 简单画了一块配合树莓派驱动步进电机驱动器的扩展板开始编程。这次主要是记录下如何使python程序关联到LIRC红外驱动库,网上的资料要么不全,要么版本太老,和现在最新的不兼容。
- 在树莓派上安装lirc和python-lirc(版本为lirc0.10.0,python-lirc 1.2.3)
sudo apt update
sudo apt install lirc
sudo apt-get install liblircclient-dev #如果要使用pylirc, 必须要安装liblircclient-dev
sudo apt-get install python3-lirc # or python-lirc
- 修改文件 /boot/config.txt 配置lirc的红外接口IO
sudo nano /boot/config.txt
找到 lirc-rpi module 的部分,注释掉默认的配置,修改为自己需要的引脚定义:
# Uncomment this to enable the lirc-rpi module
#dtoverlay=lirc-rpi,gpio_out_pin=17,gpio_in_pin=18,gpio_in_pull=up
注意gpio引脚是BCM编码,我的扩展板上红外接收管连接到物理Pin13脚:
dtoverlay=lirc-rpi,gpio_in_pin=27,gpio_in_pull=up # 没有发射管就不用配发射IO
给一张树莓派2B编码图:
- 修改文件 /etc/lirc/lirc_options.conf 配置lirc硬件接口
sudo nano /etc/lirc/lirc_options.conf
找到这两行
driver = devinput
device = auto
修改为:
driver = default
device = /dev/lirc0
然后,重启树莓派,就能开始测试了。
- 测试lirc库是否正常工作
必须停止lircd服务才能进入接收红外信号模式
sudo service lircd stop # 停止lircd服务
mode2 -d /dev/lirc0 # 接收红外信号
用遥控器对着接收管随便按一些按钮,如果出现形式如下的输出就表示正常:
- 红外按键编码录制
查看可用的按键名
irrecord -l
根据遥控器,选择了几个按键名并记录下来,然后执行红外线编码录制命令
irrecord -d /dev/lirc0 ~/lircd.conf
回车,先给录制文件起个名字,再回车,直到看到"Press RETURN now to start recording.",再回车一次,然后把遥控器上的按键随便按,一下一下的按,每次按键屏幕上都会出现一个"."按满一行后会提示再按二行,和上面一样,也是一下一下的按,要有耐心,千万不要按着不松手。
按满两行后屏幕提示"Please enter the name for the next button ",然后依次输入想要录制的按键,例如输入:
KEY_PLAY
然后提示“Now hold down button "KEY_PLAY".”这时候按下遥控器上的播放按钮,软件会自动记录并跳转回"Please enter the name for the next button (press <ENTER> to finish recording)",把每一个想录制的按钮全部依次输入一遍,直接回车结束。
这时提示要检查切换掩码,请尽快点按任意按钮。终于结束了……配置文件就保存在当前目录。最后,将录制好的配置文件(xxx.lircd.conf)拷贝到/etc/lirc/lircd.conf.d目录:
sudo cp ~lircd.conf /etc/lirc/lircd.conf.d # 根据自己录制的文件名修改
lircd.conf.d目录中的devinput.lircd.conf需要改名为devinput.lircd.dist
- 测试录制后的按键输出
重启lirc服务,运行lircd守护程序:
sudo service lircd restart
lircd --nodaemon --device /dev/lirc0 --driver default
另外开一个窗口运行,执行irw命令进行测试(如果没有输出建议reboot重启一次):
sudo irw
按遥控器按键,你应该看见一些键值,如下:
我在这个地方卡了一天,按遥控器总是没有按键输出,守护程序中报错 Notice: repeat code without last_code received (重复代码问题), 最后在国外论坛里找到答案:
上一节中录制的编码文件xx.lircd.conf中有一些多余的重复编码
begin remote
name ir1
bits 32
flags SPACE_ENC|CONST_LENGTH
eps 30
aeps 100
header 9043 4446
one 587 1658
zero 587 538
ptrail 595
repeat 9045 2198
gap 107901
toggle_bit_mask 0x0
frequency 38000
begin codes
key_power 0x04FB906F
key_channeldown 0x04FB6897
key_channelup 0x04FBF807
key_volumeup 0x04FBA857
key_volumedown 0x04FBD827
key_play 0x04FB8877
end codes
end remote
这个是修改后的,没有修改的文件在每个按键编码后面有2段0xXXXXXXX,第一段每个按键都不一样,但第二段每个按键都一样。修改方式就是保留第一个段编码,把键值后面重复的编码去掉即可。
- 修改lircrc配置文件
参考:https://github.com/tompreston/python-lirc
把/etc/lirc/irexec.lircrc改名为lircrc,然后按照需求进行配置,例如:
begin
prog = myprogram.py # 关联的python程序名
button = key_power # 这个是上面录制的按键名
config = KEY_POWER # 传递给程序的消息
end
- 在python程序中使用lirc红外驱动库
首选导入lirc模块,接着初始化lirc驱动库
import lirc
sockid = lirc.init("myprogram.py")
这部分网上中文资料很少,我详细介绍下:
'''
sockid = lirc.init("myprogram.py")
'''
初始化lirc,分为阻塞和不阻塞模式。上面没有带参数的就是阻塞模式,不接收消息就一直等待。
sockid = lirc.init("myprogram.py", blocking=False) # 关联lirc 取消阻塞
带blocking=False参数,就是不阻塞模式,消息来了你不收就没有了,哈哈,这个我喜欢,因为我的遥控器有很多空消息(就是上面干掉的编码)。
先试试在程序里面打印接收到的按键消息:
btn = lirc.nextcode()
print"btn"
然后你想干啥就干啥吧,比如:
btn = lirc.nextcode()
if btn == [u'KEY_PLAY']:
print"KEY_PLAY..."
if STATE_PALY:
STATE_PALY = 0
else:
STATE_PALY = 1
程序结束时不要忘了释放lirc驱动库:
lirc.deinit()