
本文介绍在树莓派4上使用lirc(linux infrared remote control)捕获红外遥控信号,并结合python实时响应按键事件,动态控制lcd显示内容,替代键盘输入方案,适用于嵌入式人机交互项目。
本文介绍在树莓派4上使用lirc(linux infrared remote control)捕获红外遥控信号,并结合python实时响应按键事件,动态控制lcd显示内容,替代键盘输入方案,适用于嵌入式人机交互项目。
在树莓派4上实现红外遥控(IR)按键检测,是构建免接触式交互界面(如LCD信息屏、智能家居控制终端)的关键能力。不同于keyboard等仅监听PC键盘的Python库,红外遥控需依赖底层红外驱动与用户空间协议解析——LIRC(Linux Infrared Remote Control)正是为此设计的标准开源框架。
✅ 基础环境准备
- 硬件连接:将红外接收模块(如VS1838B)接入GPIO(推荐GPIO17,即物理引脚11),VCC接5V,GND接地;确保接收头正对遥控器发射端。
-
启用红外支持:编辑 /boot/config.txt,添加以下行并重启:
dtoverlay=gpio-ir,gpio_pin=17
-
安装并配置LIRC:
sudo apt update && sudo apt install lirc -y sudo systemctl enable lircd
? 测试红外信号接收
运行以下命令验证是否能捕获原始脉冲:
sudo mode2 -d /dev/lirc0
对准遥控器任意键按下,若终端持续输出类似 space 16722159 的脉冲序列,则硬件与内核驱动正常。
?️ 配置遥控器键码映射(以常见NEC遥控为例)
生成自定义配置文件(如/etc/lirc/lircd.conf.d/my_remote.conf):
# Please make this file available to others
# at https://sourceforge.net/p/lirc-remotes/code/ci/master/tree/
# This config file was automatically generated
# using lirc-tools-0.10.1.gitf9b6e2a on Mon Jun 10 15:22:33 2024
#
# contributed by
#
# brand: MyRemote
# model no. / :
# devices being controlled: LCD Display
#
begin remote
name MyRemote
bits 16
flags SPACE_ENC|CONST_LENGTH
eps 30
aeps 100
header 9000 4500
one 560 1690
zero 560 560
gap 108000
toggle_bit_mask 0x0
begin codes
KEY_OK 0x00FF4AB5
KEY_UP 0x00FF02FD
KEY_DOWN 0x00FFC23D
end codes
end remote? 提示:使用 irrecord -d /dev/lirc0 ~/lircd.conf 可交互式录制键码,避免手动猜测十六进制值。
重启LIRC服务生效:
sudo systemctl restart lircd
? Python实时响应遥控按键(非阻塞式)
关键点在于避免irw命令阻塞主线程(如原问题中“checking the button from the ir will just stop the whole program”)。推荐使用子进程+异步读取,或更稳健的python-lirc库:
pip3 install python-lirc
完整示例代码(兼容LCD显示逻辑):
#!/usr/bin/env python3
import time
import subprocess
import threading
from lirc import RawConnection
# 模拟LCD显示函数(替换为实际LCD驱动,如RPLCD或Adafruit_CharLCD)
def lcd_print(text):
print(f"[LCD] {text}")
# 全局状态控制
current_mode = "default" # 'default', 'paused', 'exit'
stop_event = threading.Event()
def ir_listener():
global current_mode
try:
conn = RawConnection()
while not stop_event.is_set():
try:
# 非阻塞读取,超时1秒避免卡死
code = conn.readline(timeout=1.0)
if code and len(code) >= 2:
key_name = code[1].strip()
print(f"IR Key detected: {key_name}")
if key_name == "KEY_OK":
current_mode = "exit"
lcd_print("See you soon!")
break
elif key_name == "KEY_UP":
current_mode = "default"
lcd_print("Hello StackOverflow!")
elif key_name == "KEY_DOWN":
current_mode = "paused"
lcd_print("HI!")
except (IOError, OSError):
pass # LIRC暂时不可用,继续轮询
except Exception as e:
print(f"IR read error: {e}")
except Exception as e:
print(f"LIRC init failed: {e}")
# 主显示循环(模拟5秒自动切换 + 实时响应)
def lcd_main_loop():
start_time = time.time()
while not stop_event.is_set():
elapsed = time.time() - start_time
if current_mode == "default":
if elapsed > 5.0:
lcd_print("HI!")
current_mode = "paused"
elif current_mode == "exit":
break
time.sleep(0.5)
if __name__ == "__main__":
lcd_print("Hello StackOverflow!")
# 启动IR监听线程(后台非阻塞)
ir_thread = threading.Thread(target=ir_listener, daemon=True)
ir_thread.start()
# 运行主显示逻辑
try:
lcd_main_loop()
except KeyboardInterrupt:
print("\nExiting...")
finally:
stop_event.set()⚠️ 注意事项与最佳实践
- 权限问题:确保当前用户属于lirc组:sudo usermod -a -G lirc pi,否则RawConnection()会报错。
- 去抖与重复触发:部分遥控器长按会连续发送相同码,可在Python层加入时间窗口过滤(如记录上次触发时间,间隔
- LCD兼容性:本例中lcd_print()仅为占位;实际项目请集成对应驱动(如使用I²C接口的16×2 LCD可选用RPLCD.i2c)。
- 性能考量:irw命令虽简单但启动开销大,不建议在循环中频繁调用subprocess.run(['irw']);python-lirc基于Unix socket直连,延迟更低、更可靠。
通过以上配置,你的树莓派4即可稳定识别红外按键,并在不中断主程序的前提下实时更新LCD内容——真正实现“遥控即响应”的嵌入式交互体验。









