上淘宝买了两个红外线模块,一个是接收器,另一个是发送器。
问了卖家,没有资料,但是根据电路板上打印的信息,似乎是标准的模块。于是先插上树莓派试试看。
看宝贝描述,这个模块是给Arduino用的,于是搜索了一下Arduino相关的资料,发现github上有
Arduino-IRremote这个项目,里面有各种协议包括NEC红外协议的实现。
举个例子,代码里面发送NEC的实现:
这里先发送一个头部,然后按比特发送数据,
比特为1发560us的PWM,然后等待1690us
比特位0的时候发送560us的PWM,然后等待560us
最后发送一个560us的PWM结束
手头上有一块树莓派和一个美的空调,所以先用这两个硬件下手,实际上使用STM32会更方便,因为树莓派自带了操作系统,控制硬件没有STM32这种单片机方便。后续准备将程序移植到STM32上面。
解析器
要知道美的空调的编码,首先要做一个解析器。实际上,使用逻辑分析仪也可以得知。一开始并没有拆开遥控器看看,先用IR接收器做了一个解析器。
代码传上去了,见:
https://github.com/tanhangbo/RaspberryIR
做解析器的时候首先要了解红外头的工作原理,首先它里面有一个滤波器,有38K数据的时候输出‘1‘,没有38K数据的时候输出‘0‘。外部供电3.3V。接下来就要对输入的数据进行处理了。
首先对其产生的跳变进行响应,这里就注册了一个中断,INT_EDGE_BOTH表示不论下降沿和上升沿都进行响应,这样就可以采集到数据了:
wiringPiISR(IR_INPUT, INT_EDGE_BOTH, &ir_int)
接下来要对响应做计数。一开始用gettimeofday测试了一下,并不准确,查资料得知树莓派的ARM芯片内部有一个1MHZ的时钟可以用来做计数器。不过因为树莓派有linux操作系统,直接访问时钟地址是不行的。
首先要打开datasheet(网上可以搜到)
BCM2835-ARM-Peripherals.pdf
里面提到了两种timer:
其中System Timer的定义
ARM timer的定义:
看它的描述还是使用System Timer比较好。
首先要知道System Timer的地址。
这里写的是 0x7E003000,但是看图说话(第5页),还是要转换成为0x20003000:
转换好之后就要解决怎么用了。首先想到的就是写一个驱动,不过写驱动需要花一些时间调试,搞不好kernel搞挂了,为了简单一点,这里有一个比较portable的办法,就是使用mmap直接读取/dev/mem的信息。详情见代码。
于是根据这个思路作了一个获取时间间隔的一个API:
long long int get_timer_diff() { long long int ret; ret = *timer - prev_timer; prev_timer = *timer; return ret; }
这里为什么要用long long?因为这个timer是64bit的。
解析分为三步:1.解析波形,2.解析bit,3.解析Byte
解析完成之后就拿到我需要的东西了。
拿着遥控器对着红外头测试,发现美的空调的格式如下:
0xb2,0x4d,0xf5,0x0a,0xa5,0x5a
接下来查找了网上的资料,发现它的格式实际上是这个样子的:
http://www.geek-workshop.com/thread-5707-1-1.html
发射器
接下来做一个发射器,俗话说,上山容易下山难,编码容易解码难,过了解码这个步骤,编码也挺容易了,不过做发射器的时候还是有一些问题需要考虑的。
做发射器的时候需要打开树莓派的PWM,并且使用1MHZ的时钟做一个API:
void delay_us(int us) { long long int prev_timer; prev_timer = *timer; while (*timer - prev_timer < us) ; }
这样就可以逐个将数据发送出去了。其中开关PWM的时候发现一个问题,关闭PWM倒是很快,开启PWM有延时。于是在开启之前将关闭PWM的时间缩短解决。如果能直接控制UART,我想可以用UART模拟一样的波形,利用RTS-CTS快速关断,比PWM的效果好。
接下来已经接近成功了,用两个IR模块对测,解析器也能解析出正确的结果,但是空调就是不给面子,一直没反应。于是拆开空调遥控器用逻辑分析仪抓包,同时也用逻辑分析器抓取IR发送器的包,最后调的波形差不多,空调还是没有反应。这个问题后面再看看。
波形
抓到的遥控器波形(管脚端),手工查看,得知:
0110010 01001101 00011111 11100000 01001000 10110111L (同一个波形发两次)
第一个bit是MSB:
B2 4D 1F E0 48 B7
屏幕上显示的是24度,和前面提到的资料一致。
遥控器的波形并不完美,我自己产生的波形完美的多,不知道为什么对遥控器没有效果,