树莓派Sense HAT红外遥控掌控板RGB灯:跨硬件平台信号解码与控制实践

📅 2026/7/28 4:01:48
树莓派Sense HAT红外遥控掌控板RGB灯:跨硬件平台信号解码与控制实践
1. 项目缘起从“遥控灯”到“掌控互动”的硬件探索几年前我在一个创客工作坊里看到几个中学生围着一块小小的板子用手机App控制上面的LED灯带变换颜色。他们兴奋地讨论着如何把家里的台灯也改成这样。那个场景让我印象深刻也让我意识到硬件编程的魅力就在于这种“看得见、摸得着”的即时反馈。今天要聊的这个项目就是这种魅力的一个经典体现用一块名为“掌控板”的国产开源硬件结合树莓派上的Sense HAT扩展板实现一个可以通过红外遥控器控制的智能灯。听起来是不是有点像把电视遥控器对准台灯然后按一下按钮灯就亮了没错核心逻辑就是这么直观。但这个项目的有趣之处远不止于此。它本质上是一个跨硬件平台的“信号翻译”与“指令执行”过程。我们用一个最普通的家用红外遥控器比如电视、空调遥控器发射信号树莓派上的Sense HAT负责接收并解码这个信号然后通过某种方式比如网络或串口将指令发送给另一块独立的“掌控板”最终由掌控板点亮或控制其板载的RGB LED灯。这个过程串联起了红外通信、微控制器编程、网络通信或串口通信等多个知识点是一个绝佳的综合性硬件入门项目。为什么选择这个组合对于初学者尤其是教育领域的用户树莓派Sense HAT提供了强大的计算能力和丰富的传感器但直接用它做简单的IO控制如点灯有时显得“大材小用”且GPIO电压是3.3V驱动能力有限。而掌控板则是一款专为教育和物联网入门设计的微控制器它集成了RGB灯、麦克风、加速度计等编程环境如Mind、mPython对青少年极其友好其IO口驱动能力也更强。将两者结合既能利用树莓派处理复杂信号如红外解码又能发挥掌控板在互动灯光效果上的优势实现“强强联合”。这个项目非常适合那些已经玩过Arduino或掌控板基础项目想向树莓派和更复杂系统交互迈进的硬件爱好者、创客教师以及学生们。2. 核心硬件解析Sense HAT与掌控板的角色定位在开始动手之前我们必须先搞清楚手头的两块“主角”硬件各自擅长什么以及它们在这个项目中如何分工。这就像组建一个团队明确每个人的职责协作才能顺畅。2.1 树莓派与Sense HAT信号接收与解码的“大脑”树莓派在这个项目中扮演着“信息处理中心”的角色。它性能强大可以运行完整的操作系统如Raspbian/Debian轻松处理来自各种外设的复杂数据。而我们实现遥控功能的关键在于它上面插着的一块扩展板——Sense HAT。Sense HAT是一块功能丰富的附加板它集成了LED点阵屏、陀螺仪、加速度计、磁力计、温湿度及气压传感器。但对我们这个项目而言最重要的一个常被忽略的功能是其红外接收和发射管。是的Sense HAT板载了一个红外接收器通常位于板子边缘这意味着我们无需额外购买和焊接任何红外接收模块就能直接接收来自遥控器的红外信号。这大大简化了硬件连接是选择Sense HAT的核心原因之一。树莓派系统如Raspbian通常已经包含了lircLinux Infrared Remote Control驱动和软件包它可以用来配置和读取红外信号。我们的任务就是配置lirc让它能正确识别Sense HAT上的红外接收器并解码我们遥控器发出的信号。每个遥控器的按键都对应一个独特的红外编码通常是NEC、RC-5等协议lirc的作用就是将这些闪烁的红外光脉冲翻译成我们可以理解的按键名称比如“KEY_POWER”、“KEY_VOLUMEUP”等。注意不同版本的树莓派和Sense HAT其红外接收器对应的GPIO引脚可能不同。对于较新的树莓派4B/5与Sense HAT常见的映射是GPIO 18。这是后续软件配置中至关重要的一步配置错了就无法收到信号。2.2 掌控板灯光效果的“执行者”掌控板是一块基于ESP32的微控制器开发板。它体积小巧但“五脏俱全”板载1.44寸彩色LCD屏、麦克风、加速度计、地磁计、蜂鸣器以及一圈12颗可编程的RGB LED灯NeoPixel。这些RGB LED灯正是我们这个项目的最终输出设备。我们可以通过编程让这些灯显示任何颜色实现呼吸、渐变、跑马灯等各种炫酷效果。掌控板的编程环境如Mind图形化编程或mPython的Blockly/代码模式对新手非常友好。它可以通过USB线直接与电脑连接进行编程和供电。在这个项目中掌控板需要接收来自树莓派的指令。那么指令如何传递呢这里有两种主流方案串口通信UART通过USB数据线将掌控板的串口与树莓派的USB口连接。树莓派上运行一个Python脚本将解码后的红外指令通过串口发送给掌控板。掌控板端的程序持续监听串口收到特定指令后执行相应的灯光操作。这种方式硬件连接简单一根USB线通信可靠是初学者的首选。Wi-Fi网络通信掌控板的ESP32核心自带Wi-Fi功能。我们可以让掌控板连接本地Wi-Fi树莓派和掌控板处于同一局域网内。树莓派作为服务器Server或客户端Client通过TCP或UDP协议向掌控板发送指令。这种方式无需物理连线更加灵活但需要配置网络复杂度稍高。对于首次尝试我强烈推荐使用串口通信方案。它避开了网络配置可能带来的IP地址、端口、防火墙等问题让调试过程更专注于核心逻辑。3. 环境搭建与红外信号解码配置硬件角色清晰后我们进入实战环节。第一步是让树莓派能够“听懂”遥控器的话。3.1 树莓派系统与基础准备首先确保你的树莓派已经安装了操作系统。Raspberry Pi OS原Raspbian是官方推荐的选择。使用树莓派官方的Imager工具烧录系统到SD卡是最稳妥的方式。系统启动后建议先通过sudo apt update sudo apt upgrade -y更新软件包列表和系统。接下来需要安装红外解码的核心软件包lircsudo apt install lirc -y安装完成后我们需要配置系统告诉它红外接收器连接在哪个GPIO引脚上以及使用哪种驱动模式。3.2 配置LIRC驱动与硬件映射这是最关键且最容易出错的一步。我们需要修改两个配置文件。首先编辑/etc/lirc/lirc_options.conf文件sudo nano /etc/lirc/lirc_options.conf找到driver和device这两行将其修改为如下内容。这告诉lirc使用默认的devinput驱动并从/dev/lirc0设备文件读取数据。driver default device /dev/lirc0接下来我们需要配置硬件指定红外设备对应的GPIO引脚。编辑/boot/config.txt文件sudo nano /boot/config.txt在文件末尾添加以下一行。这里的gpio_in_pin18指定了红外接收器的输入引脚。正如前面提到的对于树莓派4B/5 Sense HAT组合GPIO 18是常见配置。如果你使用的是其他型号或遇到问题可以尝试GPIO 17。dtoverlaygpio-ir,gpio_in_pin18保存并退出编辑器然后重启树莓派以使配置生效sudo reboot重启后验证红外接收器是否被正确识别。运行以下命令ls /dev/lirc*如果看到/dev/lirc0这个设备文件恭喜你硬件配置基本成功。3.3 录制遥控器按键编码现在我们需要让lirc学习你的遥控器的“语言”。使用一个通用的电视或空调遥控器即可。首先停止lirc服务并启动一个原始模式来接收信号sudo systemctl stop lircd mode2 -d /dev/lirc0此时用遥控器对准Sense HAT的红外接收器按下任意键比如音量。如果终端屏幕上开始快速滚动显示pulse和space后面跟着一串数字说明红外信号已经被成功接收。按CtrlC退出。接下来使用irrecord工具来录制并生成一个属于你遥控器的配置文件。这个文件将每个按键的红外波形映射为一个按键名。irrecord -d /dev/lirc0 ~/lircd.conf按照屏幕提示操作它会先让你按一些随机键用于分析你遥控器的载波频率。然后提示你输入一个按键名称例如KEY_POWER你按下遥控器上想被命名为“KEY_POWER”的键比如电源键。重复第二步录制其他按键如KEY_VOLUMEUP,KEY_VOLUMEDOWN,KEY_CHANNELUP,KEY_CHANNELDOWN等。建议至少录制4-5个键用于后续控制灯光的不同模式。录制完成后按回车结束。现在你的家目录下会生成一个lircd.conf文件。将其复制到lirc的系统配置目录并重启lirc服务sudo cp ~/lircd.conf /etc/lirc/lircd.conf.d/ sudo systemctl start lircd sudo systemctl enable lircd3.4 测试红外解码服务启动后我们可以进行测试。运行irw命令irw此时再次用遥控器对准Sense HAT按下你录制过的按键。在irw终端里你应该能看到实时的输出例如0000000000ff00dd KEY_VOLUMEUP MyRemote这表示lirc已经成功将红外信号解码并识别出你按下的是“MyRemote”这个遥控器配置文件中定义的名称的“KEY_VOLUMEUP”键。至此树莓派端的红外解码环境全部搭建完成。4. 掌控板端程序灯光控制逻辑的实现树莓派已经能“听懂”指令了现在我们需要让掌控板“执行”指令。我们采用串口通信方案因此需要编写掌控板的程序让其监听串口并根据收到的字符串命令改变RGB灯的状态。这里以掌控板常用的mPython或Mind编程环境为例。其核心逻辑非常简单初始化串口和RGB灯然后在主循环中不断检查串口是否有数据到来如果有就读取并解析。下面是一个示例代码框架基于mPython的代码模式# 导入必要的模块 from mpython import * import time # 初始化硬件 # 假设我们使用板载的NeoPixel RGB灯环有12颗灯 import neopixel np neopixel.NeoPixel(Pin(Pin.P15), n12, bpp3, timing1) # 初始化串口波特率设置为9600需与树莓派发送端一致 uart machine.UART(1, txPin(Pin.P1), rxPin(Pin.P0), baudrate9600) # 定义一些灯光模式函数 def light_on(color(255, 255, 255)): # 默认白色全亮 for i in range(12): np[i] color np.write() def light_off(): for i in range(12): np[i] (0, 0, 0) np.write() def breathe_effect(color(0, 100, 255)): # 呼吸灯效果 # ... 呼吸灯实现代码 ... pass def rainbow_cycle(): # 彩虹循环效果 # ... 彩虹灯实现代码 ... pass # 主循环 while True: if uart.any(): # 检查串口是否有数据 command uart.read().decode(utf-8).strip() # 读取并解码数据 print(Received:, command) # 在掌控板串口监视器打印用于调试 # 根据接收到的命令执行相应操作 if command ON: light_on() elif command OFF: light_off() elif command BLUE: light_on((0, 0, 255)) elif command GREEN: light_on((0, 255, 0)) elif command BREATHE: # 注意呼吸灯效果是持续的需要特殊处理循环 breathe_effect() elif command RAINBOW: rainbow_cycle() # ... 可以添加更多命令 ... time.sleep(0.05) # 短暂延时避免CPU占用过高将这段代码通过USB线烧录到掌控板中。烧录完成后掌控板就会开始运行并等待来自串口的指令。实操心得在编写掌控板程序时务必注意字符串匹配的精确性。树莓派发送的字符串是ON\n带换行符还是ON在掌控板端读取后使用.strip()方法去除首尾空白字符包括换行符\n是一个好习惯可以避免因格式不一致导致的命令无法识别。另外复杂的灯光效果如呼吸、彩虹是动画需要在一个循环内不断更新LED状态。在实现时要小心不要让这个效果循环阻塞主循环导致无法接收新的串口命令。一种简单的做法是使用状态机收到“BREATHE”命令后设置一个全局状态标志在主循环中根据这个标志来执行呼吸灯的一帧更新。5. 树莓派桥接程序解码指令与串口发送现在我们有了能听懂的树莓派和能执行的掌控板缺一个“翻译官”——运行在树莓派上的Python桥接程序。这个程序的工作流程是监听lirc解码后的按键事件将不同的按键映射为不同的字符串命令然后通过串口发送给掌控板。首先确保树莓派上安装了Python的串口库pyserialpip3 install pyserial然后创建一个Python脚本例如ir_controller.py#!/usr/bin/env python3 import serial import time import subprocess import select # 配置掌控板连接的串口设备名和波特率 # 树莓派上掌控板通过USB连接通常会映射为 /dev/ttyACM0 或 /dev/ttyUSB0 # 可以通过 ls /dev/ttyA* 或 ls /dev/ttyU* 插入掌控板前后对比确认 SERIAL_PORT /dev/ttyACM0 BAUD_RATE 9600 # 初始化串口连接 try: ser serial.Serial(SERIAL_PORT, BAUD_RATE, timeout1) time.sleep(2) # 等待串口稳定对于某些设备很重要 print(fConnected to {SERIAL_PORT} at {BAUD_RATE} baud.) except serial.SerialException as e: print(fError opening serial port {SERIAL_PORT}: {e}) exit(1) # 定义一个函数用于向掌控板发送命令 def send_command(cmd): if ser.is_open: message cmd \n # 添加换行符作为命令结束标志 ser.write(message.encode(utf-8)) print(fSent: {cmd}) else: print(Serial port is not open.) # 使用subprocess打开irw命令并实时读取其输出 # irw会持续输出按键信息 proc subprocess.Popen([irw], stdoutsubprocess.PIPE, textTrue) print(Listening for IR commands. Press CtrlC to exit.) try: # 使用select来非阻塞地读取irw的输出 while True: # 检查irw进程是否有输出可读 readable, _, _ select.select([proc.stdout], [], [], 0.1) if proc.stdout in readable: line proc.stdout.readline() if line: # irw输出格式: 0000000000ff00dd KEY_VOLUMEUP MyRemote parts line.strip().split() if len(parts) 3: key_name parts[1] remote_name parts[2] # 根据按键名称映射到我们要发送的命令 # 这里的映射关系需要和你之前irrecord录制的按键名对应 command_map { KEY_POWER: OFF, # 电源键关灯 KEY_VOLUMEUP: ON, # 音量开灯白色 KEY_VOLUMEDOWN: BLUE, # 音量-蓝色 KEY_CHANNELUP: GREEN, # 频道绿色 KEY_CHANNELDOWN: BREATHE, # 频道-呼吸灯 KEY_MUTE: RAINBOW, # 静音键彩虹灯 } if key_name in command_map: send_command(command_map[key_name]) else: print(fUnmapped key: {key_name}) time.sleep(0.01) # 短暂休眠降低CPU占用 except KeyboardInterrupt: print(\nExiting...) finally: proc.terminate() if ser.is_open: ser.close() print(Serial port closed.)代码关键点解析串口设备名/dev/ttyACM0是ESP32/掌控板类设备在Linux下的常见串口名。如果连接后找不到尝试/dev/ttyUSB0。使用ls /dev/tty*命令查看。波特率必须与掌控板程序中设置的baudrate9600完全一致。命令映射command_map字典是核心它定义了遥控器上哪个按键key_name对应发送给掌控板的哪个字符串命令。你需要根据自己irrecord时定义的按键名来修改这个字典。irw进程监听脚本没有直接调用lirc的Python库而是通过subprocess启动irw命令并捕获其输出。这是一种简单可靠的方法避免了处理lirc套接字或驱动细节的复杂性。添加换行符cmd \n确保命令以换行符结尾方便掌控板端的readline()或strip()处理。给脚本添加执行权限并运行chmod x ir_controller.py python3 ir_controller.py现在用遥控器对准Sense HAT按下你映射过的按键如音量你应该能在树莓派终端看到“Sent: ON”的提示同时掌控板上的RGB灯应被点亮成白色。6. 项目优化与扩展思路当基础功能跑通后我们可以从稳定性、用户体验和功能扩展几个层面来优化这个项目。6.1 稳定性提升与错误处理最初的脚本在异常处理上比较薄弱。在实际部署中我们需要考虑更多串口重连机制掌控板可能意外重启或USB接触不良。可以在脚本中添加一个检测循环如果串口断开尝试每隔几秒重新连接直到恢复。irw进程守护irw进程有时会意外结束。可以用一个while True外层循环如果发现proc.poll()不为None表示进程已终止就重新启动subprocess.Popen。去抖动处理红外遥控按下时可能发送多个重复信号。可以在代码中记录上一次有效按键的时间如果两次相同按键的间隔小于某个阈值如200毫秒则忽略后续信号防止一次按下触发多次动作。6.2 从串口到Wi-Fi实现无线控制摆脱USB线的束缚会让项目更整洁。我们可以修改方案让树莓派和掌控板通过Wi-Fi通信。掌控板端Wi-Fi客户端 TCP Server编写掌控板程序使其启动后连接家庭Wi-Fi。在掌控板上创建一个TCP服务器监听某个端口如8888。主循环中接受来自树莓派的TCP连接并读取数据解析命令控制灯光。树莓派端TCP Client在之前的Python桥接脚本中将serial.Serial部分替换为socket.socket。脚本启动后尝试连接到掌控板的IP地址和端口。收到红外指令后通过TCP Socket发送命令字符串。这种方式下掌控板需要有一个固定的局域网IP或者使用mDNS如掌控板.local来访问。虽然设置稍复杂但实现了真正的无线遥控项目适用范围更广。6.3 功能扩展更多传感器与交互Sense HAT和掌控板都拥有丰富的传感器这为项目扩展提供了无限可能环境感应灯利用Sense HAT上的温湿度、气压传感器。树莓派程序可以定时读取环境数据当温度超过阈值时通过串口发送命令让掌控板的灯光变为“警示”的红色湿度高时变为蓝色等。姿态控制灯利用Sense HAT或掌控板自带的加速度计。编写程序当检测到板子被倾斜或晃动时改变灯光颜色或模式。例如向左倾斜变冷色调向右倾斜变暖色调。灯光效果序列定义更复杂的命令如“MODE1”触发一组预设的灯光动画序列而不仅仅是单一颜色。集成语音控制在树莓派上安装语音识别库如Snowboy或Vosk结合USB麦克风。实现“打开灯”、“变成蓝色”等语音指令与红外遥控并存形成多模态交互。6.4 部署为系统服务为了让项目开机自启动我们可以将树莓派的Python桥接脚本设置为系统服务。创建一个服务文件/etc/systemd/system/ir-light-controller.service[Unit] DescriptionIR Remote Controlled Light Service Aftermulti-user.target lircd.service Wantslircd.service [Service] Typesimple Userpi ExecStart/usr/bin/python3 /home/pi/ir_controller.py Restarton-failure RestartSec5s [Install] WantedBymulti-user.target然后启用并启动服务sudo systemctl daemon-reload sudo systemctl enable ir-light-controller.service sudo systemctl start ir-light-controller.service这样每次树莓派启动后遥控灯服务就会自动在后台运行无需手动登录执行脚本。通过以上步骤一个由红外遥控器控制、基于Sense HAT和掌控板的互动灯项目就从概念变成了现实。它不仅是一个有趣的玩具更是一个涵盖了嵌入式Linux配置、外设驱动、串口通信、多硬件平台协作的微型系统工程样本。