遥控器小制作(四)"/>
万能遥控器小制作(四)
前面的文章中我们已经知道如何获取遥控器的红外编码,以及通过单片机重放红外信号,来遥控空调。但是这样是远远不够的,要想让家电智能起来,我们需要把模块接入一些高级点的系统中,比如树莓派,然后通过Linux系统来控制红外发射。下面我们将介绍如何使用Linux与红外模块交互。
1.通信协议的制定
就目前而言,模块与外界通信的渠道只有串口可以使用,所以我们决定使用串口与树莓派进行通信。但是只要制定好双方通信的协议,两者才能合理正确地通信,不然就像你说英语我说中文,鸡同鸭讲。
通信协议采用比较简单的方式,包括起始位
,数据个数
,数据
三个部分组成。
起始位
:占一个字节,用来标识报文的开始,数值为0x2B数据个数
:占一个字节,用来标识之后数据的数量,最大为0XFF,即后面的数据最长为255个数据
:传输的有效载荷,实际的数据
举个例子2B 03 11 22 33有效数据位 11 22 33
2.单片机端解析报文
单片机端需要在串口接收中断中根据协议来处理报文,处理的代码如下。
/*用来标识是否正在使用缓存区*/
bit buf_empty = 0;/*报文起始位有效,接收后续报文*/
bit rec_start = 0;/*该则报文接收到的数据个数*/
unsigned char rec_counter = 0;/*该则报文需要接收的数据个数*/
unsigned char rec_sum = 0;/*需要处理的数据个数*/
unsigned char snd_sum = 0;/*接收缓存区*/
unsigned char idata recv_buff[MAX_BUF];/*protocol: | start | byte count | byte0 | byte1 | ...*/
void Uart_Isr() interrupt 4 using 1
{/*receive data*/if (RI && buf_empty){unsigned char ch = SBUF;RI = 0; /*normal bytes*/if(rec_start && rec_sum != 0){recv_buff[rec_counter++] = ch;}/*the amount of all bytes*/if(rec_start && 0 == rec_sum){snd_sum = rec_sum = ch;} /*start byte*/if(!rec_start && DATA_PREFIX == ch){rec_start = 1; }if(MAX_BUF == rec_counter || (rec_sum != 0 && rec_sum <= rec_counter)){/*buff is full*/rec_counter = 0;buf_empty = 0;rec_sum = 0;rec_start = 0;} }/*send data*/if (TI){TI = 0; busy = 0; }
}
3.树莓派端报文发送程序
树莓派端需要实现串口的读写即可,代码如下。
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <termios.h>#define MAX_SIZE 256void init_series(int fd)
{struct termios t ;tcgetattr( fd , &t) ;t.c_cflag &=~CSIZE ;t.c_cflag &=~CSTOPB;t.c_cflag |= CREAD ;t.c_cflag |= CLOCAL ;t.c_cflag &= ~CRTSCTS;t.c_cflag |= CS8;cfsetispeed( &t , B9600);cfsetospeed( &t , B9600);tcflush( fd , TCIOFLUSH);tcsetattr( fd , TCSANOW ,&t);
}/*这里没有写协议封装函数*/
char air_on[] = {0x2B, 104, 01, 01, 00, 00, 00, 00, 01, 01, 01, 01, 01, 00, 01, 00, 00, 01, 00, 00, 00, 00, 00, 01, 01, 01, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 01, 00, 01, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 01, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 01, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 01, 00, 01, 00, 00, 00, 00, 00, 01, 01, 01, 01, 01, 00, 00, 00};char air_off[] = {0x2B, 104, 01, 01, 00, 00, 00, 00, 01, 01, 01, 01, 01, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 01, 01, 01, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 01, 00, 01, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 01, 00, 01, 00, 00, 00, 00, 00, 01, 01, 01, 01, 00, 00, 01, 00};int main(int argc, char **argv)
{int fd ;int count ;char *buff_send = NULL;if(argc <2){printf("please input args!\n");return 0;}fd = open("/dev/ttyUSB0" , O_RDWR | O_NOCTTY );if(fd<0){printf("open series error\n");return 0 ;}init_series(fd);switch(argv[1][0]){case 'n':case 'N': buff_send = air_on; break;case 'f':case 'F': buff_send = air_off; break;default: break;}if(buff_send != NULL){write(fd , buff_send , 104+2);}close(fd);return 0 ;
}
OK啦,现在可以通过Linux来控制空调啦!但是这样貌似还不是很方便,如果想远程通过手机来控制的话可能会更方便,后面的文章将介绍搭建简单的物联网云平台,然后将手机和树莓派接入云平台实现远程控制空调。
更多推荐
万能遥控器小制作(四)
发布评论