Arduino红外信号接收与解码
一、项目背景与意义
在智能家居、远程控制等领域,红外信号的应用十分广泛。比如我们日常使用的电视遥控器、空调遥控器,都是通过发射红外信号来实现对设备的控制。
二、硬件选型与原理
(一)硬件清单
VS1838B 红外接收头、红外遥控器( NEC 编码格式)
三、软件准备与代码解析
(一)软件工具
红外解码库:为了简化红外信号解码的程序编写,我们可以使用第三方的红外解码库,例如 “IRremote” 库。该库支持多种常见的红外编码格式(如 NEC、Sony、RC5、RC6 等),提供了丰富的函数接口,方便我们读取和解析红外信号。安装 “IRremote” 库的方法如下:打开 Arduino IDE,点击 “项目” 菜单,选择 “加载库”,再点击 “管理库”,在弹出的 “库管理器” 对话框中,在搜索框输入 “IRremote”,找到对应的库后,点击 “安装” 即可完成安装。
(二)库函数准备

如图当你下载好官方的库之后,可以进入库查看库函数。对于Arduino快速开发,很多常用模块都能直接找到库使用。在红色箭头处,可以看到相应的库函数。到时候直接调用库函数就行。
(二)学习使用IRremoteInt红外库函数
在学习函数前,需先了解 2 个关键数据结构 —— 它们是函数操作的数据载体:
| 数据结构 | 作用 | 核心字段(常用) |
|---|---|---|
IRData |
存储解码后的红外信号数据(新版本核心结构,替代旧版decode_results) |
protocol(协议类型,如NEC/RC5)、address(设备地址)、command(控制命令) |
decode_results |
旧版解码结果结构(已 deprecated,兼容旧代码用) | value(旧版命令值)、bits(数据位数)、isRepeat(是否为重复信号) |
1. 检查是否有信号:available()
- 函数原型:
bool available() - 作用:判断是否接收到可解码的红外信号,返回
true表示有可用信号,false表示无。 - 使用场景:在
loop()中轮询,有信号时再执行解码,避免无效计算。 - 示例:
void loop() { if (IrReceiver.available()) { // 有信号时解码 IrReceiver.decode(); // 执行解码 // 后续处理解码结果... } }
3. 解码信号:decode()
- 函数原型:
bool decode()(新版本) /bool decode(decode_results *aResults)(旧版,已废弃) - 作用:对接收的原始红外信号进行解码,将结果存入
IrReceiver.decodedIRData(新版本核心字段)。 - 返回值:
true表示解码成功,false表示解码失败(如信号不匹配已知协议)。 - 关键说明:
解码成功后,通过IrReceiver.decodedIRData获取详细信息,例如: -
IrReceiver.decodedIRData.protocol:协议类型(如NEC/RC5/SONY); IrReceiver.decodedIRData.address:设备地址(红外遥控器的 “设备标识”); IrReceiver.decodedIRData.command:控制命令(如 “电源键”“音量 +” 对应的数值)。 - 示例:
if (IrReceiver.decode()) { Serial.print("协议: "); switch(IrReceiver.decodedIRData.protocol) { case NEC: Serial.println("NEC"); break; case RC5: Serial.println("RC5"); break; default: Serial.println("未知"); } Serial.print("地址: 0x"); Serial.print(IrReceiver.decodedIRData.address, HEX); // 十六进制输出地址 Serial.print(" 命令: 0x"); Serial.println(IrReceiver.decodedIRData.command, HEX); // 十六进制输出命令 }
4. 准备接收下一个信号:resume()
- 函数原型:
void resume() - 作用:重置接收器状态,清空当前解码结果,准备接收下一个红外信号。
- 必须调用:每次
decode()成功后,若需继续接收信号,必须调用resume(),否则后续无法接收新信号。 - 示例:
if (IrReceiver.decode()) { // 处理解码结果... IrReceiver.resume(); // 重置,准备接收下一个信号 }
三、红外发送核心函数(IRsend类)
IRsend类负责生成并发送指定协议的红外信号,核心函数围绕 “初始化→发送指定协议信号” 设计:
1. 初始化发送器:begin()
- 函数原型:
无预设发送引脚时:
void begin(uint_fast8_t aSendPin, bool aEnableLEDFeedback = false, uint_fast8_t aFeedbackLEDPin = USE_DEFAULT_FEEDBACK_LED_PIN)
有预设发送引脚(定义IR_SEND_PIN)时:void begin(bool aEnableLEDFeedback = false, uint_fast8_t aFeedbackLEDPin = USE_DEFAULT_FEEDBACK_LED_PIN)
- 作用:初始化红外发送器,绑定发射引脚(如红外 LED 的引脚)、配置反馈 LED(可选)。
- 参数说明:
aSendPin:红外 LED 的控制引脚(如3);- 其他参数同
IRrecv::begin()(反馈 LED 配置)。
- 硬件注意:红外 LED 需串联 220Ω 限流电阻,避免烧毁。
- 示例:
#include <IRremote.hpp> #define IR_SEND_PIN 3 // 红外LED接3脚 void setup() { IrSender.begin(IR_SEND_PIN); // 初始化发送器 }
2. 发送 NEC 协议信号:sendNEC()
- 函数原型:
-
void sendNEC(uint16_t aAddress, uint16_t aCommand, int_fast8_t aNumberOfRepeats = NO_REPEATS) - 作用:发送NEC 协议的红外信号(最常用的红外协议,如电视、空调遥控器多采用)。
- 参数说明:
aAddress:设备地址(需与接收端匹配,如0x00);aCommand:控制命令(如 “电源” 对应0x12,“音量 +” 对应0x14);aNumberOfRepeats:重复发送次数(默认NO_REPEATS=0,即发送 1 次;设为2则发送 1 次原始信号 + 2 次重复信号)。
- 示例:发送 “NEC 协议,地址 0x00,命令 0x12” 的信号(模拟按 “电源键”):
void loop() { IrSender.sendNEC(0x00, 0x12, 0); // 地址0x00,命令0x12,不重复 Serial.println("已发送NEC信号"); delay(2000); // 每2秒发送一次 }
需要编写的代码

// 引入IRremote库
#include <IRremote.h>
const int RECV_PIN = 11;
// 创建IRrecv对象,用于接收红外信号,参数为红外接收引脚
IRrecv irrecv(RECV_PIN);
// 创建decode_results对象,存储解码后的结果
decode_results results;
void setup() {
Serial.begin(9600);
// 使能红外接收功能
irrecv.enableIRIn();
}
void loop() {
// 接收到进行解码
if (irrecv.decode(&results)) {
Serial.print("接收到的红外信号编码值(十六进制):0x");
Serial.println(results.value, HEX);
// 输出红外信号的编码格式
Serial.print("编码格式:");
switch(results.decode_type) {
case NEC:
Serial.println("NEC");
break;
case SONY:
Serial.println("SONY");
break;
case RC5:
Serial.println("RC5");
break;
case RC6:
Serial.println("RC6");
break;
default:
Serial.println("未知格式");
break;
}
// 输出红外信号的脉冲数
Serial.print("脉冲数:");
Serial.println(results.rawlen);
// 换行,使串口监视器上的输出更清晰
Serial.println();
// 准备接收下一次红外信号
irrecv.resume();
}
}
更多推荐

所有评论(0)