zoukankan      html  css  js  c++  java
  • 树莓派控制红外线收发

    上淘宝买了两个红外线模块,一个是接收器,另一个是发送器。
    问了卖家,没有资料,但是根据电路板上打印的信息,似乎是标准的模块。于是先插上树莓派试试看。
     
     
    (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欧姆就可以了。
    面包板搭建图如下:
     
  • 相关阅读:
    ubuntu12.04 死机 卡屏 画面冻结解决方案
    Install Firefox 20 in Ubuntu 13.04, Ubuntu 12.10, Ubuntu 12.04, Linux Mint 14 and Linux Mint 13 by PPA
    ListView1.SelectedItems.Clear()
    android studio 下载地址
    jquery.slider.js jquery幻灯片测试
    jquery.hovermenu.js
    jquery.tab.js选项卡效果
    适配 placeholder,jquery版
    jquery.autoscroll.js jquery自动滚动效果
    将 Google Earth 地图集成到自己的窗体上的 简单控件
  • 原文地址:https://www.cnblogs.com/tanhangbo/p/4712670.html
Copyright © 2011-2022 走看看