ESP32接VS1838B:红外NEC解码与按键控制

2026-11-03 13:19:08 31阅读

家里遥控器一大堆,电视的、机顶盒的、风扇的,坏一个遥控器整套设备就变摆设。其实这些遥控器全都能被 ESP32 读懂:加一个几块钱的红外接收头,三根线接上,串口里就能打出每个按键的十六进制码。这篇把接线、装库、读码、按键触发动作整套流程走一遍,坑也都标出来。

ESP32与红外接收头三线接线图

全套硬件就这么点:一块 ESP32 开发板、一个红外接收头、几根杜邦线。接收头常见型号是 VS1838B 和 TSOP38238,都是 38kHz 载波的解调一体器件,接收、放大、解调在内部一次做完,输出的已经是数字信号,ESP32 拿普通 GPIO 直接读。

先认器件:38kHz 解调头,几块钱搞定

红外接收头市面上最常见的就是 VS1838B 和 TSOP38238,引脚都是三根:VCC、GND、OUT。它内部把 38kHz 载波解调掉,输出端给的是还原好的脉冲序列,单片机这边不需要任何载波处理。价格上这类接收头单颗普遍几毛到一两块钱;遥控器如果家里有现成的旧遥控,一分钱不用花。

挑的时候注意一点:不同型号接收头的引脚排列可能不一样,有的正对自己从左到右是 OUT、GND、VCC,有的反过来。动手前先核对手头这颗的引脚定义,接反了轻则读不到码,重则器件发热损坏。

ESP32红外接收实验全景:遥控器、接收头与开发板

整套实验的全景就是这样:遥控器负责发射,接收头负责解调,ESP32 负责把脉冲翻译成数字码。下面开始接线。

接线:三根线,供电认准 3.3V

接线只有三根:接收头的 VCC 接 ESP32 的 3.3V,GND 接 GND,OUT(有的丝印标 DAT 或 S)接 GPIO15。供电认准 3.3V,ESP32 的 GPIO 耐压就是 3.3V,虽然不少接收头标称宽压都能工作,但为了不给 IO 口引入 5V 电平风险,统一按 3.3V 接。

红外接收头与ESP32开发板电路连接示意

关于接收脚还有一句提醒:GPIO15 能用,但它是 boot strapping 引脚,外接电路尽量别再挂上拉或下拉,免得干扰上电时序。嫌拘束可以换 GPIO14、GPIO23 这类无启动依赖的脚,把代码里的 RECV_PIN 改成对应编号就行。

装库与烧录:IRremote 一个库全包

环境按常规 Arduino-ESP32 流程走:装好 ESP32 开发板支持包,板型选对,串口选对。库管理器里搜 IRremote,作者是 Armin Joachimsmeyer,装最新版即可,解码和发码都靠它。

烧录这步新手最容易卡在串口上。板子插上后 IDE 里找不到端口,多半是 CP210x 或 CH340 驱动没装,装好驱动端口就出来了。上传时如果一直停在 connecting...,按住板子上的 BOOT 键再点上传,进下载模式就能过。烧完打开串口监视器,波特率 115200。

第一段代码:把每个按键读出来

先上最基础的读码程序。头文件这里用双引号包含 IRremote.hpp,和尖括号写法在 Arduino 的库搜索路径下等价:

/*
  Filename: ol_ir_remote.ino
  Description: Reads IR remote signals using ESP32
  Author: www.oceanlabz.in
  Modification: 1/4/2025
*/

#include "IRremote.hpp"

#define RECV_PIN 15

void setup() {
  Serial.begin(115200);

  // Initialize IR Receiver
  IrReceiver.begin(RECV_PIN, ENABLE_LED_FEEDBACK);
}

void loop() {
  if (IrReceiver.decode()) {

    Serial.print("Received Value: ");
    Serial.println(IrReceiver.decodedIRData.decodedRawData, HEX);

    // Ready to receive the next signal
    IrReceiver.resume();
  }
}

上传完拿遥控器对准接收头按按键,每个键会打印出一个十六进制值,这就是这个键的原始码。把常用的键抄下来记好,后面触发动作全靠这批值。

看懂打印:NEC 帧、地址与命令

