在上一篇文章中,我们已经知道遥控器红外的编码基本规范,但是每个键值是什么编码我们还不得而知。其实,每个键值是按照什么规则编码我们并不care,我们只需要将键值记录下重放即可。
1.记录键值
记录键值很简单,只需要根据文章(二)中的时间统计程序,把信号中每个位的时间记录下,然后根据位的编码规则就可以反推出这个位的含义。下面是我记录下的开空调(制冷26度)和关空调的编码,使用时需要加上起始位与结束位。
开空调:
1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0
关空调:
1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0
2.发射红外信号
模块板上的红外发射管前面是有一个NPN组成的驱动电路,单片机输出1是红外发射管亮,输出0红外发射管灭。如果无法判断可以输出信号后用手机摄像头进行查看,如果亮的话会有红色光。
要想发送出的红外信号被空调红外接收管接收,需要对发送的信号进行调制。调制的方式很简单,采用38KHz载波,当输出低电平时红外发射管亮,高电平时红外发射管灭即可。
单片机如何通过软件输出38KHz载波这里简单说下,可以通过定时器1/38000/2时间溢出一次,然后溢出时去翻转引脚上的输出,这样就可以输出38KHz方波。为什么要除以2是因为一个周期内需要高低电平翻转一次,通过计算定时器溢出的周期为13us。
所以,只需要在输出低电平信号的时间段去翻转发射引脚上的信号。代码如下:
sbit irt = P1^0;
bit signal_flag = 0;
int signal_count = 0;
unsigned char idata time_counter[128] = {1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0};
void sendCode(int low_int, int high_int)
{
/*send low level*/
TL0 = T0TIME;
TH0 = T0TIME;
signal_flag = 1;
signal_count = 0;
TR0 = 1;
while(signal_count < low_int);
TR0 = 0;
/*send high level*/
signal_flag = 0;
signal_count = 0;
TL0 = T0TIME;
TH0 = T0TIME;
TR0 = 1;
while(signal_count < high_int);
TR0 = 0;
}
void test()
{
int i;
/*下面的数值是根据电平时间除以载波周期得出的,比如9000us的低电平为:9000/13=692*/
/*start bit*/
sendCode(692, 346);
for(i = 0; i < 104; i++)
{
if(0 == time_counter[i])
{
sendCode(42, 42);
}
else
{
sendCode(42, 127);
}
}
/*end bit*/
sendCode(42, 0);
irt = 0;
}
void timer0(void) interrupt 1 using 1
{
signal_count++;
/*send irt*/
if(1 == signal_flag)
{
irt = ~irt;
}
else
{
irt = 0;
}
}
至此,即可通过单片机来控制空调了。后续的章节将结合树莓派来实现智能家居空调。