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

网上淘到了一个红外接收器(HX1838+NEC编码红外遥控器)和一个红外遥控器,准备放到树莓派上学习一下红外控制。
[img]http://dl2.iteye.com/upload/attachment/0128/9746/82f5aa5d-baf0-30eb-8373-34c197589c2d.jpg[/img]
不知道为什么接受器带灯的那个距离感应很近,不知道为什么,这里就不用带灯的,用下图两个,一个接收器和控制器
[img]http://dl2.iteye.com/upload/attachment/0128/9742/24d2a5e1-a19e-348c-85db-f44224ede92a.jpg[/img]
[img]http://dl2.iteye.com/upload/attachment/0128/9744/df539677-1c58-31f5-b94c-a6ffa923cfb2.png[/img]

1.正面对准自己,然后从左到右三个头分别是如下图,插到对应的树莓派上
[img]http://dl2.iteye.com/upload/attachment/0128/9748/84a2fa5c-a10d-3f58-8761-5df2d8ccc66b.jpg[/img]

2.安装lirc,修改配置文件
LIRC (Linux Infrared remote control)是一个linux系统下开源的软件包。这个软件可以让Linux系统接收及发送红外线信号。

sudo apt-get install lirc

这里要重点说明一下,安装上之后网上基本上文章都是说修改/etc/lirc/hardware.conf这个文件,但是我装上lirc最新版(0.9.2)之后根本就找不到这个配置文件,修改的不是hardware.conf这文件,修改/etc/lirc/lirc_options.conf这个文件,把这个文件中对应以下几个参数修改一下

#driver = devinput
driver = default
#device = /dev/lirc0
device = auto

3.修改/boot/config.txt文件,这里26是对应bcm树莓派上的gpio接口:

dtoverlay=lirc-rpi,gpio_in_pin=26

4.重新开启lirc功能,至此lirc软件就配置完成了。

sudo /etc/init.d/lircd restart
sudo modprobe lirc_rpi


5.关闭红外线接收功能
首先关闭lirc软件,然后执行如下命令:
sudo kill $(pidof lircd)


6.测试红外接收
mode2 -d /dev/lirc0

用红外遥控器,对着接收器按下任意按键,屏幕会打印类似下面的内容,说明红外接收功能正常。
[quote]space 16300
pulse 95
space 28794
pulse 80
space 19395[/quote]

7.红外编码录制
irrecord --list-namespace

可查看有哪些按键名并记录下来,然后执行红外线编码录制命令
irrecord -d /dev/lirc0 ~/lircd.conf

开始时需要输入一下别名,最后会根据此名称保存对应的文件名,我这里起的:pi
按提示需要输入两次按键次数,需要多少次记不清楚了,你只要来回把按钮全按一遍一直按到提示结束,接下来就是根据上面记录下来的按键名称来点击控制器上对应的按钮,把控制器上所有按钮全部对应到一个不同的按按键名上,如果全部完成之后多按一次回车,提示结束,但这里还需要随便再按一次按钮才会保存成功,成功之后会在~/目录下生成pi.lircd.conf这个文件,只要把这个文件放到/etc/lirc/lircd.conf.d/这个目录里就行了,执行:
sudo cp ~/pi.lircd.conf /etc/lirc/lircd.conf.d/

下面是我生成的pi.lircd.conf此文件内容:

# Please take the time to finish this file as described in
# https://sourceforge.net/p/lirc-remotes/wiki/Checklist/
# and make it available to others by sending it to
#
#
# This config file was automatically generated
# using lirc-0.9.4c(default) on Sat Feb 24 13:30:19 2018
# Command line used: -d /dev/lirc0 /home/pi/lircd.conf
# Kernel version (uname -r): 4.9.59-v7+
#
# Remote name (as of config file): pi
# Brand of remote device, the thing you hold in your hand:
# Remote device model nr:
# Remote device info url:
# Does remote device has a bundled capture device e. g., a
# usb dongle? :
# For bundled USB devices: usb vendor id, product id
# and device string (use dmesg or lsusb):
# Type of device controlled
# (TV, VCR, Audio, DVD, Satellite, Cable, HTPC, ...) :
# Device(s) controlled by this remote:

begin remote

name pi
bits 32
flags SPACE_ENC|CONST_LENGTH
eps 30
aeps 100

header 8994 4467
one 583 1641
zero 583 570
ptrail 583
repeat 8994 2217
gap 107314
toggle_bit_mask 0x0
frequency 38000

begin codes
KEY_0 0x00FF6897 0x7ED25DBC
KEY_1 0x00FF30CF 0x7ED25DBC
KEY_2 0x00FF18E7 0x7ED25DBC
KEY_3 0x00FF7A85 0x7ED25DBC
KEY_4 0x00FF10EF 0x7ED25DBC
KEY_5 0x00FF38C7 0x7ED25DBC
KEY_6 0x00FF5AA5 0x7ED25DBC
KEY_7 0x00FF42BD 0x7ED25DBC
KEY_8 0x00FF4AB5 0x7ED25DBC
KEY_9 0x00FF52AD 0x7ED25DBC
KEY_CHANNEL 0x00FF629D 0x7ED25DBC
KEY_CHANNELDOWN 0x00FFA25D 0x7ED25DBC
KEY_CHANNELUP 0x00FFE21D 0x7ED25DBC
KEY_PLAY 0x00FFC23D 0x7ED25DBC
KEY_NEXT 0x00FF02FD 0x7ED25DBC
KEY_PREVIOUS 0x00FF22DD 0x7ED25DBC
KEY_VOLUMEDOWN 0x00FFE01F 0x7ED25DBC
KEY_VOLUMEUP 0x00FFA857 0x7ED25DBC
KEY_EQUAL 0x00FF906F 0x7ED25DBC
KEY_A 0x00FF9867 0x7ED25DBC
KEY_B 0x00FFB04F 0x7ED25DBC
end codes

