概述

在本课中我们将学习用Pi解码红外信号,并用红外遥控器控制Pi上外接的3个LED灯。

所需器件

1 * Raspberry Pi 3
1 * Breadboard
1 * 红外接收器(VS1838B)

1 * Infrared Remote Controller

3 * LED

3* Resistor(200Ω)
Several jumper wires

工作原理

在本课中,我们采用VS1838B作为红外线接收头,VS1838B能接收红外信号,还可以输出TTL逻辑电平信号。VS1838B有三个引脚,分别是OUT、GND和VCC,如图所示

VS1838B与Pi按照下图连接

 

实物连接

没画

软件

首先需要安装LIRC(Linux Infrared remote control),LIRC is a package that allows you to decode infrared signals of many (but not all) commonly used remote controls. LIRC runs as a daemon that will decode IR signals received by the device drivers and provide the information on a socket. We will then write a program in the user space to monitor this socket for input events using the LIRC client library.更多关于LIRC软件信息请看这里。

1) 安装LIRC和client libraries

sudo apt-get install lirc liblircclient-dev

2) 设置LIRC

a.打开 /etc/modules 文件

sudo  nano /etc/modules

添加下面两行

lirc_dev
lirc_rpi gpio_in_pin=18 gpio_out_pin=17

键盘输入Ctrl+X,再输入Y保存退出。

b.打开/boot/config.txt

sudo  nano  /boot/config.txt

并在末尾添加下面一行

dtoverlay=lirc-rpi:gpio_in_pin=18  gpio_out_pin=17

键盘输入Ctrl+X,再输入Y保存退出。

c.编辑/etc/lirc/hardware.conf文件

sudo  nano /etc/lirc/hardware.conf

按照图示修改

d.下载遥控配置文件(remote configuration file)lircd.conf,并复制到指定目录

cd   ~

wget –no-check-certificate http:osoyoo.com/driver/pi3_start_learning_kit_lesson_19/lircd.conf

sudo  cp  lircd.conf  /etc/lirc/

d. 重启使修改生效

reboot

5) 测试红外接收器

a.检查lirc是否被加载

ls /dev/li*

如果lirc被加载了,你会看到如下信息

如果没有出现上图的信息,请检查你的配置。

b.测试是按键

sudo /etc/init.d/lirc   restart
irw

将遥控器对着红外接收器按按键,屏幕会输出如下信息

如果没有出现上图的信息,请检查你的配置。

for C language users

1) 在/home/pi目录下新建一个.c源文件,名字随意(你开心就好)

cd  ~

sudo  nano  IRtest.c

向新建的文件中写入如下代码

#include 
#include 
#include 
#include 
#include 
#include 
#include 
 
void flipLED (int led);
 
//The WiringPi pin numbers used by our LEDs
#define LED1 4
#define LED2 5
#define LED3 6
 
#define ON 1
#define OFF 0
 
int main(int argc, char *argv[])
{
        struct lirc_config *config;
 
        //Timer for our buttons
        int buttonTimer = millis();
 
        char *code;
        char *c;
 
        //Initiate WiringPi and set WiringPi pins 4, 5 & 6 (GPIO 23, 24 & 25) to output. These are the pins the LEDs are connected to.
        if (wiringPiSetup () == -1)
            exit (1) ;
 
        pinMode (LED1, OUTPUT);
        pinMode (LED2, OUTPUT);
        pinMode (LED3, OUTPUT);
 
        //Initiate LIRC. Exit on failure
        if(lirc_init("lirc",1)==-1)
                exit(EXIT_FAILURE);
 
        //Read the default LIRC config at /etc/lirc/lircd.conf  This is the config for your remote.
        if(lirc_readconfig(NULL,&config,NULL)==0)
        {
                //Do stuff while LIRC socket is open  0=open  -1=closed.
                while(lirc_nextcode(&code)==0)
                {
                        //If code = NULL, meaning nothing was returned from LIRC socket,
                        //then skip lines below and start while loop again.
                        if(code==NULL) continue;{
                                //Make sure there is a 400ms gap before detecting button presses.
                                if (millis() - buttonTimer  > 400){
                                        //Check to see if the string "KEY_1" appears anywhere within the string 'code'.
                                        if(strstr (code,"KEY_1")){
                                                printf("MATCH on KEY_1\n");
                                                flipLED(LED1);
                                                buttonTimer = millis();
                                        }
                                        else if(strstr (code,"KEY_2")){
                                                printf("MATCH on KEY_2\n");
                                                flipLED(LED2);
                                                buttonTimer = millis();
                                        }
                                        else if(strstr (code,"KEY_3")){
                                                printf("MATCH on KEY_3\n");
                                                flipLED(LED3);
                                                buttonTimer = millis();
                                        }
                                }
                        }
                        //Need to free up code before the next loop
                        free(code);
                }
                //Frees the data structures associated with config.
                lirc_freeconfig(config);
        }
        //lirc_deinit() closes the connection to lircd and does some internal clean-up stuff.
        lirc_deinit();
        exit(EXIT_SUCCESS);
}
 
