单片机学习小组
直播中

王玲

8年用户 1496经验值
私信 关注

求大佬分享一种空调遥控器破解方案

求大佬分享一种空调遥控器破解方案

回帖(1)

孙原元

2022-2-15 11:35:19
介绍

最近人在深圳温度比较高,每天回家进门感到很热,然后又连续两天早上出门忘关空调,每次调空调时来回找遥控也很麻烦,就希望空调能够自己调节自己,给我省点心。
以前破解遥控器的一种方案,真的是破解,就是把遥控拆开,按键短路接在继电器上,继电器再通过一个主控编程控制,这样继电器就可以模拟按键的过程。但是这样的解决方案不够优雅也很麻烦。最近使用了一个新方案,在网上购入了红外编解码模块,可以接收发送红外信号,解析后通过串口与主控通信,这样的方案优雅了很多。
理想生活是每天早上起床希望空调自动打开,出门上班空调关闭,晚上回家前空调提前打开降温,夜里进入睡眠模式,凌晨时候再关闭空调,全部通过程序自动控制,不需要再每次找遥控进行调节,一个成熟的空调应该学会自己调整自己。
硬件设计


使用淘宝上购入的stm32f103c8t6最小系统板作为主控,利用其TIMER或RTC模块作为定时器实现时钟走时及定时功能,通过串口通信与红外编解码模块进行通信。
简单说一下红外编解码,红外模块有一个发射二极管和一个接收二极管,通过电路调制,发射部分将数据变成高低电平通过二极管发出,接收二极管接到数据后进行解析,高低电平的的格式不同常见的可以分为PPM调制和PWM调制,其对应的编解码芯片不同,例如

具体原理不再赘述。一开始没有考虑红外的载波形式还有不同标准因此随意买了一个模块。

通过串口转USB模块连接电脑先测试一下,供电正常,使用遥控正对红外模块接收头按键测试,发现机顶盒、电视机遥控按键按下时串口助手可以回读正常数据,但是空调遥控器怎么按就是没反应,检查之后发现这个模块支持的是NEC编码,说明里标注说支持99%的NEC编码下的遥控器,之前把这个模式前提忽略了,猜想家里的空调应该不是NEC编码的,查询了一下发现格力空调确实有自己的编码格式。之后在重新下单了一个编解码模块,这个模块号称可以解码99%的红外设备,简单对比了一下说明发现,第一种编解码模块是收到数据后会根据NEC的编码协议,将高低电平数据解析为一帧数据发出,

如果本身的编码格式不是按这个固定格式的,那肯定会解析失败,什么都解析不出来。但是第二种模块,是自己的解读规则将收到的高低电平数据存成固定的236个字节,这个字节其实没有实际意义,只对应高低电平信号,因此厂家专门指出,同一遥控器按键信号在光线强弱不同时有可能解析出不同的数据。这一点在之后的测试中也到了印证,都是按关机键有时会得到不同的信号,且有时得到的数据不做改动使用发送部分发送时无法正常操作空调。

将新的模块同样通过u***-ttl模块连接电脑测试,使用空调遥控器对准模块按下后,可以正常接收到解析出的236字节数据。将接收到的数据通过串口助手发送给模块时,空调可以正常响应,认为该模块可以正常使用。

软件设计
RTC时钟
首先使用stm32的RTC模块配置一个时钟,实现日常的走时、闹钟等。


u8 RTC_Init(void)
{
        u8 temp=0;
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);         
        PWR_BackupAccessCmd(ENABLE);       
        if (BKP_ReadBackupRegister(BKP_DR1) != 0x5050)               
                {                                
                BKP_DeInit();       
                //RCC_LSEConfig(RCC_LSE_ON);       
                while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET&&temp<250)       
                        {
                        temp++;
                        delay_ms(10);
                        }
                if(temp>=250)return 1;   
                RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div128);                 
                RCC_RTCCLKCmd(ENABLE);         
                RTC_WaitForLastTask();
                RTC_WaitForSynchro();               
                RTC_ITConfig(RTC_IT_SEC, ENABLE);               
                RTC_WaitForLastTask();
                RTC_EnterConfigMode();
                RTC_SetPrescaler(62499);
                RTC_WaitForLastTask();
                RTC_Set(2020,9,25,0,13,30);  
                RTC_ExitConfigMode();   
                BKP_WriteBackupRegister(BKP_DR1, 0X5050);       
                }
        else
                {


                RTC_WaitForSynchro();       
                RTC_ITConfig(RTC_IT_SEC, ENABLE);       
                RTC_WaitForLastTask();       
                }
        RTC_NVIC_Config();                                                         
        RTC_Get();
        return 0;
}       


