格力空调红外编码解析

使用红外遥控空调,就必须先了解红外遥控的原理,数据的定义等。本博客解析了空调的最基本的功能的红外编码,包括:开关,温度,定时,风速,扫风,校验码。其他的功能因为空调型号不同而差别较大,所以暂时不作解析。同时,空调大部分时间工作在制冷模式下,其他模式下的编码也暂时未解析。

一,红外遥控原理

1,红外线

红外线是波长在760nm到1mm的电磁波,根据波长的不同可分为可见光(0.38um-0.76um)和不可见光。使用红外线作为遥控的话,由于红外发射管与红外接收管的响应波长一般为0.8um-0.94um,所以选择波长为0.76um-1.5um的红外光作为通讯的波长。

红外通信广泛应用于家电控制,其优点是抗干扰能力强(频率低),功耗小,性价比高等。

2,工作原理

发射器发射38khz方波为载波的红外光(占空比50),即红外光以38khz的频率闪烁着,接收器接收到以此频率闪烁的红外光时,会在其信号脚输出高电平信号,否则输出低电平。

根据这个最基本的原理来,来实现编码解码数据。数据就是一组二进制的数据,0和1的区别就是高低电平时间的不同。比如,以下例子中,0与1的区别就是1的高电平时间较长。发射器首先需要编码,根据二进制数据每一位的内容,发射持续时间不一样的红外光(控制低高电平时间),而接收器则需要判断高低电平的时间来解码数据。

二,实验波形

本实验是基于格力空调的红外数据
一帧红外编码数据的组成如下:
起始码+35位数据+连接码+32位数据+结束码
在这里插入图片描述其中多次测量得出:

起始码:9000us 低电平 + 4500us高电平;
连接码:646us低电平 + 20000us高电平;
结束码:646us低电平 + 高电平;

数据0:646us低电平 + 516us高电平;
数据1:646us低电平 + 1643us高电平;

数据码中的0和1,经过多次的测量,取众数作为依据,实验数据如下:

在这里插入图片描述

三,红外编码解析

知道了一帧红外数据的0和1的表示,我们就可以自由的组成一帧数据。接下来需要了解的是在一帧数据中,数据位中的每一个bit代表的意思。
这里以25℃,制冷模式,低风速,无扫风,打开,定时时间为0的一帧数据为例子:

第一段数据:

开关:bit3;

0:关闭;1:开启

风速:bit4,bit5;

自动风速:00
一级风速:10
二级风速:01
三级风速:11

扫风开关:bit6,以及第二段bit0;

0:关闭;1:开启

温度:bit8,bit9,bit10,bit11;

16℃: 0000
17℃: 1000
18℃: 0100
19℃: 1100
20℃: 0010
21℃: 1010
22℃: 0110
23℃: 1110
24℃: 0001
25℃: 1001
26℃: 0101
27℃: 1101
28℃: 0011

定时分钟数:bit12,bit13,bit14;

由于我的手机只能发送定时半小时为最小单位的定时时间,所以只有定时30分钟的数据

30min: 100

bit15 定时开关;

0:关闭;1:开启

定时小时数:bit16,bit17,bit18,bit19;

一小时:1000
两小时:0100
三小时:1100

在这里插入图片描述

第二段数据:

第二段数据比较简单,需要注意的就是bit0是扫风的开关,她与第一段数据中的bit6是一样的数值。另外是后四位bit28,bit29,bit30,bit31组成的校验码。
网上也有许多关于校验码的公式,但是我试了后发现并不适用,于是自己尝试出了一条公式:
校验码 = 温度 - 18 + 定时小时数 + 空调开关 × 8;
例如以上例子的校验码是:25 - 18 + 0 + 1× 8 = 15 = 0xf;
在这里插入图片描述

四,小结

红外遥控的实现大同小异,最好还是要自己有测试的设备进行代码的测试。红外接收管和逻辑分析仪是你的不二选择。

友情连接:
esp32实现红外发射与接收

作者才疏学浅,难免有错误,希望指正。如果文章对你有帮助,帮忙点个赞呗。
在这里插入图片描述

格力空调遥控信号的编码格式为自定义格式,需要先进行信号录制和解码,然后根据解码结果来编写解析程序。以下是基于 STM32 的格力空调遥控信号解析程序: ```c #include "stm32f10x.h" #define IR_PIN GPIO_Pin_0 #define IR_GPIO GPIOA #define IR_EXTI EXTI_Line0 #define IR_EXTI_PORT_SOURCE GPIO_PortSourceGPIOA #define IR_EXTI_PIN_SOURCE GPIO_PinSource0 #define IR_TIM TIM2 volatile uint32_t irData[128]; volatile uint8_t irCount = 0; volatile uint8_t irState = 0; void IR_TIM_Config(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); TIM_TimeBaseStructure.TIM_Period = 8999; // 90us TIM_TimeBaseStructure.TIM_Prescaler = 71; // 1MHz TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(IR_TIM, &TIM_TimeBaseStructure); TIM_Cmd(IR_TIM, ENABLE); } void IR_EXTI_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); GPIO_InitStructure.GPIO_Pin = IR_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(IR_GPIO, &GPIO_InitStructure); GPIO_EXTILineConfig(IR_EXTI_PORT_SOURCE, IR_EXTI_PIN_SOURCE); EXTI_InitStructure.EXTI_Line = IR_EXTI; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } void EXTI0_IRQHandler(void) { static uint16_t lastValue = 0; uint16_t duration = (uint16_t)(IR_TIM->CNT); IR_TIM->CNT = 0; if (duration < 10000) { // ignore noise if (irState == 0 && duration > 8000 && duration < 9000) { // start bit irCount = 0; irState = 1; } else if (irState == 1 && duration > 400 && duration < 600) { // 0 bit irData[irCount++] = 0; irState = 2; } else if (irState == 1 && duration > 1200 && duration < 1400) { // 1 bit irData[irCount++] = 1; irState = 2; } else if (irState == 2) { // next bit irState = 1; } else { // invalid bit irData[irCount++] = lastValue; // use previous value } lastValue = irData[irCount-1]; } else { // stop bit irState = 0; } EXTI_ClearITPendingBit(IR_EXTI); } int main(void) { IR_TIM_Config(); IR_EXTI_Config(); while(1) { if (irState == 0 && irCount == 70) { // valid data if (irData[0] == 0 && irData[1] == 1 && irData[2] == 0 && irData[3] == 1) { // check start code uint16_t addr = 0; uint16_t cmd = 0; for (int i = 0; i < 8; i++) { addr = (addr << 1) | irData[4+i]; } for (int i = 0; i < 8; i++) { cmd = (cmd << 1) | irData[20+i]; } // do something with addr and cmd } irCount = 0; } } } ``` 此程序可以解析格力空调遥控信号,使用了 TIM2 定时器和 EXTI 外部中断来计时和捕获信号。当接收到有效的红外线信号时,会将信号值存储在 `irData` 数组中,并根据信号格式和状态机来判断是否解析完整个数据包。如果解析成功,可以获取地址码和命令码并执行相应的操作。 需要注意的是,格力空调遥控信号的编码格式可能存在差异,此程序只是一个简单的解析例程,实际使用时需要根据具体的遥控器型号和编码格式进行修改和优化。
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值