上一段打印的是 decodedRawData 原始值;想看得更细,IRremote 自带的解析还能把协议名、地址、命令分开打出来。家用遥控最常见的是 NEC 协议:38kHz 载波,一帧里带着地址和命令两部分,接收头解调后 IRremote 直接帮你拆好。按住同一个键不放,遥控器会连发重复帧,串口里就刷一串相同的值。

KEYES红外遥控器NEC键值码表

拿常见的 KEYES 小遥控举例,↑键 FF02FD、←键 FF22DD、→键 FFC23D。不同遥控的码表各不相同,以自己实读出来的为准,别照抄别人的表。

第二段代码:按键触发动作

读到码就能触发动作。下面这段把接收脚定义成 23,按到 0x45 这个键码就翻转 GPIO2 上的板载 LED。换成你自己的遥控时,把 case 里的值改成上一步实读的码:

#include "Arduino.h"
#include "IRremote.h"

#define IR_RECEIVE_PIN 23
#define LED_PIN 2

bool LED = false;

void setup() {
  Serial.begin(115200);
  pinMode(LED_PIN, OUTPUT);
  IrReceiver.begin(IR_RECEIVE_PIN, DISABLE_LED_FEEDBACK);
  Serial.println("IR Receiver Ready");
}

void loop() {
  if (IrReceiver.decode()) {
    uint8_t command = IrReceiver.decodedIRData.command;
    switch (command) {
      case 0x45: // Example button code
        Serial.println("Power button pressed!");
        digitalWrite(LED_PIN, LED);
        LED = !LED;
        break;
      case 0x46:
        Serial.println("Another button was pressed!");
        break;
      // Add more cases as needed
    }
    IrReceiver.resume();
  }
}

两个脚本放一起看就清楚了:读码脚本负责抄表,触发脚本负责办事。查表、比对、执行,这就是所有红外遥控改造项目的骨架。

收不到码、打乱码:按顺序排查

收不到码,依次查四样。一看供电,接收头 VCC 是不是真落在 3.3V 上,GND 有没有和 ESP32 共地;二看波特率,串口监视器必须 115200,对不上就全是乱码;三看距离和角度,红外是视距通信,接收窗要正对遥控器,中间别挡外壳;四看环境,阳光直射和强红外源会让接收头打出随机码,挪个背光位置再试。

如果串口有输出但协议显示 UNKNOWN,说明这颗遥控用的不是 IRremote 默认支持的协议,或者帧格式比较特殊。读码学习不受影响,想走存码重放那条路,得换对应协议的发送接口。另外发射和接收不是一回事:要用 ESP32 发红外,得加一颗 940nm 发射管,而且不能让 GPIO 直接驱动,要经三极管加限流电阻去推,这部分留到下一篇展开。

跑通之后,路就宽了

这一步通了以后可以接着玩:拿读到的码去控继电器和灯,把旧遥控变成智能控制的触发器;配一颗发射管做成万能遥控;接 Home Assistant 这类平台做场景联动。整套器件成本不到十块钱,是传感器入门里性价比最高的实验之一。

实际操作里最常见的坑还是两条:引脚顺序接反、串口波特率没对上。先查这两样再动代码,能省掉大半折腾时间。你还踩过哪些红外接收的坑,评论区报上来。


作者:固件烧录仔
链接:https://www.aiddithome.com/p/1bef93a6478f32.html
本作版权归作者所有,未经允许请勿转载。若存在违规行为,您可以点击 “举报”。


登录 后发表评论
4条评论
隔壁工位的好奇宝
1楼 · 2026-11-03 13:20:01

发射那部分什么时候写?想拿 ESP32 控制空调,就差 IR LED 加三极管那一段了。

老张装机
2楼 · 2026-11-03 13:20:00

这个接线我上个月刚踩过坑,VS1838B 正面看和背面看的引脚顺序是镜像的,照着丝印接反了,折腾半天以为接收头坏了。后来按 3.3V 重新接,串口立刻出码。另外 GPIO15 那个提醒很实在,我第一版代码没事,第二版加了外部上拉之后偶尔开机异常,换到 GPIO27 就再没出现过。新手一定先核对引脚定义再插线。

拆机党
3楼 · 2026-11-03 13:20:00

按住键会连发重复帧这个细节有用,昨天做长按调亮度正好用上。

第三次终于亮了
4楼 · 2026-11-03 13:20:00

串口乱码先查波特率这条是真的,我上次 9600 对 115200 折腾了一晚上才反应过来。