ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

ESP8266红外控制器:美的空调协议解析与HA接入

ESP8266红外控制器:美的空调协议解析与HA接入 智能家居玩了几年我最深的体会是空调这种东西厂商压根没想过让你好好做自动化。手里的美的遥控器面板上那一堆模式、风速、摆风选项几乎没有一个万能遥控器能完美复刻。网上抄来的红外码经常是“开关能用、调温失灵”归根结底是没搞懂协议本身。这篇就从头聊一次怎么用ESP8266加一个几毛钱的红外发射管把普通美的空调接进Home Assistant重点是协议解析的过程、发射电路的坑、以及HA里的自动化写法。先说明白这个项目能干什么手机或语音控制开关机、切模式、调温度配合温湿度传感器实现“屋里超过30℃自动开制冷26℃”离家自动关空调。难点不在ESP8266本身而在红外协议解析——美的空调用的不是标准NEC遥控码而是一种“完整状态帧”每次按键发出去的都包含当前全部设定信息。把这块啃下来后面所有方案都能顺理成章推进。适合谁看有一定Arduino或ESPHome基础想折腾智能家居但不想买成品网关的人。成品红外网关虽然省事但六七十块钱起步协议也是别人写好的出了问题没法改。自己动手这套全套成本控制在二十块钱以内还能顺带掌握红外协议解析的通用套路以后控制电视、风扇、投影仪都是同一套方法论。1. 方案选型为什么自己拼一个ESP8266红外控制器1.1 三种常见方案的对比先说说市面上现成的路子免得你绕弯路。我用过成品空调伴侣也玩过带红外的智能音箱总体来说各有利弊。方案成本协议自由度HA集成度可维护性成品空调伴侣60-150元只有厂商预设的码库看品牌部分有官方或第三方集成云服务挂了就废智能音箱红外版100-300元同样受限且依赖云端通常要桥接隐私和稳定性都一般ESP8266红外管自做15-25元完全自主想发什么码就发什么码原生ESPHome/MQTT接入全本地化坏了换块板子重新刷成品方案最大的问题是“黑盒”。你没法看到它到底发了什么码也没法自定义一套符合家里空调机型的完整状态控制。特别是一些老款美的空调成品伴侣码库里根本没有只能走“学习模式”而学习来的码往往只有开关机有效调温就抓瞎。原因我在下一章详细说。1.2 为什么选ESP8266而不是其他开发板ESP8266在智能家居DIY里地位一直很稳原因就三个便宜、联网、资料多。一块NodeMCU或D1 mini现在十几块钱板载Wi-Fi直接跟Home Assistant走局域网通信不依赖云端。相比ESP32红外控制这种简单场景用ESP8266完全够而且IRremoteESP8266这个库在ESP8266上的优化很成熟软件生成38kHz载波没有问题。有人会问ESP8266没有红外硬件功能能用吗能用。红外遥控的本质就是“38kHz的载波用不同的脉冲宽度来编码0和1”ESP8266虽然没内置红外发射外设但可以靠IO口的高低电平配合定时器/软件PWM精确翻转IRremoteESP8266库已经把时序算好了你只需要告诉它“用哪个引脚发射”。实测下来只要引脚选择正确、驱动电路不出问题时序是稳定的。还有一层原因ESP8266能顺便把温湿度传感器接了。做空调自动化核心逻辑永远是“温度到了就开/关”板载读一个DHT22或SHT30再联动发红外码整个闭环就通了。后期想扩展灯带、窗帘之类也都在同一块板子上。2. 红外协议解析拆掉美的空调遥控器的“黑盒”2.1 红外遥控的基础38kHz载波与NEC编码先说底层原理不然后面抓码、改码你都不知道在改什么。红外遥控发射的是波长940nm左右的红外光肉眼看不见而接收头内部有光电二极管和解调芯片。为了让信号在环境光干扰下也能被准确接收发送端会先把数据调制到38kHz的载波上——简单理解就是“以每秒三万八千次的频率快速闪烁红外光”接收端只认这个频率的光其他频段的光直接忽略。数据编码方式常见的是NEC协议。NEC用脉冲宽度表示0和1完整的帧包括引导码、地址码、地址反码、命令码、命令反码。逻辑1与逻辑0的区别在于载波电平持续后跟的空闲时间长短逻辑1一般是560us载波加1680us空闲逻辑0则是560us载波加560us空闲。引导码通常是9ms载波加4.5ms空闲用来告诉接收头“一帧数据开始了”。但空调遥控器不太一样。电视遥控器是按一下发一个键码空调遥控器要同时传达温度、模式、风速、摆风、定时等一大串状态因此很多厂商都改成“完整状态帧”编码一帧里几乎包含所有设定参数的当前值。这也是为什么你没法简单用“学习电视遥控”的思路搞定空调。2.2 美的空调协议的特殊性美的空调的红外协议在圈子里出了名的“不按套路出牌”。它用的不是标准NEC的32位帧很多机型是48位自定义格式协议源码在IRremoteESP8266库里被命名为Midea协议。每一帧数据不是一个简单的“按键码”而是把当前遥控器上所有状态打包之后整体发送。举个例子说明这个区别美的遥控器上你按一下“温度”发出来的不是“温度加一”这个命令而是“我把当前所有状态改成温度26℃、制冷、自动风、摆风关闭”的完整状态帧。如果只抓到一个“电源键”的码单独重放确实能开关机但空调此时是“无状态”的你没法通过一个单纯的调温码去改变当前温度因为根本没这个设计。更麻烦的是美的不同年份、不同系列的空调帧格式还有差异。同一套红外码拿给同品牌另一台空调经常“有反应但不完全响应”。所以别指望网上抄一段代码就通吃所有美的空调最稳妥的办法就是抓自己遥控器的码然后自己做字段拆解。2.3 实际抓码流程逻辑分析仪加IRrecvDump我的做法分两条路并行一条是用IRremoteESP8266库的示例程序直接解码另一条是用逻辑分析仪看原始波形。需要准备的硬件很简单一个VS1838B一体化红外接收头三根杜邦线一块逻辑分析仪24MHz带宽的就够。VS1838B是38kHz载波接收头输出低电平有效接法非常固定VCC接3.3V或5VGND接地OUT接逻辑分析仪的某个通道。软件方面先装好Arduino IDE安装IRremoteESP8266库打开它的示例程序IRrecvDumpV2烧录到已经接好接收头的ESP8266上。烧录后用遥控器对准接收头按一下你要学习的那个按键串口监视器里就会输出解析结果包括Protocol、Bits、Code和RawData。抓码时几个细节要注意电池要新遥控器电量低时波形会变形导致解码出来一堆UNKNOWN。操作时距离接收头10-30厘米左右太远波形会有毛刺太近容易过载。按键按一下就行不要长按或连按否则会混入重复帧干扰字段拆解。环境里的节能灯、阳光直射都会干扰接收头尽量在拉上窗帘的室内操作。逻辑分析仪的作用在于看“真实波形”。IRrecvDump输出的RawData本质上就是一个个时间间隔比如9000、4500、560、1680这种数组它代表载波持续时间和空闲时间。如果你只靠解码器输出一旦库不认识这种协议字段含义就完全瞎了。用逻辑分析仪看波形能自己数引导码长度、数据位宽度即使没有现成解码器也能手工把每一位数据抠出来。2.4 示例一个48位码的含义拆解这里拿我实际抓过的一台美的柜机举例。解码出来是一串48位十六进制比如0xA2400000042C12个十六进制字符就是48位。不同机器这个值一定不一样重点是看拆解思路。用二进制表示大概是1010 0010 0100 0000 0000 0000 0000 0000 0000 0100 0010 1100我对照不同按键抓了几十组码总结出这台机器的字段布局大致是这样注意这是示意不是通用标准位段含义说明高8位设备标识/厂商字段固定不变次高8位固定参数区通常不变中间若干位电源、模式、风速、摆风状态每个状态占用若干bit温度字段目标温度编码常见是“设定温度减16”偏移末尾若干位校验码多数是前几字节累加取低字节我实测时发现把温度从17℃调到30℃十六进制里只有一个位置的数值跟着变并且变化规律是“设定温度减16”。也就是17℃对应某个值的起始点每加一度数值加一到30℃刚好加13。这类规律是拆解协议时最有价值的发现因为它意味着你不需要穷举所有温度和模式的组合只需要抓几组边界值就能推算出完整编码规则。校验码的问题必须重点提。美的不少机型帧尾有校验位直接抓码重放时空调会正常响应但如果手动改了温度字段后不重新计算校验空调会直接忽略这帧数据表现是“完全没反应连指示灯都不闪一下”。我一开始就是抱着“改一个字节就发”的心态折腾了一个多小时才发现是校验的问题。判断方法也很简单抓两个只有温度不同、其他状态完全相同的码比较除温度和末尾字节之外的位段有没有变如果变了那个位置就是校验或者与被改动字段有联动关系。3. 硬件制作ESP8266加红外发射管的驱动电路细节3.1 元件清单与电路连接协议搞明白之后就到真正干活的环节了。全套元件如下ESP8266开发板一块建议NodeMCU或D1 mini带USB口方便烧录调试。940nm红外发射管选5mm直插的几毛钱一个多买几个备用。NPN三极管8050一只用来放大驱动电流。电阻基极1kΩ一个发射极限流10Ω一个。VS1838B红外接收头一个前面抓码用后面调试返查也用得上。面包板、杜邦线若干。后期定稿了可以焊在洞洞板上。电路连接我直接给你可照抄的接线ESP8266 GPIO4 → 1kΩ电阻 → 8050三极管基极(B) 8050三极管发射极(E) → GND 8050三极管集电极(C) → 红外发射管负极 红外发射管正极 → 10Ω限流电阻 → 5V或3.3V三极管的作用很关键。ESP8266的GPIO输出能力有限直接推红外发射管虽然能亮但发射距离通常只有几十厘米对着空调隔两三米就收不到。加了8050之后等于用GPIO做了一个“开关”由外部电源提供真正驱动电流红外管能工作在接近额定的电流下实测距离可以到5米以上覆盖普通卧室没有任何问题。3.2 载波频率、发射角度与多发管扩展发射管发射的红外光波长是940nm人眼完全看不见但手机摄像头通常能捕捉到一点紫色光点。调试时把手机相机打开对着发射管按下发送时能看到微弱的闪动这是一个非常实用的自检手段能快速判断GPIO和驱动电路有没有工作。发射角度有个容易被忽略的坑。红外发射管虽然有20度左右的视角但空调内机的红外接收窗通常只在面板正中央一个小范围如果你的ESP8266板子放在空调侧面发射角度偏了距离再近也可能收不到。解决方法是把发射管装上空调面板附近或者用杜邦线引出来贴在空调下方正对接收窗的位置。实在不行就并联两三只发射管每只单独串一个10Ω限流电阻朝向不同方向覆盖范围能大不少。载波频率方面绝大多数空调遥控器是38kHz但少数机型是36kHz或40kHz。如果你发现波形明明正确、发射管也在闪空调就是没反应去查一下自己空调的载波频率在代码里把发送频率改掉再试。IRremoteESP8266库和ESPHome的transmit_raw都支持自定义载波频率改一个参数的事。3.3 固件选型ESPHome还是自写Arduino硬件搭好后固件方案我推荐优先选ESPHome原因很实际配置即代码、原生接入Home Assistant、OTA升级方便不用自己维护MQTT连接逻辑。自写Arduino的好处是完全自由但你需要自己处理网络重连、MQTT topic、HA实体发现等一堆周边问题为了控制一个空调这个成本不值。Tasmota也是个选项自带红外发送功能但它的红外系统更偏向于“学习-重放”场景对自定义字段计算支持不好。我们的场景是要根据当前温度动态计算出完整的红外状态帧Tasmota的灵活性就差了不少。ESP8266的固件选择本质上是“你要不要写代码”。ESPHome虽然也是写YAML配置但底层已经有完整的红外组件、传感器组件、自动化组件你要做的只是把协议的发送逻辑填进去出问题的概率小得多。下一章直接给出完整配置。4. 从发送到自动化接入Home Assistant4.1 ESPHome配置与代码ESPHome接入Home Assistant是目前最顺滑的路径。先给出一份能直接用的ESPHome YAML配置骨架esphome: name: ac-controller platform: ESP8266 board: nodemcuv2 wifi: ssid: 你的WiFi名 password: 你的WiFi密码 api: encryption: key: 生成一个32字节base64密钥 logger: ota: platform: esphome password: OTA密码 remote_transmitter: pin: number: GPIO4 inverted: false carrier_duty_percent: 50% sensor: - platform: dht pin: GPIO5 temperature: name: Bedroom Temperature humidity: name: Bedroom Humidity update_interval: 60s这份配置里最关键的是remote_transmitter组件。pin指定发射管接的GPIO口carrier_duty_percent是载波占空比一般保持50%默认即可。注意GPIO4在NodeMCU板子上丝印标的是D2不同板子丝印不同以实际原理图为准。发送红外码我这里建议用transmit_raw动作直接发原始raw数组。为什么不用协议内置的sendMidea函数因为不同美的机型帧格式有差异而raw数组是从你实际抓码得到的最保真。EspHome中的remote_transmitter.transmit_raw写法如下script: - id: send_ac_midea parameters: code: int[] then: - remote_transmitter.transmit_raw: carrier_frequency: 38kHz data: !lambda return code;实际发送时把抓到的raw数组传进去就行。这里有一个重要细节红外码发送不能太频繁。空调每收一帧完整状态码之后会有处理时间如果你在几毫秒内连续发送多帧空调可能只响应第一帧或直接忽略全部。我在自动化里通常会给发送动作加一个至少100ms的延时确保空调能稳定处理。4.2 Home Assistant实体与仪表盘配置ESPHome设备接入HA后传感器、脚本实体都会自动出现。但直接用script实体在界面上操作体验很原始因为你需要一个“温度模式”的可视化面板。我的做法是在Home Assistant里定义几个辅助实体input_select: ac_mode: name: 空调模式 options: - 制冷 - 制热 - 除湿 - 送风 - 自动 input_number: ac_temperature: name: 目标温度 min: 17 max: 30 step: 1 unit_of_measurement: °C然后写自动化监听这两个实体只要值变化就调用ESPhome中的发送脚本附带根据当前模式、温度生成的红外raw码。为了不让自动化逻辑写得太长建议把“模式温度到码”的映射提前算好放进一个Python Script或模板传感器里让自动化只负责发码。一个更进阶的做法是直接把ESPHome的脚本参数设置为“传入模式和温度”在lambda里用C代码动态计算完整状态帧并发送这样Home Assistant只需要调用一个脚本服务所有协议换算逻辑都封在里面更新维护都方便。4.3 自动化场景示例接入之后自动化能玩的花样就多了。我实际在用的几个简单场景离家自动关空调。HA里装好离家检测手机GPS或是路由器设备跟踪状态变为离家时调用发送脚本发一帧“关机”码。这个场景对红外控制来说是最稳的因为关机码不牵扯状态同步。温度联动。卧室放了一个DHT22配合空调当温度高于30℃且当前不是制冷模式时自动发一帧“制冷26℃”的码当温度降到24℃以下时发一帧关机码。注意这里要防止频繁启停自动化里加一个冷却时间比如至少运行15分钟才能执行下一次关机动作。起床前自动调温。用HA的时间触发早上6点半自动发一帧“制热23℃”的码冬天起床舒适度提升非常明显。这个场景最大的好处是改造成本为零——原来的遥控器继续放在床头手动操作依然有效。5. 常见问题与排查我的踩坑记录5.1 发送没反应怎么办这是所有人都逃不掉的第一步。按照这个顺序查能省几个小时。先确认代码真的执行了。ESPHome日志里会有发送动作的提示同时手机摄像头对准红外发射管发送瞬间能看到微弱的紫色光点。如果没有光点查接线和三极管电路多半是GPIO定义错了或者三极管引脚接反。如果光点有但空调没反应下一步查载波频率把38kHz改成36kHz试试。还要确认空调的红外接收窗真在你发射范围内。我踩过一个坑把板子塞在电视柜里发射角度倾斜空调在墙对面收不到信号。后来把发射管用杜邦线引出来贴在空调正下方的踢脚线上问题立刻解决。5.2 码是对的但只响了一次“学习码重放”场景里经常遇到手动对着遥控器按一下空调响应把这段码存到HA里自动发送第一次也响应第二次空调就没动静了。出现这个现象十有八九是红外码发了两遍或发太快。ESPHome的自动化如果同时触发多个脚本比如模式切换和温度调整同时发生可能连续发了两帧而中间没有足够的间隔时间。空调收到连续帧时可能只解析最后一帧而最后一帧的状态恰好是你不需要的。解决方案是在脚本调用之间加delay: 500ms给空调一个稳定的处理窗口。5.3 抓码不准或RawData太短IRrecvDump输出里看到Protocol为UNKNOWN、Bits不固定或者RawData数组长度明显少于预期的基本都是抓码环境有问题。电池电量不足是最大的干扰源遥控器快没电时按键发出的红外“啵啵”不脆波形就是一团糟。其次是周围的节能灯这种灯的红外辐射很强接收头很容易被干扰抓码时最好把接收头拿手遮一下或者干脆换到暗处。另一个细节是IRrecvDumpV2默认会把超长数据截断特别是空调这种48位状态帧协议解析器有时候只输出前32位。这时用逻辑分析仪看原始波形最靠谱把整个脉冲序列录下来按时间轴数数据位。虽然笨但对理解协议帮助很大。5.4 Home Assistant自动化重复触发空调自动化最让人头疼的问题就是“明明停了过一会儿又自己开了”。根源在于状态不同步。红外遥控是单向通信空调根本没有回传“当前温度”“当前运行模式”的能力HA里存的目标温度可能早就和空调实际状态不一致了。所以做空调自动化时尽量把控制策略改成“按绝对状态发码”而不是“按当前状态做增量调整”。要开就明确发“制冷26℃开机”要关就发“关机”不要只发一个“温度加一”之类的增量操作。这样即使HA状态丢失重发一次完整状态帧也能让空调回到预期状态。另加一个自动化冷却时间比如用mode: restart加delay避免传感器读数抖动导致反复控制。5.5 常见问题速查表现象可能原因处理方法红外管不发光接线错误、GPIO定义错误、板子没跑起来用手机摄像头自检检查线路与日志发光但空调没反应载波频率不对、发射角度偏、距离太远改载波频率调整发射管朝向与位置码存了但重放不对对比遥控器和HaState不同、校验位不完整抓自己的码验证整帧包含校验位温度能调但开不了机制热/制冷字段拆解错误、校验没重算拆解不同模式码按字段布局重算校验HA自动控制与手动遥控冲突状态不同步、重复触发用完整状态帧加冷却延时5.6 一些个人实战心得抓码阶段一定不要只抓“电源”“温度”“模式”这几个键就急着写配置。要多抓几组“温度不同、其他相同”和“模式不同、温度相同”的组合码把字段规律彻底摸清后面写自动化时能省大量时间。我手里这个项目最开始的raw数组就是靠十几组码的对比才确定温度字段的偏移规则如果只是随手抓几个码硬拼肯定会在某一步翻车。另外发送模块装好后建议在空调面板上贴一个“遥控码已集成HA”的标签提醒家里人这个遥控器可以被自动化接管。不然你会收到无数次“为什么空调自己开了”的售后投诉因为家里人可能一边用手机控制一边又拿遥控器调温度两边状态互相覆盖。在自动化里加一个“遥控器操作后休眠10分钟”的逻辑能很大程度缓解这种冲突。这个项目做完最好把抓到的协议码、字段拆解表、ESPHome配置模板都整理到本地笔记里尤其是空调型号、遥控器型号、协议帧长这些关键信息。因为空调将来如果换主板码很可能就变了到时重抓一套码照着旧模板改几个字段就能复用。
返回列表