串口通信
stm32f1的芯片有多个串口可以进行使用,电平为TTL电平和红外模块匹配。这里就随意选择一个串口,配置时钟、波特率、数据位格式、收发引脚等信息。


void uart_init(u32 bound)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;


        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);       
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;       
        GPIO_Init(GPIOA, &GPIO_InitStructure);


        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOA, &GPIO_InitStructure);


        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;               
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                       
        NVIC_Init(&NVIC_InitStructure);       


        USART_InitStructure.USART_BaudRate = bound;
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        USART_InitStructure.USART_StopBits = USART_StopBits_1;
        USART_InitStructure.USART_Parity = USART_Parity_No;
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;       


  USART_Init(USART1, &USART_InitStructure);
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
  USART_Cmd(USART1, ENABLE);                  
}


红外数据解析
要控制空调,就需要先解析在遥控器空调按键按下时发送给空调的是什么数据,然后在定时的到时间的时候模拟遥控器发送的数据发送即可。结合期望的时间和空调动作,设计如下控制流程:


早上九点打开空调,这是一般天气不会太热个人认为开27℃风速低速即可;
早上十点关闭空调,一般这个时候差不多出门上班,直接将空调关闭;
晚上十点左右一般会下班到家,所以在十点左右打开空调,晚上温度较高,这时开27℃风速中速;
夜里十二点入睡,将空调调整为27℃风速低速,打开睡眠模式;
凌晨时间室温降低,人的体温在睡眠中也会降低,因此四点半关闭空调;
数据解析时可以使用单片机直接记录红外模块解析发送的数据存进flash中,这里没有做遥控学习功能,所以手动测试,将模块连接至电脑,打开串口助手,将遥控调制27℃风速低,然后按关闭,这是对准红外接收模块按开机键,可以在电脑上看到串口助手收到236字节数据,将数据拷贝存入代码数组中,在指定时间通过串口向外发送该数组数据即可控制空调开机至27℃风速低,其他遥控操作解析同上。



{0xFD, 0xFD, 0x30, 0x03, 0x63, 0x8B, 0x00, 0x34, 0x12, 0x01, 0x2B, 0x02, 0x63, 0x00, 0x2A, 0x00, 0x1E, 0x00, 0x29, 0x00, 0xD5, 0x04, 0x2A, 0x00, 0x00, 0x00, 0x26, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x22, 0x12, 0x12, 0x21, 0x12, 0x12, 0x22, 0x22, 0x22, 0x22, 0x11, 0x22, 0x22, 0x21, 0x21, 0x22, 0x12, 0x32, 0x22, 0x21, 0x22, 0x21, 0x12, 0x22, 0x12, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x22, 0x24, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x76, 0x3F, 0x8C, 0xDF, 0xDF}
测试

测试后程序功能正常,可以控制空调运行,但有如下几个问题需要注意:



  • 一开始没有仔细了解这个编码的原理,发现有时解析出来的遥控数据发送后空调不能正常响应,根据厂家说明里的提示猜想是应为在解析时对遥控器信号有遮挡,这是还是可以正常解析出236字节的数据,但该数据与正常遥控器发出的数据不对应,因此导致发送还原后空调不能正常响应。
  • 关于RTC计时问题,一开始测试时发现RTC走时不准,在这里做了详细记录:

  关于STM32开发板RTC计时不准的问题
总结

使用这个红外收发模块代替遥控大概两周了,寻找遥控器的频率大大下降,之前每天因为温度变化和人处的状态不同需要一天找四五次遥控器,现在几天才偶尔找遥控器调一下温度,人的幸福感有很大提高。有朋友说现在很多空调都有智能调温度或者定时等等,但是这些功能可编程的灵活度都不够高,不能满足人各种情况的需求。还有人提到关于天猫精灵等语音控制的智能家电,这里是希望连语音都不需要,能根据我日常的习惯自动调节。因为我每天各个时间段对于空调温度的设置比较固定,想进一步解放人力,并且有时语音控制的交互也并不是很好。遗留了一个小问题就是这里对于空调温度的设置是根据我的生活习惯设置的,都是经验性的指令,如果有一天晚上特别热的时候我还是得手动把空调温度降低,之后考虑加入测温模块解决。
完整代码可私戳
举报

更多回帖

发帖
×
20
完善资料,
赚取积分