树莓派系列教程:红外遥控

来自丢石头百科
Admin讨论 | 贡献2020年11月20日 (五) 15:42的版本
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)


上一章我们介绍了如果通过树莓派device tree,将在ds18b20添加到linux系统中,并通过命令行读取温度数据,这一章我们也通过device tree添加红外接收


lirc为linux系统中红外遥控的软件,树莓派系统已经有这个模块,我们只需设置一下就而已使用。

sudo vi /boot/config.txt

在文件后面添加下面这一行

dtoverlay=lirc-rpi,gpio_in_pin=18


红外默认输出是18管脚,如果红外接收头接到其他管脚则需修改对应管脚,(管脚为BCM编码),Pioneer 600接收头默认接到18管脚故只需要添加

dtoverlay=lirc-rpi

在/boot/overlay/README文件中我们可以找到详细说明。



090456m24i29am29iao9ht.png

安装lirc软件

sudo apt-get install lirc

运行lsmod命令查看设备是否已启动,如若没有找到可运行sudo modprobe lirc_rpi加载驱动。



090717crxhst3br0qbd071.png

运行sudo mode2 –d /dev/lirc0,按遥控上任何键,查看是否接到到类似脉冲。



090717avrrkkrfvbv4kbll.png

如有接到到脉冲测lirc正常使用。


采用脉宽调制的串行码,以脉宽为0.565ms、间隔0.56ms、周期为1.125ms的组合表示二进制的"0";以脉宽为0.565ms、间隔1.685ms、周期为2.25ms的组合表示二进制的"1

090949w646xyjvj13hxxzx.png

协议:


上述“0”和“1”组成的32位二进制码经38kHz的载频进行二次调制以提高发射效率,达到降低电源功耗的目的。然后再通过红外发射二极管产生红外线向空间发射,如下图。


090950ejokh8vjk28jz811.png

 |    引导码    |  用户识别码   |用户识别码反码 |   操作码    |  操作码反码   |


  一个命令只发送一次,即使遥控器上的按键一直按着。但是会每110mS发送一次代码,直到遥控器按键释放。


重复码比较简单:一个9mS的AGC脉冲、2.25mS间隔、560uS脉冲。


090950mak7u4rq4fwjqmaw.png


090950gzfiy0dfy068l9yd.png

bcm2835程序:

===   cpp代码: ===

#include <bcm2835.h>
#include <stdio.h>
#define PIN 18
#define IO bcm2835_gpio_lev(PIN)
unsigned char i,idx,cnt;
unsigned char count;
unsigned char data[4];

int main(int argc, char **argv)
{
    if (!bcm2835_init())return 1;
    bcm2835_gpio_fsel(PIN, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(PIN, BCM2835_GPIO_PUD_UP);
    printf("IRM Test Program ... \n");

    while (1)
    {	
	if(IO == 0)
	{
	    count = 0;
	    while(IO == 0 &amp;&amp; count++ < 200)   //9ms
            delayMicroseconds(60);
			
			count = 0;
			while(IO == 1 &amp;&amp; count++ < 80)	  //4.5ms
		    	delayMicroseconds(60);
			
			idx = 0;
			cnt = 0;
			data[0]=0;
			data[1]=0;
			data[2]=0;
			data[3]=0;
			for(i =0;i<32;i++)
			{
				count = 0;
				while(IO == 0 &amp;&amp; count++ < 15)  //0.56ms
		    		delayMicroseconds(60);
				
				count = 0;
				while(IO == 1 &amp;&amp; count++ < 40)  //0: 0.56ms; 1: 1.69ms
		    		delayMicroseconds(60);

				if (count > 25)data[idx] |= (1<1<cnt);
				if(cnt== 7)
				{
				    cnt=0;
 				    idx++;
				}
				else cnt++;
				if(data[0]+data[1] == 0xFF &amp;&amp; data[2]+data[3]==0xFF)	//check	
				printf("Get the key: 0x%02x\n",data[2]);
		}
	}
    bcm2835_close();
    return 0;

}


  编译并执行,按下遥控按键,终端会显示接到到按键的键值。

gcc Wall irm.c o irm lbcm2835
sudo ./irm


092048idx430q4e3d0mee4.png

python程序

#!/usr/bin/python
# -*- coding:utf-8 -*-
import RPi.GPIO as GPIO
import time

PIN = 18; 

GPIO.setmode(GPIO.BCM)
GPIO.setup(PIN,GPIO.IN,GPIO.PUD_UP)
print('IRM Test Start ...')
try:
    while True:
        if GPIO.input(PIN) == 0:
            count = 0 
            while GPIO.input(PIN) == 0 and count < 200:  #9ms
                count += 1
                time.sleep(0.00006)

            count = 0 
            while GPIO.input(PIN) == 1 and count < 80:  #4.5ms
                count += 1
                time.sleep(0.00006)

            idx = 0 
            cnt = 0 
            data = [0,0,0,0]
            for i in range(0,32):
                count = 0 
                while GPIO.input(PIN) == 0 and count < 15:    #0.56ms
                    count += 1
                    time.sleep(0.00006)
    
                count = 0 
                while GPIO.input(PIN) == 1 and count < 40:   #0: 0.56mx
                    count += 1                               #1: 1.69ms
                    time.sleep(0.00006)

                if count > 8:
                    data[idx] |= 1>>cnt
                if cnt == 7:
                    cnt = 0
                    idx += 1
                else:
                    cnt += 1
            if data[0]+data[1] == 0xFF and data[2]+data[3] == 0xFF:  #check
                print("Get the key: 0x%02x" %data[2])
except KeyboardInterrupt:
GPIO.cleanup();

    执行,按下遥控按键,终端会显示接到到按键的键值。

sudo python irm.py


092048czio5bokkkw52zkc.png


系列教程

树莓派系列教程