【Arduino】基于ESP32实现空调遥控器(红外)-格力为例

前言

好久没更新了哈,并不是我停下了学习探索的脚步,而是有点懒,没有写博客了。

最近天气热了,宿舍要开空调,但是遥控器坏了,全宿舍能开空调的就两个人,就会很不方便(万一都不在就开不了咯)。然后之前也是做过一个门锁,能够实现刷卡开门,就想着再弄个遥控器吧,反正能用的上。

一、格力红外编码协议

网上介绍的挺多哈,其实重点了解一下电平的定义就可以,下面我也总结了。可以look look。

1. 电平定义

0的电平宽度为:600us低电平+600us高电平,
1的电平宽度为:600us低电平+1600us高电平
起始码S电平宽度为:9000us低电平+4500us高电平
连接码C电平宽度为:600us低电平+20000us高电平

下面这些可能你在其他博客见不到,我自己定义,具体什么意思什么作用呢?你看到下面就知道了。

长连接码CC电平宽度为:600us低电平+40000us高电平
结束码P电平宽度为:600us低电平+0us高电平

2. 完整通讯顺序

网上很多都是基于35+32的模式,其实这个理解并不是完全的正确,我觉得实际的通讯是32+3+32的模式。

这里我先给出红外一次发送的完整格式的通讯顺序:

起始码S + 4字节数据 + 3个固定数据的bit位 + 连接码C + 4字节数据 + 长连接码CC + 起始码S + 4字节数据 + 3个固定数据的bit位 + 连接码C + 4字节数据 + 结束码P

为什么说是32+2+32的模式呢,红外一次发送的完整格式可以拆分成两串指令(有起始信号S就代表一个指令,完整格式有两个起始信号S,所以是两串指令),一串指令发送8个字节,但是并不是8个字节的数据连着发送哦。而是将这8个字节拆分两个4字节,并且在中间,插入3个bit位的数据:010。4个字节是32个bit位,所以就得出32+3+32。有些空调只发送第一串指令就可以响应,但是建议是发送完整的格式。

二、数据定义

通过IRRemoteESP8266的项目源码的ir_Gree.h文件,找到数据结构的定义:

struct {
    // Byte 0
    uint8_t Mode      :3;		//模式
    uint8_t Power     :1;		//开关
    uint8_t BasicFan  :2;		//风速
    uint8_t SwingAuto :1;		//自动扫风
    uint8_t           :1;  		
    // Byte 1
    uint8_t Temp  :4;  			//温度
    uint8_t       :4;		
    // Byte 2
    uint8_t           :4;		
    uint8_t Turbo     :1;		//强劲
    uint8_t Light     :1;		//灯光
    uint8_t IonFilter :1;		//负离子
    uint8_t XFan      :1;		//根据模式的不同,有不同的含义。当模式为除湿和制冷模式时,这一位表示是否启用干燥模式,0为关闭,1为启用。而当模式为制热时,这一位代表是否启用电辅热,是反过来的,0代表启用电辅热,而1则代表的是关闭电辅热。
    // Byte 3
    uint8_t :4;
    uint8_t :2;  				//可能与定时器相关,通常是01
    uint8_t :2;  				//命令结束 01
    // (B010 marker and a gap of 20ms)
    // Byte 4
    uint8_t SwingV  :4;
    uint8_t SwingH  :1;
    uint8_t         :3;
    // Byte 5~6
    uint8_t pad0[2];  		//定时器相关,通常为0
    // Byte 7
    uint8_t       :4;  		//用于定时器模式
    uint8_t Sum1  :4;  		//第一个校验位
    第一部分的校验码,四个bits,计算方式为:
        基础值为10,然后将前面四个字节的低位相加,再加上紧接着三个字节的高位相加,最后结果对256取余,然后取结果的低4位。如果定义为uint8_t的话,溢出之后相当于是取余了,可以不用取余。

        //间隔40ms
        // (重新发送起始信号)
        // Byte 8~10
        uint8_t pad1[3];  // Repeat of byte 0~2
    // Byte 11
    uint8_t :4;
    uint8_t :2;  // 可能与定时器有关 (通常设置为 11)
    uint8_t :2;  // 命令块结束 (设置为01)
    // (B010 marker and a gap of 20ms)
    // Byte 12
    uint8_t       :1;  // 睡眠
    uint8_t       :6;  // (在休眠模式下使用, 通常全0 0b000000)
    uint8_t Quiet :1;
    // Byte 13
    uint8_t     :8;  // (通常 0x00)
    // Byte 14
    uint8_t     :4;  // (通常 0b0000)
    uint8_t Fan :3;
    // Byte 15
    uint8_t       :4;
    uint8_t Sum2  :4;  // 前一个字节的校验和 (8-14)第二部分的校验码,计算方式和第一部分的一样,只不过起始位置是从第八个字节开始算的。
};

具体哪些bit位表示什么功能,我在上面也标识了,没有名字的我猜应该是保留的。
从上面也可以看到,从Byte0-Byte15一共有16个字节,也就是说这就是完整通信所发送的所有数据(8+8嘛)。Byte0-Byte7是第一串指令发送的数据,Byte8-Byte15是第二串指令发送的数据,而每串指令都会带有一个校验码Sum,分别在Byte7高四位Byte15高四位

三、校验公式计算环节

网上很多的计算公式其实都是错的,也导致我在做这个的时候,一直不行,一气之下,我找到了IRRemoteESP8266中ir_Gree的源码的校验计算的部分。
在这里插入图片描述
没错,就是这个函数,关于计算校验码的,不难看出,sum首先有个初始值,然后不断累加。我通过上下文得出最后的计算结论:

校验码1的计算和填充

Byte7 |= (10 + Byte0到Byte3的低四位的和 + Byte4到Byte6高四位的和) & 0x0F;

校验码2的计算和填充

Byte15 |= (10 + Byte8到Byte11的低四位的和 + Byte12到Byte14高四位的和) & 0x0F;

我可是有捕获数据验证过的 [狗头]。

四、代码实现部分

好了好了,最想知道的环节来了,哔哩吧啦说那么多,这估计也是你们最想要的环节了。像格力这种厂家,ardinuo里面肯定有库实现的啦,底层就不用我们自己写咯。所以就算前面那些你看不懂,也一样可以调库(我一开始并没有直接调库,学习嘛,学的细致一点)。

使用的就是IRremoteESP8266库,前面有提过啦。我们需要的头文件是ir_Gree.h,当然里面空调的品牌可多了,一大堆,你想控制什么空调就去引入具体的头文件就好了。(我以格力为例)

我简单给段示例代码,估计你就能够看懂了。

#include <Arduino.h>
#include <Gree.h>
#define IR_GPIO 4
IRGreeAC gree_ac(IR_GPIO);

void setup() {
  Serial.begin(115200);
  gree_ac.begin();
  delay(1000);
}
void loop() {
    gree_ac.on();		//打开空调
    gree_ac.send();		//发送红外
    delay(2000);
  } 
}

具体设置模式啊,设置温度这些,看.h文件就好啦。

最后

到这里就结束咯,如果需要我空调遥控器的源码,关注这篇博客就好了,后续我会将资源网址发布出来(因为还没写好,现在发不了)

  • 8
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

点灯学徒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值