end remote


完成之后重启树莓派

8.接下来就是编写代码,我这里给出两种语言的代码,一个是c语言的,一个是python语言的代码,都是调用通过

c代码(必须要提前安装上bcm2835的库,从网上百度吧很多):

#include
#include
#include

#define PIN 26
#define IO bcm2835_gpio_lev(PIN)
unsigned char i,idx,cnt;
unsigned char count;
unsigned char data[4];

static int flag = 0;
int exec_cmd(unsigned char key_val){
switch(key_val) {
case 0x45://CH-
printf("Button CH-\n");
break;
case 0x46://CH
printf("Button CH\n");
break;
case 0x47://CH+
printf("Button CH+\n");
break;
case 0x44://PREV
printf("Button PREV\n");
system("mpc prev");
break;
case 0x40://NEXT
printf("Button NEXT\n");
system("mpc next");
break;
case 0x43://PLAY/PAUSE
printf("Button PLAY/PAUSE\n");
if (flag == 0) {
flag = 1;
printf("mpc play\n");
//system("mpc play");
}else{
flag = 0;
printf("mpc pause\n");
//system("mpc pause");
}
break;
case 0x07://VOL-
printf("Button VOL-\n");
system("mpc volume -1");
break;
case 0x15://VOL+
printf("Button VOL+\n");
system("mpc volume +1");
break;
case 0x09://EQ
printf("Button EQ\n");
break;
case 0x16://0
printf("Button 0\n");
break;
case 0x19://100+
printf("Button 100+\n");
break;
case 0x0d://200+
printf("Button 200+\n");
break;
case 0x0c://1
printf("Button 1\n");
break;
case 0x18://2
printf("Button 2\n");
break;
case 0x5e://3
printf("Button 3\n");
break;
case 0x08://4
printf("Button 4\n");
break;
case 0x1c://5
printf("Button 5\n");
break;
case 0x5a://6
printf("Button 6\n");
break;
case 0x42://7
printf("Button 7\n");
break;
case 0x52://8
printf("Button 8\n");
break;
case 0x4a://9
printf("Button 9\n");
break;
default:
break;
}
return 0;
}

int main(int argc, char const *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 && count++ < 200) //9ms
delayMicroseconds(60);

count = 0;
while (IO == 1 && 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 && count++ < 15) //0.56ms
delayMicroseconds(60);

count = 0;
while (IO == 1 && count++ < 40) //0: 0.56ms; 1: 1.69ms
delayMicroseconds(60);

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

bcm2835_close();
return 0;
}

写好之后编译运行c文件:

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

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

下面再说下python代码:

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

PIN = 26;

GPIO.setmode(GPIO.BCM)
GPIO.setup(PIN,GPIO.IN,GPIO.PUD_UP)
print("irm test start...")

def exec_cmd(key_val):
if(key_val==0x45):
print("Button CH-")
elif(key_val==0x46):
print("Button CH")
elif(key_val==0x47):
print("Button CH+")
elif(key_val==0x44):
print("Button PREV")
elif(key_val==0x40):
print("Button NEXT")
elif(key_val==0x43):
print("Button PLAY/PAUSE")
elif(key_val==0x07):
print("Button VOL-")
elif(key_val==0x15):
print("Button VOL+")
elif(key_val==0x09):
print("Button EQ")
elif(key_val==0x16):
print("Button 0")
elif(key_val==0x19):
print("Button 100+")
elif(key_val==0x0d):
print("Button 200+")
elif(key_val==0x0c):
print("Button 1")
elif(key_val==0x18):
print("Button 2")
elif(key_val==0x5e):
print("Button 3")
elif(key_val==0x08):
print("Button 4")
elif(key_val==0x1c):
print("Button 5")
elif(key_val==0x5a):
print("Button 6")
elif(key_val==0x42):
print("Button 7")
elif(key_val==0x52):
print("Button 8")
elif(key_val==0x4a):
print("Button 9")

try:
while True:
if GPIO.input(PIN) == 0:
count = 0
while GPIO.input(PIN) == 0 and count < 200:
count += 1
time.sleep(0.00006)

count = 0
while GPIO.input(PIN) == 1 and count < 80:
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:
count += 1
time.sleep(0.00006)

count = 0
while GPIO.input(PIN) == 1 and count < 40:
count += 1
time.sleep(0.00006)

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

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

[img]http://dl2.iteye.com/upload/attachment/0128/9756/8c1aeb62-46c4-34d5-961c-994ce3be3cbc.png[/img]

你可能感兴趣的:(树莓派)