void flipLED (int led)
{
        //If LED is on, turn it off. Otherwise it is off, so thefore we need to turn it on.
        if(digitalRead(led)==ON)
                digitalWrite(led, OFF);
        else
                digitalWrite(led, ON);
}

在键盘上输入Ctrl+X,在输入Y保存退出。

完整的程序源码可以通过下面命令获取

wget  https://osoyoo.com/driver/pi3_start_learning_kit_lesson_19/IRtest.c

2) 编译

sudo  gcc  -Wall -o  IRtest     IRtest.c  -lwiringPi     -llirc_client

3) 创建一个文件

在运行程序之前需要在/etc/lirc/ 下创建一个lircrc文件不然会报错

sudo  touch /etc/lirc/lircrc

4) 运行程序

sudo /etc/init.d/lirc restart

sudo   ./IRtest    

5) 最终结果

遥控器对着红外接收器,按下遥控器上的1,第一个灯如果是亮着的会熄灭,如果是熄灭的会亮起。按下遥控器上的2、3,第二和第三个LED也会出现一样的现象。


for python users

在/home/pi下新建一个.py脚本文件

cd  ~

sudo  nano   IRtest1.py

向新建的IRtets1.py文件中添加一下内容

"""
$      If KEY_1 is pressed,this script will be executed,LED1 will turn on(or off)
$      LED1 connect to GPIO5(BCM_GPIO 24)
"""
import RPi.GPIO as GPIO

PIN = 24

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

GPIO.setup(PIN, GPIO.IN)
GPIO.setup(PIN, GPIO.OUT)

if GPIO.input(PIN) == 0:
     GPIO.output(PIN, GPIO.HIGH)
else:
     GPIO.output(PIN, GPIO.LOW)

在键盘上输入Ctrl+X,在输入Y保存退出。

以同样的方式再新建两个Python脚本,脚本名分别为IRtest2.py、IRtest3.py

分别向IRtest2.py、IRtest3.py中添加一下代码

"""
$      If KEY_2 is pressed,this script will be executed,LED1 will turn on(or off)
$      LED2 connect to GPIO6(BCM_GPIO 25)
"""
import RPi.GPIO as GPIO

PIN = 25

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

GPIO.setup(PIN, GPIO.IN)
GPIO.setup(PIN, GPIO.OUT)

if GPIO.input(PIN) == 0:
     GPIO.output(PIN, GPIO.HIGH)
else:
     GPIO.output(PIN, GPIO.LOW)
"""
$      If KEY_3 is pressed,this script will be executed,LED1 will turn on(or off)
$      LED3 connect to GPIO7(BCM_GPIO 4)
"""
import RPi.GPIO as GPIO

PIN = 4

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

GPIO.setup(PIN, GPIO.IN)
GPIO.setup(PIN, GPIO.OUT)

if GPIO.input(PIN) == 0:
     GPIO.output(PIN, GPIO.HIGH)
else:
     GPIO.output(PIN, GPIO.LOW)

在键盘上输入Ctrl+X,在输入Y保存退出。

完整代码可以通过下面命令下载

cd   ~

wget  https://osoyoo.com/driver/pi3_start_learning_kit_lesson_19/IRtest1.py

wget  https://osoyoo.com/driver/pi3_start_learning_kit_lesson_19/IRtest2.py

wget  https://osoyoo.com/driver/pi3_start_learning_kit_lesson_19/IRtest3.py

2) 在/home/pi下新建一个.lircrc文件

cd  ~

sudo  nano  ./.lircrc

.lircrc中添加以下代码

begin
    prog = irexec
    button = KEY_1
    config = sudo python /home/pi/IRtest1.py
end
begin
    prog = irexec
    button = KEY_2
    config = sudo python /home/pi/IRtest2.py
end
begin
    prog = irexec
    button = KEY_3
    config = sudo python /home/pi/IRtest3.py
end

wget –no-check-certificate https://osoyoo/driver/pi3_start_learning_kit_lesson_19/.lircrc下载

3) 执行程序
sudo /etc/init.d/lirc restart
irexec
4) 最终结果

将遥控器对着红外接收头,按下遥控器上的1,第一个灯如果是熄灭的就会亮起,如果是是亮起的会熄灭。同样,按下2和3,第二个和第三灯同样如此。