在上一篇文章中,我们已经知道遥控器红外的编码基本规范,但是每个键值是什么编码我们还不得而知。其实,每个键值是按照什么规则编码我们并不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;
    }
}

至此,即可通过单片机来控制空调了。后续的章节将结合树莓派来实现智能家居空调。