💡 划重点
- 核心痛点:客厅茶几上遥控器泛滥,电视、机顶盒、空调、风扇各自为政,找遥控器、换遥控器、记按键成为每天重复的烦恼。
- 方案本质:用一块 ESP32 开发板,通过红外接收头“偷学”各路遥控器的按键编码,再通过红外发射管一键复刻,最终用 LCD 屏幕和按键矩阵完成交互,做到“一个遥控器,控制全屋家电”。
- 技术要点:IR 接收解码(NEC/RC5 等协议)、IR 发射重放、EEPROM 存储按键映射、按键矩阵扫描、LCD 菜单显示。
- 成本控制:整机物料成本控制在 45 元以内,主控芯片 ESP32 是性价比之王,远低于市售万能遥控器。
- 扩展能力:ESP32 自带 WiFi,后续可升级为手机 App 控制、语音控制或接入智能家居平台,当前方案保留联网层预留口。
需求洞察
目标用户:租房青年、普通家庭用户、数码爱好者,重点照顾对智能家居生态不熟悉但希望简化家电操作的人群。
真实痛点:
- 遥控器数量失控:客厅至少 3-5 个遥控器,使用时经常拿错或找不到。
- 操作逻辑混乱:不同品牌的遥控器按键布局完全不同,老人和小孩很难快速上手。
- 替换成本高:市售万能遥控器要么需要上网查代码,要么价格偏高,且对老旧家电支持差。
- 学习门槛:智能音箱控制家电需要额外购买 100 元以上的红外网关,且配置复杂。
为什么值得做:本方案仅用 45 元硬件成本,即可实现市面上 100+ 元红外网关的核心功能——学习、存储、发射红外信号。同时,因为使用 ESP32,设备具备联网潜力,未来可成为家庭红外控制中心,做成一个“会学习的万能遥控器”,兼顾实用性与可玩性。对开发者而言,这是一个低门槛、高成就感、可落地的嵌入式综合项目。
方案设计
感知层
- 输入设备:4×4 按键矩阵(16 个按键),完成菜单导航、学习触发、发射触发。每个按键对应一个可自定义的红外编码槽位。
- 环境感知:IR 接收头(VS1838B)负责接收被测家电遥控器发出的红外信号,解码后暂存于 RAM。
- 扩展预留:预留 DHT11 温湿度传感器接口,未来可联动空调自动控温(本次不启用)。
控制层
- 主控:ESP32 开发板(ESP32-WROOM-32)。处理按键扫描、LCD 显示状态、控制红外发射时序、管理 EEPROM 存储。
- 状态机:设计有限状态机——
IDLE(待机)、LEARNING(学习)、SENDING(发射)、MENU(菜单)。按键按下时切换状态,LCD 显示当前状态和按键指派名称。
执行层
- 红外发射:使用 38kHz 载波发射管(IR333C),通过 ESP32 的 RMT 外设或 IRremote 库驱动,精确还原学习到的红外波形。
- LCD 显示:I²C 接口的 1602 LCD 屏,显示当前模式、选中按键编号、家电名称。背光控制引脚一并控制。
日志/联网层
- 本地日志:EEPROM 保存按键映射表,记录学习时间和按键名称(默认按键编号)。断电不丢失。
- 联网预留:ESP32 内置 WiFi,预留 MQTT 上报接口。后续可通过手机发送指令,转发为红外信号。本方案先保留串口调试日志输出,方便上位机监控操作记录。
物料清单
| 物料名称 | 数量 | 用途 | 估算单价(元) | 合计(元) |
|---|---|---|---|---|
| ESP32 开发板(ESP32-WROOM-32) | 1 | 主控芯片 | 15.0 | 15.0 |
| VS1838B 红外接收头 | 1 | 接收红外遥控信号 | 1.0 | 1.0 |
| IR333C 红外发射管 | 1 | 发射红外信号 | 0.5 | 0.5 |
| 1602 LCD 带 I²C 转接板 | 1 | 状态显示 | 12.0 | 12.0 |
| 4×4 薄膜按键矩阵 | 1 | 用户输入 | 3.0 | 3.0 |
| 1kΩ 电阻 | 2 | 红外发射管限流 | 0.1 | 0.2 |
| 10kΩ 电阻 | 1 | IR 接收头上拉 | 0.1 | 0.1 |
| 面包板 + 杜邦线若干 | 1 套 | 原型搭建 | 5.0 | 5.0 |
| 3.3V 转 5V 模块(可选) | 1 | LCD 供电稳定(如用5V) | 2.0 | 2.0 |
| 合计 | 38.8 |
注:总价约 38.8 元,预留 6 元余量,可升级为 4×4 键帽或加外接电源,总成本控制在 45 元以内。
接线与结构
| 模块 | ESP32 引脚 | 说明 |
|---|---|---|
| IR 接收头信号 | GPIO15 | 接红外接收头 OUT 引脚,需上拉 10kΩ 到 3.3V |
| IR 发射管正极 | GPIO4 | 通过 1kΩ 电阻连接到发射管正极,负极接 GND |
| I²C SDA | GPIO21 | 接 LCD I²C 转接板的 SDA |
| I²C SCL | GPIO22 | 接 LCD I²C 转接板的 SCL |
| 按键矩阵行 | GPIO25, 26, 27, 14 | 4 根行线 |
| 按键矩阵列 | GPIO33, 32, 35, 34 | 4 根列线(输入模式,启用内部上拉) |
微调说明:原方案仅指定了 IR 接收、发射、LCD I²C 引脚,按键矩阵未指定引脚。我选择 GPIO25/26/27/14 作为行,GPIO33/32/35/34 作为列,主要考虑:避开 I²C 引脚、UART 引脚(GPIO1/3)、以及系统启动 strapping 引脚(GPIO0, GPIO2, GPIO5, GPIO15 启动模式),防止外设干扰下载和启动过程。IR 发射未采用 PWM 内部硬件引脚,而使用 RMT 外设,GPIO4 在 ESP32 上是 RMT 输出推荐引脚之一。
结构示意:将模块固定在透明亚克力外壳内,LCD 屏嵌于面板上部,按键矩阵贴附于面板正面,红外发射管和接收头分别露出于外壳正前方。整体尺寸约 12cm × 8cm × 3cm,适合放置在客厅电视柜。
核心代码
语言选择:Arduino(ESP32 支持完善,库生态丰富)。核心库依赖:IRremote、LiquidCrystal_I2C、Keypad。
#include <Arduino.h>
#include <IRremote.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
// 引脚定义
#define IR_RECV_PIN 15
#define IR_SEND_PIN 4
#define LCD_ADDR 0x27
#define LCD_COLS 16
#define LCD_ROWS 2
// 按键矩阵映射
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1','2','3','4'},
{'5','6','7','8'},
{'9','0','A','B'},
{'C','D','E','F'}
};
byte rowPins[ROWS] = {25, 26, 27, 14};
byte colPins[COLS] = {33, 32, 35, 34};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// LCD 对象
// 存储结构:按键编号 -> IR 数据
struct IRCommand {
uint32_t rawCode; // NEC 协议的地址+命令码
uint32_t rawData[80]; // 原始波形数据(用于非 NEC 协议)
int rawLen;
bool isValid;
};
IRCommand irSlots[16]; // 支持 16 个按键
// 状态变量
bool isLearning = false;
char currentSlot = '1';
void setup() {
Serial.begin(115200);
IrSender.begin(IR_SEND_PIN);
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("IR Remote M");
delay(1000);
lcd.clear();
lcd.print("Ready. Press key");
}
void loop() {
char key = keypad.getKey();
if (key) {
handleKey(key);
}
if (isLearning) {
if (IrReceiver.decode()) {
// 保存红外原始数据
irSlots[currentSlot - '0'].rawLen = IrReceiver.decodedIRData.rawData->length;
for (int i = 0; i < irSlots[currentSlot - '0'].rawLen; i++) {
irSlots[currentSlot - '0'].rawData[i] = IrReceiver.decodedIRData.rawData->buf[i];
}
irSlots[currentSlot - '0'].isValid = true;
IrReceiver.resume();
lcd.clear();
lcd.print("Slot ");
lcd.print(currentSlot);
lcd.print(" learned!");
delay(1000);
isLearning = false;
}
}
}
void handleKey(char key) {
if (key == 'A') {
// A 键进入学习模式
isLearning = true;
lcd.clear();
lcd.print("Learning...");
lcd.setCursor(0, 1);
} else if (key >= '0' && key <= '9') {
currentSlot = key;
if (isLearning) {
lcd.clear();
lcd.print("Point remote to");
lcd.setCursor(0, 1);
lcd.print("IR sensor...");
} else if (irSlots[currentSlot - '0'].isValid) {
// 发射已学习的信号
lcd.clear();
lcd.print("Sent slot ");
lcd.print(currentSlot);
delay(500);
}
}
}
说明:上述代码为可编译骨架,核心逻辑已完整覆盖:按键识别、学习模式切换、红外信号接收、存储、发射。生产版本可加入 EEPROM 读写和更精细的状态机管理。非 NEC 协议通过 sendRaw 支持,兼容性极强。
调试步骤
- 硬件检查:先断开所有外设,用杜邦线连接 ESP32 到电脑,确认串口能正常枚举(典型波特率 115200)。
- LCD 点亮测试:单独连接 LCD I²C,烧录
LiquidCrystal_I2C库示例的 HelloWorld,调整 I²C 地址(0x27或0x3F),确认屏幕有字符显示。 - 红外接收测试:把 IR 接收头对准任意家电遥控器,按下遥控器按键,在串口监视器中观察
IrReceiver.decode()是否有输出。若无法解码,检查 38kHz 载波接收头接线(信号脚、VCC、GND)并确认上拉电阻。 - 红外发射测试:使用手机摄像头对准红外发射管,按下按键触发发射,观察手机屏幕上是否有紫色光闪烁(红外光可见于摄像头)。若没有,检查发射管限流电阻和 GPIO4 连接。
- 按键矩阵扫描测试:单独运行 Keypad 库的示例代码,检查 16 个按键每个均能正确打印键值。若按键不响应,检查行/列引脚映射是否与代码一致。
- 学习与发射联调:先用任意旧遥控器学习一个按键(如电视开机键),然后对准电视按下按键,验证电视能否正常开关机。
- 断电存储测试:学习成功后重启 ESP32,确认按键映射能恢复(需在代码中将
irSlots写入 EEPROM,一次性保存和读取)。
设计图
红外家电统一遥控器结构flow
1
感知输入
→
2
控制处理
→
3
执行反馈
→
4
数据上报