• 树莓派控制红外线收发


    上淘宝买了两个红外线模块,一个是接收器,另一个是发送器。
    问了卖家,没有资料,但是根据电路板上打印的信息,似乎是标准的模块。于是先插上树莓派试试看。
     
     
    (update:上图的发射器没有三极管,所以只能做到1-2m)
     
     
    看宝贝描述,这个模块是给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
    接下来查找了网上的资料,发现它的格式实际上是这个样子的:
     
     
     

    发射器

     
    接下来做一个发射器,俗话说,上山容易下山难,编码容易解码难,过了解码这个步骤,编码也挺容易了,不过做发射器的时候还是有一些问题需要考虑的。
     
    做发射器的时候需要打开树莓派的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的效果好。
     
    用函数开关PWM有200us的延时,这里是要考虑下的。开的时候是200ms之后就打开了,
    关的时候会立马关闭,但是这个过程还是会延时200us。
     
    目前的结果是,用两个IR模块对测,解析器也能解析出正确的结果,空调也能被控制。
     
     
     
     
     
    波形

    抓到的遥控器波形(管脚端),手工查看,得知:
     
     
    0110010 01001101 00011111 11100000 01001000 10110111L (同一个波形发两次)
    第一个bit是MSB:
    B2 4D 1F E0 48 B7
     
     
    屏幕上显示的是24度,和前面提到的资料一致。
     
     
    遥控器的波形并不完美,我自己产生的波形可以完美的多:
     
     
     
    现在已经可以控制美的空调了,空调被控制的时候也会产生‘滴’的声音。不过控制距离只有1米,
    可能是模块的电流比较小导致的。
     
    【0817更新】
    通过自己搭电路,已经可以解决距离太小的问题,解决办法是增加一个三极管,增大红外管的电流,
    另外将图中的100欧姆换成10欧姆就可以了。
    面包板搭建图如下:
     
  • 相关阅读:
    js中面向对象的写法
    js中防止全局变量被污染的方法
    移动端的头部标签和meta
    励志
    UX是什么?
    HTTP
    Django RestFramework (DRF)
    Vue(一)
    Vue-基础
    Vue-es6基础语法
  • 原文地址:https://www.cnblogs.com/tanhangbo/p/4712670.html
Copyright © 2020-2023  润新知