ESP32-S3 红外接收
·
ESP32-S3 红外接收
红外信号需要搭载在一个固定频率的“载波”上发射,以减少环境光干扰。接收头必须选择与发射端匹配的频率才能正确接收。常见的频率有38kHz(最主流)、36kHz、40kHz、56.7kHz等。你的遥控器和接收头必须“同频”,才能“共振”通信。如果频率不匹配,会导致接收距离变短甚至完全无法接收。
不同的家电厂商发展出了多种通信协议,它们在地址码、命令码、数据格式和重复码上都有各自的规定。常见的包括:
NEC协议:使用最广泛的协议之一,采用脉冲宽度调制,具有8位地址和8位命令。
飞利浦RC-5 / RC-6协议:采用脉冲位置调制,有固定的编码结构。
索尼SIRC协议:索尼设备常用,有12位、15位和20位等多种数据格式。
其他:如你之前提到的三星、LG、JVC、松下等,都有各自定义的协议。
点击 牛瘪汤 主页可以了解更多。
1. 核查原理图
ESP32 S3 红外接收使用 TOP75238TR 双红外接收头,接收更稳定。供电范围 3-5V。

追查原理图 IR_RX 与 IO7 连接,记住端口等下要用。
2. 编写测试 demo
以下是基于ESP32-S3与红外接收模块(连接IO7引脚)的Arduino代码,使用IRMP库实现多种红外协议(NEC、SONY、RC5、RC6、Panasonic、LG、JVC、SAMSUNG、Whynter、COOLIX)的解码检测,并包含RAW原始信号识别。代码会打印出协议名称、地址、命令等信息,对RAW信号输出长度和首脉冲宽度。
#include <Arduino.h>
#include <IRremoteESP8266.h>
#include <IRrecv.h>
#include <IRutils.h>
// ==== 配置参数 =====
const uint16_t kRecvPin = 7; // 红外接收头连接到 GPIO7
const uint32_t kBaudRate = 115200; // 串口通讯波特率
const uint16_t kCaptureBufferSize = 1024; // 捕获缓冲区大小 (单位: 毫秒), 通常 1024 足够
// 在多协议解码时,建议开启超时设置,以适应长信号(如空调)
const uint8_t kTimeout = 15; // 关闭超时: 0; 典型值: 15 或 50 毫秒
// ===================
// 初始化红外接收对象
IRrecv irrecv(kRecvPin, kCaptureBufferSize, kTimeout, true);
decode_results results; // 用于存储解码结果的结构体
void setup() {
// 初始化串口,用于打印解码信息
Serial.begin(kBaudRate);
while (!Serial) // 等待串口连接(针对部分开发板)
delay(50);
Serial.println("\n" __FILE__);
Serial.print("IRrecv multi-protocol decoding is now running and waiting for remote signal on GPIO ");
Serial.println(kRecvPin);
// 启用红外接收器
irrecv.enableIRIn();
#if DECODE_HASH
// 如果需要解码未知协议的原始信号,必须启用 HASH 解码。
// 这允许库将无法识别的协议作为原始数据转储。
irrecv.setUnknownThreshold(1); // 可选: 设置未知解码的最小长度
#endif
Serial.println("Ready to receive IR signals.");
}
void loop() {
// 检查是否解码到信号
if (irrecv.decode(&results)) {
// 调用函数打印解码结果
printDecodedResults(&results);
// 打印信号的原始数据(时序)到串口,有助于分析未知协议
Serial.println(resultToHumanReadableBasic(&results));
// 必须调用 resume() 来准备接收下一个信号
irrecv.resume();
}
delay(100); // 简单的防抖动延迟,避免串口输出过快
}
/**
* 打印解码结果的详细信息。
* 根据协议类型,格式化输出协议名称、地址、命令、数值等。
* @param results 指向 decode_results 结构体的指针
*/
void printDecodedResults(decode_results *results) {
// 输出协议名称
Serial.print("Protocol: ");
Serial.print(typeToString(results->decode_type, results->repeat)); // 使用库函数获取协议名
// 如果是未知协议,输出 Hash 值便于识别
if (results->decode_type == decode_type_t::UNKNOWN) {
Serial.print(" (Hash: 0x");
Serial.print(results->value, HEX);
Serial.print(")");
}
Serial.print("\t");
// 打印协议相关的具体数值(地址、命令、数据值等)
// 使用库提供的函数 resultToHumanReadableBasic 也可以输出类似信息,
// 但为了更清晰的展示,我们手动解析几个常见字段。
if (results->decode_type != decode_type_t::UNKNOWN) {
// 打印数据值 (Value)
Serial.print("Value: 0x");
Serial.print(results->value, HEX);
// 打印地址 (Address) - 很多协议有这个字段
if (results->address > 0 || results->command > 0) { // 简单的判断,避免打印无意义的 0
Serial.print("\tAddr: 0x");
Serial.print(results->address, HEX);
Serial.print("\tCmd: 0x");
Serial.print(results->command, HEX);
}
// 打印位数
Serial.print("\tBits: ");
Serial.print(results->bits);
}
Serial.println(); // 换行
}
接收到红外遥控,可以看到日志。
IRrecv multi-protocol decoding is now running and waiting for remote signal on GPIO 7
Ready to receive IR signals.
Protocol: NEC Value: 0x27D00FF Addr: 0xDF80 Cmd: 0x0 Bits: 32
Protocol : NEC
Code : 0x27D00FF (32 Bits)
Protocol: NEC Value: 0x27D48B7 Addr: 0xDF80 Cmd: 0x12 Bits: 32
Protocol : NEC
Code : 0x27D48B7 (32 Bits)
结语
文章都看到完了,就不点个关注吗,老铁!
欢迎关注博主–牛瘪汤 。
更多推荐
所有评论(0)