红外发射器入门指南:从原理到实战,打造万能遥控中心

发布时间:2026/8/3 14:11:23
红外发射器入门指南:从原理到实战,打造万能遥控中心 1. 项目概述从“万能遥控”到智能交互的桥梁最近在整理工作室的杂物翻出来好几个旧家电的遥控器电视、空调、风扇每个都得单独找麻烦不说有些老设备的遥控器早就不知所踪了。这让我想起了之前用Wio Terminal配合红外发射器做的一个小项目本质上就是打造一个“万能遥控中心”。红外发射器这个听起来有点技术宅味道的小东西其实离我们的生活非常近。你手里任何一个遥控器90%以上都是通过它来发送指令的。它的原理并不复杂就是通过一个红外发光二极管IR LED以人眼不可见的红外光脉冲形式发送特定的编码信号。接收端比如你的电视有一个红外接收头负责接收并解码这些脉冲从而执行开关机、换台、调音量等操作。这个“红外发射器入门指南”就是带你从零开始彻底搞懂这个小玩意儿。无论你是想复活一个丢失遥控器的老音箱还是想用单片机比如Arduino、ESP32或者我们这里用到的Wio Terminal来自定义控制家里的红外设备甚至是想做一些有趣的互动艺术装置比如用挥手来控制灯光变化红外通信都是一个成本极低、上手很快的切入点。它不像Wi-Fi或蓝牙那样需要复杂的配对和协议栈就是一种简单的“光通信”特别适合硬件爱好者入门嵌入式开发和物联网交互。接下来我会结合Wio Terminal这款集成了屏幕、按键和丰富接口的开发板把红外发射从硬件连接到软件编码再到实际调试的完整流程拆解清楚让你看完就能动手做出自己的红外控制器。2. 红外通信核心原理与硬件选型解析2.1 红外信号的本质不只是“亮与灭”很多人以为红外发射就是让红外灯简单地亮和灭像摩尔斯电码一样。其实不然那会导致严重的干扰和误操作。民用红外遥控普遍采用一种叫做“调制”的技术。你可以把它理解为用两种不同频率的“载波”来代表0和1。最常用的载波频率是38kHz千赫兹这意味着红外LED会以每秒38000次的极高速度闪烁。我们所要发送的数据比如“开机”这个指令会通过一种编码格式如NEC、RC5、Sony SIRC等去控制这个38kHz载波的“有”和“无”。以最常见的NEC编码为例它用一个9ms的高电平和4.5ms的低电平作为“起始信号”。紧接着是8位地址码标识设备类型比如电视品牌和8位命令码具体操作如电源键以及它们的反码用于校验。每一位数据0或1又是通过一个560微秒的载波脉冲后跟随一段低电平时间来区分的逻辑“0”是560微秒脉冲后接560微秒低电平逻辑“1”是560微秒脉冲后接1690微秒低电平。最后以一个560微秒的脉冲作为结束。整个信号就是一串精心设计的时间序列。接收头内部有一个带通滤波器专门识别38kHz附近的信号从而过滤掉环境光和其他红外光源如太阳光、白炽灯的干扰只将解调后的数字波形输出给单片机。注意不同品牌的设备可能采用完全不同的编码协议和载波频率36kHz、40kHz等。在动手前最好先确定你要控制的设备用的什么协议。一个通用的方法是先用红外接收头配合单片机录下原装遥控器的信号再分析其波形。2.2 硬件核心发射管、驱动电路与Wio Terminal的搭配红外发射部分的硬件非常简单核心就两个红外发射管IR LED和一个驱动三极管。为什么不能直接把IR LED接到Wio Terminal的GPIO引脚上因为单片机引脚的输出电流能力有限通常只有20mA左右而为了让信号有足够的发射距离和角度IR LED往往需要瞬间通过100mA甚至更大的电流。这就需要三极管来充当一个“电流开关”。硬件连接方案以Wio Terminal的D0引脚为例红外发射管IR LED注意区分正负极长脚为正阳极短脚为负阴极。NPN型三极管如S8050这是最常用的开关三极管。基极B通过一个限流电阻如220Ω-1kΩ连接到Wio Terminal的D0引脚。集电极C连接到IR LED的负极阴极。发射极E连接到电路地GND。限流电阻IR LED的正极阳极需要串联一个电阻再接到电源正极如Wio Terminal的5V或3.3V输出。这个电阻值很关键它决定了流过LED的电流大小。计算公式是R (电源电压 - LED正向压降) / 期望电流。IR LED的正向压降通常在1.2V-1.6V。如果我们用5V电源期望电流为100mA那么R (5V - 1.4V) / 0.1A 36Ω。考虑到三极管饱和时也有微小压降可以选择一个33Ω或47Ω的电阻。功率方面P I² * R 0.1² * 47 0.47W所以最好选用1/2瓦或1瓦的电阻避免发热严重。连接示意Wio Terminal 5V - 限流电阻(47Ω) - IR LED正极 - IR LED负极 - 三极管集电极(C) - 三极管发射极(E) - GND。同时Wio Terminal D0 - 基极限流电阻(1kΩ) - 三极管基极(B)。这样当D0输出高电平时三极管导通IR LED所在的回路接通LED发光发射38kHz调制光。当D0输出低电平三极管关闭LED熄灭。关于Wio Terminal它是一款基于ATSAMD51的ARM Cortex-M4开发板自带2.4英寸LCD屏幕、按键、摇杆和各种传感器接口。对于红外项目它的优势在于1有丰富的GPIO可以连接发射电路2自带屏幕可以直观地显示控制界面比如做一个遥控器菜单3支持Arduino和MicroPython生态丰富。我们这里主要使用Arduino框架进行开发。3. 软件驱动与协议模拟实战3.1 开发环境搭建与核心库选择首先确保你的Arduino IDE已经安装好并且添加了Seeed的Wio Terminal开发板支持。接下来是最关键的一步选择红外库。Arduino社区最强大、最通用的红外库是IRremoteESP8266。别看它名字里有ESP8266但它完美支持AVR、ESP32、SAMD21/SAMD51包括Wio Terminal等多种架构并且支持超过100种红外协议还能接收和发送原始信号是当之无愧的首选。在Arduino IDE的库管理中搜索“IRremoteESP8266”并安装。安装后你会在示例中找到海量的例子。为了驱动我们刚才搭建的发射电路我们需要告诉库使用哪个引脚进行发送。这里有个关键点库通常使用单片机内置的硬件PWM脉冲宽度调制定时器来生成精确的38kHz载波所以并非所有GPIO引脚都适合。对于Wio Terminal的ATSAMD51芯片大部分数字引脚都支持。我们假设使用D0引脚。3.2 编写第一个发射程序发送NEC协议信号让我们从一个最简单的例子开始发送一个NEC协议的开机码地址假设为0x00FF命令为0x15EA这是一个常见的测试码可能对应某些品牌的电视。#include Arduino.h #include IRremoteESP8266.h #include IRsend.h const uint16_t kIrLed D0; // 指定红外发射管连接的引脚 IRsend irsend(kIrLed); // 创建IRsend对象 void setup() { Serial.begin(115200); irsend.begin(); // 初始化红外发送 Serial.println(红外发射器准备就绪); } void loop() { Serial.println(发送NEC开机信号...); // 参数地址 命令 重发次数 irsend.sendNEC(0x00FF, 0x15EA, 1); delay(5000); // 每隔5秒发送一次 }上传这段代码到Wio Terminal将红外发射管对准一个支持NEC协议的设备或者用手机摄像头观察红外LED会发出微弱的紫光看看设备是否有反应比如电视指示灯闪烁。sendNEC函数的最后一个参数是重发次数NEC协议本身在发送完一帧数据后会自动发送一次重复码特殊的短脉冲这里设置为1表示发送一次完整信号加一次重复码提高接收成功率。3.3 进阶捕获、解析与重发任意遥控信号仅仅发送固定码还不够我们的目标是“学习”并控制任意设备。这就需要用到红外接收头如VS1838B、TSOP38238。它的三个引脚分别是输出接单片机GPIO、电源Vcc 通常3.3V或5V、地GND。将它连接到Wio Terminal的另一个引脚比如D1。下面是一个结合了接收和发送的完整示例实现“学习-回放”功能#include Arduino.h #include IRremoteESP8266.h #include IRrecv.h #include IRsend.h #include IRutils.h const uint16_t kRecvPin D1; // 红外接收头引脚 const uint16_t kIrLedPin D0; // 红外发射管引脚 IRrecv irrecv(kRecvPin); IRsend irsend(kIrLedPin); decode_results results; // 用于存储解码结果的结构体 void setup() { Serial.begin(115200); irrecv.enableIRIn(); // 启动红外接收 irsend.begin(); // 初始化红外发送 Serial.println(等待接收红外信号...); } void loop() { // 尝试解码接收到的信号 if (irrecv.decode(results)) { // 在串口监视器打印解码结果的详细信息 serialPrintUint64(results.value, HEX); Serial.print( (); Serial.print(typeToString(results.decode_type)); Serial.print()); Serial.print( 比特长度: ); Serial.println(results.bits); Serial.println(); // 将接收到的信号原样发送回去 Serial.println(正在回放接收到的信号...); irsend.send(results.decode_type, results.value, results.bits); irrecv.resume(); // 准备接收下一个信号 } delay(100); }上传代码后打开串口监视器用原装遥控器对准接收头按下一个键。你会在串口看到类似FF00FF(NEC) 这样的十六进制码以及协议类型。这时程序会自动将这个码用发射管发送出去。如果学习成功被控设备应该会有响应。实操心得接收头对环境光敏感尤其是日光灯和太阳光可能会产生干扰。在调试时尽量避开强光直射或者用不透光的材料稍微遮挡一下接收头。另外不同接收头的引脚顺序可能不同务必查阅其数据手册确认Vcc、GND和Out。4. 构建基于Wio Terminal的图形化遥控器4.1 利用屏幕和按键创建交互界面Wio Terminal的屏幕为我们提供了绝佳的交互可能。我们可以利用其内置的按键三个侧键和摇杆配合TFT屏幕库制作一个图形化的遥控器界面。例如我们可以画几个按钮分别对应“电源”、“音量”、“音量-”、“菜单”。首先需要安装Wio Terminal的TFT驱动库通常是Seeed_Arduino_LCD或TFT_eSPI。这里以TFT_eSPI为例它功能强大且通用。#include Arduino.h #include TFT_eSPI.h #include IRremoteESP8266.h #include IRsend.h TFT_eSPI tft TFT_eSPI(); const uint16_t kIrLed D0; IRsend irsend(kIrLed); // 假设我们已通过学习获得了以下红外码示例值 const uint64_t POWER_CODE 0xFF00FF; const uint64_t VOL_UP_CODE 0xFE01FE; const uint64_t VOL_DOWN_CODE 0xFD02FD; void drawButton(const char* label, int x, int y, int w, int h, uint16_t color) { tft.fillRoundRect(x, y, w, h, 8, color); tft.drawRoundRect(x, y, w, h, 8, TFT_WHITE); tft.setTextColor(TFT_WHITE); tft.setTextDatum(MC_DATUM); tft.drawString(label, x w/2, y h/2, 2); } void setup() { Serial.begin(115200); tft.init(); tft.setRotation(3); tft.fillScreen(TFT_BLACK); irsend.begin(); // 绘制按钮 drawButton(Power, 20, 50, 80, 40, TFT_RED); drawButton(Vol, 120, 50, 80, 40, TFT_GREEN); drawButton(Vol-, 220, 50, 80, 40, TFT_BLUE); drawButton(Menu, 120, 120, 80, 40, TFT_YELLOW); tft.setTextColor(TFT_CYAN, TFT_BLACK); tft.drawString(Wio IR Remote, tft.width()/2, 20, 4); } void loop() { // 检测屏幕触摸Wio Terminal支持电容触摸 uint16_t x, y; if (tft.getTouch(x, y)) { // 简单判断触摸区域 if (x 20 x 100 y 50 y 90) { Serial.println(Power pressed); irsend.sendNEC(POWER_CODE, 32); // 发送电源码 delay(200); // 防抖延迟 } else if (x 120 x 200 y 50 y 90) { Serial.println(Vol pressed); irsend.sendNEC(VOL_UP_CODE, 32); delay(200); } // ... 可以继续添加其他按钮的判断 } delay(50); }这个例子创建了一个简单的触摸遥控界面。你需要先用前面“学习-回放”的程序获取到你设备真实的红外码替换掉代码中的示例码POWER_CODE等。4.2 集成多协议与码库管理一个真正的“万能遥控”需要管理多个设备、多种协议。我们可以在Wio Terminal的SD卡上存储一个配置文件如JSON格式来保存不同设备、不同按键对应的红外协议和码值。{ devices: [ { name: Living Room TV, protocol: NEC, codes: { power: 0xFF00FF, vol_up: 0xFE01FE, vol_down: 0xFD02FD } }, { name: Bedroom AC, protocol: DAIKIN, codes: { power: 0x123456789ABC... } } ] }然后在程序中读取SD卡配置动态生成设备列表和按钮。当用户切换设备时从配置中加载对应的协议和码值进行发送。这涉及到文件系统操作和更复杂的UI逻辑是项目深化的方向。5. 信号调试、问题排查与性能优化5.1 常见问题与排查技巧实录即使按照步骤连接第一次尝试也常常失败。下面是一个典型的问题排查流程问题设备完全没反应。排查1检查硬件连接。用万用表测量IR LED两端在发送时的电压。发送时LED两端应有约1.4V的压降。如果没有检查三极管是否导通电阻是否接错引脚定义是否正确。排查2检查发射管。用手机摄像头对准IR LED大部分手机CMOS可以感应到近红外光。在发送信号时你应该能看到LED发出微弱的白光或紫光闪烁。如果不亮LED可能损坏或极性接反。排查3检查编码和协议。这是最常见的问题。用接收头串口监视器先确认你抓取到的原始码是否正确以及协议识别是否准确。有时库可能错误识别协议。尝试用irsend.sendRaw()函数发送原始时间数据results.rawbuf和results.rawlen这是最底层的发送方式能绕过协议判断。问题控制距离很短1米或角度很窄。排查1驱动电流不足。计算一下你的限流电阻是否过大。尝试减小限流电阻如从100Ω换到47Ω增加电流。注意不要超过IR LED的最大正向电流通常100-150mA。排查2发射管型号。不同IR LED的发射功率和角度不同。选择发射角度小如30°、功率大的型号指向性更强距离更远。也可以将2-3个IR LED并联每个仍需独立限流电阻来增强信号。排查3供电电压。尝试将发射电路的供电从3.3V改为5V在相同电阻下电流更大信号更强。问题信号时灵时不灵或控制错误。排查1环境光干扰。强烈的日光、卤素灯、某些LED灯都会发出红外线。确保接收头没有直对干扰源或者尝试在接收头前加一个深红色的滤光片只透红外光。排查2信号反射。红外光可以被墙壁、桌面反射。有时反射信号会干扰直射信号造成解码错误。调整发射器和接收器的相对位置。排查3协议重复码。有些设备需要接收到特定次数的重复码才响应。调整发送函数中的重发次数参数如sendNEC的最后一个参数。5.2 提升稳定性与扩展思路增加反馈机制对于空调等有状态反馈的设备可以增加一个红外接收头用于接收设备返回的状态码有些设备在操作后会返回确认信号实现双向通信确保指令执行成功。结合Wi-Fi/蓝牙将Wio Terminal连接网络就可以通过手机App、网页或者语音助手集成Home Assistant等平台远程发送指令让传统红外设备变身智能设备。Wio Terminal本身不支持Wi-Fi但可以通过外接ESP-01s等Wi-Fi模块实现。制作红外中继器如果设备在柜子里或者角落信号被遮挡可以在视线好的地方放置一个由Wio Terminal和红外发射管组成的“中继节点”它通过无线接收到主控器的指令再转发红外信号到设备。功耗优化如果使用电池供电需要优化功耗。在不发送信号时将红外发射电路的电源通过一个MOS管完全切断并将Wio Terminal设置为深度睡眠模式仅由定时器或外部中断唤醒。红外发射器入门之旅到这里你已经掌握了从硬件原理、电路搭建、软件编程到调试排错的全套技能。这个小项目最吸引人的地方在于它用极低的成本在物理世界和数字世界之间打开了一个直观的交互通道。我自己的体会是成功控制第一个老旧风扇转动的那一刻获得的成就感远超软件编程。过程中最花时间的往往不是代码而是举着发射管到处找角度、用串口监视器一遍遍分析波形。这些看似琐碎的调试过程恰恰是硬件项目最真实的魅力所在。最后一个小建议把你所有成功解码的遥控器编码和协议都记录下来整理成自己的“红外码库”这会是未来智能家居项目里非常宝贵的资产。

相关新闻