最近一直在自学嵌入式,前期已经在Arduino上实现红外线遥控器的应用,近期想通过树莓派Raspberry实现相同功能,本文只实现了按红外遥控器,终端上输出按钮信息。并没有实现完全将红外线功能嵌入程序中,通过按红外遥控器实现控制元件,这一功能详见另一篇博文:树莓派Raspberry通过BCM2835进行红外遥控IR remote control操作,控制元件。
我使用的是外接的红外接收器与遥控器,当前主要实现接收,解析,接收端与遥控器实物如下图
注意:接收端正负极不要弄反,电压不要弄错,按照说明使用,我就弄坏了一个
Arduino实现方法是使用#include
#include
int RECV_PIN = 11;
int LED_PIN = 13;
IRrecv irrecv(RECV_PIN); // 实例化
decode_results results;
void setup()
{
Serial.begin(9600);
irrecv.enableIRIn(); // Start the receiver
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
}
void loop() {
if (irrecv.decode(&results)) {
Serial.println(results.value, HEX);
if (results.value == 0xFFA25D) //开灯的值
{
digitalWrite(LED_PIN, LOW);
} else if (results.value == 0xFF629D) //关灯的值
{
digitalWrite(LED_PIN, HIGH);
}
irrecv.resume(); // Receive the next value
}
delay(100);
}
起初,我查阅了近20篇中文教程,发现都不能用,有些是修改/etc/modules,有些是修改/etc/modprobe.d,总之没有成功。花了五六个小时,后来没办法,查英文 教程,终于让我找到一个有启发的教程,但是,这个教程我还是没有成功使用,在结合另一个教程,最后成功使用。
两点说明,第一个教程主要让我注意到,我试验时(2019年5月30日最新版本,kernel 4.19)树莓派系统Raspbian系统版本的问题,另一个是所用的库lirc版本的问题。我想应该是这两个版本与诸多中文教程上的不同,所以始终调试不成功,瞎改一通设置也没啥用。我按照链接将系统回滚到kernel version 4.14,
系统版本查看方法:uname -a 可以百度,然后按照第二个教程实验成功,下面详述过程与方法:
pi@raspberrypi:~ $ uname -a
Linux raspberrypi 4.14.52-v7+ #1123 SMP Wed Jun 27 17:35:49 BST 2018 armv7l GNU/Linux
pi@raspberrypi:~ $ sudo apt-get install lirc
正在读取软件包列表... 完成
正在分析软件包的依赖关系树
正在读取状态信息... 完成
lirc 已经是最新版 (0.9.4c-9)。
升级了 0 个软件包,新安装了 0 个软件包,要卸载 0 个软件包,有 0 个软件包未被升级。
注意:Pin口的定义方式有很多种,这里使用的是 Broadcom BCM pin number(这是部分中文教程没有说的,作为小白的我确实不知道是哪一个,只能把每种都进行实验),下图展示不同的Pin口定义方式,接线的时候不要接错
设置方法:
当然我使用的是vim编辑的
sudo nano /etc/modules
末尾加上
当然这两个Pin口可以改的,注意 接线接对就行
i2c-dev
lirc_dev
lirc_rpi gpio_in_pin=23 gpio_out_pin=22
这个文件可能需要自己创建,因为我试过的教程太多,忘记是不是自己创建的了,另外有的教程还有其他参数,应该是可以一并添加的,此外有的中文教程参数中没有引号,我也不知道对不对
sudo nano /etc/lirc/lircd.conf.d/hardware.conf
内容
DRIVER="default"
DEVICE="/dev/lirc0"
MODULES="lirc_rpi
sudo nano /boot/config.txt
内容
dtoverlay=lirc-rpi,gpio_in_pin=23,gpio_out_pin=22,gpio_in_pull=up
sudo /etc/init.d/lircd stop
sudo /etc/init.d/lircd start
sudo /etc/init.d/lircd restart
sudo /etc/init.d/lircd stop
sudo mode2 -d /dev/lirc0
至此,当按红外遥控器时屏幕应该是会有数值了,如下图,也说明各项服务,环境已经搭建成功了
https://www.raspberrypi.org/forums/viewtopic.php?t=235256
Using LIRC with kernel 4.19.X and gpio-ir
Thu Mar 07, 2019 1:42 pm
Kernel 4.19 does not include lirc_dev, so it is recommended to use gpio-ir.
https://lb.raspberrypi.org/forums/viewt … 1&start=50
However, the command “irrecord” included in lirc does not work with gpio-ir
because the signal from /dev/lircX generated by gpio-ir is
slightly different from that of lirc_dev as follows:
lirc_dev:
space XXX
pluse XXX
space XXX
...
space XXX
pulse XXX
gpio-ir:
space XXX
space XXX
pulse XXX
space XXX
...
space XXX
pulse XXX
pulse XXX <- This shuold be "timeout"
Therefore, I created a patch to use irrecord with kernel 4.19.X and gpio-ir.
I also modified mode2 so that it yields the same signal as “ir-ctl -r”.
Instructions are shown below.
Before installing:
sudo su -c "grep '^deb ' /etc/apt/sources.list | sed 's/^deb/deb-src/g' > /etc/apt/sources.list.d/deb-src.list"
sudo apt update
sudo apt install devscripts
Installing with a patch for gpio-ir:
sudo apt build-dep lirc
mkdir build
cd build
apt source lirc
wget https://raw.githubusercontent.com/neuralassembly/raspi/master/lirc-gpio-ir.patch
patch -p0 -i lirc-gpio-ir.patch
cd lirc-0.9.4c
debuild -uc -us -b
cd ..
sudo apt install ./liblirc0_0.9.4c-9_armhf.deb ./liblirc-client0_0.9.4c-9_armhf.deb ./lirc_0.9.4c-9_armhf.deb
After installing:
Please add the following lines to /boot/config.txt. You can change pin numbers.
dtoverlay=gpio-ir,gpio_pin=24
dtoverlay=gpio-ir-tx,gpio_pin=25
You don't have to add anything to /etc/modules.
When using irrecord, please edit /etc/lirc/lirc_options.conf as follows. Restarting lirc is required.
driver = default
device = /dev/lirc1
When using irsend, please edit /etc/lirc/lirc_options.conf as follows. Restarting lirc is required.
driver = default
device = /dev/lirc0
资料一
kernel 4.1.9版本开始试验没成功,系统滚回4.1.4还是没成功,改用资料二才试验成功
Goals:
There are a number of projects like this around the internet. The hardest part for me – and for others, it seems – was the IR driver/lib configuration, so this project documents what worked for me given my combination of hardware and software.
My setup:
Step 0: Set up the hardware
There are many ways to set up your LED driver circuit. I used a basic transistor circuit like the one depicted at http://www.raspberry-pi-geek.com/Archive/2015/10/Raspberry-Pi-IR-remote.
Make note of the GPIO pin connected to the base of the transistor, as that’s the pin we need to control to drive the LED. In my case that’s pin 23 (you’ll see this number in the configuration instructions below).
TIP: Your eyes can’t see infrared light, but your phone’s camera can. Useful for debugging your circuit.
Step 1: Install LIRC
sudo apt-get install lirc
NOTE: I’m using stretch (Debian 9), so this installs LIRC 0.9.4c. 0.9.4 is quite different from 0.9.0, which is what you’ll get if you’re running jessie (Debian 8). If you have 0.9.0 Step 3 will be different1.
Step 2: Enable lirc-rpi or gpio-ir kernel module
NOTE: Whether you enable lirc-rpi or gpio-ir depends on the kernel version you’re using (check with uname -a). On 4.14 you’ll use lirc-rpi and on 4.19 you’ll use gpio-ir. Instructions for both cases are given below. See the Appendix if you’d like to read more about this.
We’re going to do this via the device tree by editing /boot/config.txt.
sudo vim /boot/config.txt
You’ll see these lines in config.txt:
# Uncomment this to enable the lirc-rpi module
#dtoverlay=lirc-rpi
If you’re on kernel version 4.14, uncomment the dtoverlay line and change it to look like this:
dtoverlay=lirc-rpi,gpio_in_pin=22,gpio_out_pin=23
If you’re on kernel version 4.19, add these lines (you can leave any lines containing lirc-rpi commented out, or you can remove them):
dtoverlay=gpio-ir,gpio_pin=22
dtoverlay=gpio-ir-tx,gpio_pin=23
See how gpio_out_pin / gpio-ir-tx’s gpio_pin is set to 23? If you’re not using pin 23 change that. You can ignore gpio_in_pin / gpio-ir’s gpio_pin. It’s used for an IR receiver. TODO(mtraver) document that if I ever actually use the receiver for anything.
Optional: To enable more verbose logging (which you’ll find in dmesg), add debug=1 like this (as long as you’re on 4.14; adding debug=1 didn’t seem to change the behavior of gpio-ir on 4.19):
# Uncomment this to enable the lirc-rpi module
dtoverlay=lirc-rpi,gpio_in_pin=22,gpio_out_pin=23,debug=1
DO NOT edit /etc/modules. Other tutorials may mention putting something similar to what we added to config.txt into /etc/modules. This is unnecessary.
DO NOT add a file in /etc/modprobe.d. Other tutorials may mention putting something similar to what we added to config.txt into a file like /etc/modprobe.d/ir-remote.conf or /etc/modprobe.d/lirc.conf. This is unnecessary.
Step 3: Configure LIRC
The default LIRC configuration does not enable transmitting. From the LIRC configuration guide:
From 0.9.4+ LIRC is distributed with a default configuration based on the devinput driver. This should work out of the box with the following limitations:
Let’s fix that.
sudo vim /etc/lirc/lirc_options.conf
Change driver to default and device to /dev/lirc0. Here’s the diff between the default config and my config:
$ diff -u3 /etc/lirc/lirc_options.conf.dist /etc/lirc/lirc_options.conf
--- /etc/lirc/lirc_options.conf.dist 2017-04-05 20:23:20.000000000 -0700
+++ /etc/lirc/lirc_options.conf 2017-10-14 14:58:18.584886645 -0700
@@ -8,8 +8,8 @@
[lircd]
nodaemon = False
-driver = devinput
-device = auto
+driver = default
+device = /dev/lirc0
output = /var/run/lirc/lircd
pidfile = /var/run/lirc/lircd.pid
plugindir = /usr/lib/arm-linux-gnueabihf/lirc/plugins
DO NOT edit or add hardware.conf. Other tutorials may mention making changes to /etc/lirc/hardware.conf. LIRC 0.9.4 does not use hardware.conf2.
Step 4: Add remote control config files
We need to tell LIRC which codes to transmit to talk to the equipment we wish to control. LIRC maintains a repo of config files for many remote controls: https://sourceforge.net/projects/lirc-remotes/
Find the one for your remote control and place it in /etc/lirc/lircd.conf.d. As long as it has a .conf extension it’ll be picked up.
If there isn’t an existing config for your remote, you’re in for an adventure… I happen to be controlling a Cambridge Audio CXA60 amp with my Raspberry Pi and there was no config file for it so I made one. It’s checked into this repo.
Here’s what my config directory looks like:
我对下面这个指令在这个教程一直没有成功过,很是困惑
$ ll /etc/lirc/lircd.conf.d
total 52
drwxr-xr-x 2 root root 4096 Oct 14 11:49 .
drwxr-xr-x 3 root root 4096 Oct 14 14:58 …
-rw-r–r-- 1 root root 2679 Oct 14 11:49 cxa_cxc_cxn.lircd.conf
-rw-r–r-- 1 root root 33704 Apr 5 2017 devinput.lircd.conf
-rw-r–r-- 1 root root 615 Apr 5 2017 README.conf.d
Step 5: Reboot
sudo reboot
Below are some sanity checks for modules and services and stuff after you reboot.
On kernel version 4.14 using lirc-rpi:(我没有成功应用这个命令)
$ dmesg | grep lirc
[ 3.276240] lirc_dev: IR Remote Control driver registered, major 243
[ 3.285866] lirc_rpi: module is from the staging directory, the quality is unknown, you have been warned.
[ 4.340562] lirc_rpi: auto-detected active low receiver on GPIO pin 22
[ 4.340882] lirc_rpi lirc_rpi: lirc_dev: driver lirc_rpi registered at minor = 0
[ 4.340888] lirc_rpi: driver registered!
[ 11.929858] input: lircd-uinput as /devices/virtual/input/input0
$ lsmod | grep lirc
lirc_rpi 9032 3
lirc_dev 10583 1 lirc_rpi
rc_core 24377 1 lirc_dev
$ ll /dev/lirc0
crw-rw---- 1 root video 243, 0 Oct 14 17:08 /dev/lirc0
$ ps aux | grep lirc
root 343 0.0 0.1 4208 1084 ? Ss 17:08 0:00 /usr/bin/irexec /etc/lirc/irexec.lircrc
root 381 0.0 0.1 4280 1140 ? Ss 17:08 0:00 /usr/sbin/lircmd --nodaemon
root 516 0.4 0.4 7316 3980 ? Ss 17:09 0:00 /usr/sbin/lircd --nodaemon
root 517 0.0 0.1 4284 1164 ? Ss 17:09 0:00 /usr/sbin/lircd-uinput
pi 574 0.0 0.0 4372 552 pts/0 S+ 17:09 0:00 grep --color=auto lirc
On kernel version 4.19 using gpio-ir:
$ dmesg | grep "lirc\|gpio-ir"
[ 3.459164] rc rc0: GPIO IR Bit Banging Transmitter as /devices/platform/gpio-ir-transmitter@17/rc/rc0
[ 3.459396] rc rc0: lirc_dev: driver gpio-ir-tx registered at minor = 0, no receiver, raw IR transmitter
[ 3.522934] rc rc1: lirc_dev: driver gpio_ir_recv registered at minor = 1, raw IR receiver, no transmitter
[ 14.468862] input: lircd-uinput as /devices/virtual/input/input1
$ lsmod | grep gpio_ir
gpio_ir_tx 16384 0
gpio_ir_recv 16384 0
$ ll /dev/lirc0
crw-rw---- 1 root video 252, 0 May 26 17:10 /dev/lirc0
$ ps aux | grep lirc
root 364 0.0 0.1 4268 1088 ? Ss 17:11 0:00 /usr/sbin/lircmd --nodaemon
root 369 0.0 0.1 4196 1072 ? Ss 17:11 0:00 /usr/bin/irexec /etc/lirc/irexec.lircrc
root 555 0.1 0.3 7296 3428 ? Ss 17:11 0:00 /usr/sbin/lircd --nodaemon
root 556 0.0 0.1 4272 1172 ? Ss 17:11 0:00 /usr/sbin/lircd-uinput
pi 893 0.0 0.0 4368 544 pts/0 S+ 17:13 0:00 grep --color=auto lirc
Step 6: Test
irsend SEND_ONCE cambridge_cxa KEY_POWER_ON
Replace cambridge_cxa with the contents of the name field from your remote control config file, and KEY_POWER_ON with some code from the codes section.
At the very least this should execute without errors. If you enabled debugging in the device tree (see Step 2) you can get some insight into what happened by executing dmesg | grep lirc. Use your phone camera to watch the LED light up.
…
…
…
…
Appendix
Warning: Cannot access device: /dev/lirc0 on kernel 4.19
NOTE: This is just a record of my debugging process from when I upgraded to 4.19 and LIRC stopped working. All actions required for 4.19 are already included above.
On 2019-05-25 I upgraded my pi and it ended up on Linux 4.19.42-v7+ #1219 SMP Tue May 14 21:20:58 BST 2019 armv7l.
LIRC no longer worked! Checking the logs I found this:
$ grep lirc /var/log/syslog
May 25 15:27:01 irremote-pi lircd-0.9.4c[793]: Warning: Cannot access device: /dev/lirc0
Thankfully I had checked the kernel version before upgrading. It was Linux 4.14.52-v7+ #1123 SMP Wed Jun 27 17:35:49 BST 2018 armv7l.
As a first step I tried rolling back to that version using rpi-update. I found the commit in github.com/Hexxeh/rpi-firmware that upgraded to 4.14.52 and passed that commit hash to rpi-update to roll back:
sudo rpi-update 963a31330613a38e160dc98b708c662dd32631d5
After rebooting, the kernel was indeed rolled back and LIRC worked again.
Alright, now time to find the breaking commit!
First I jumped straight to the last 4.14: kernel: Bump to 4.14.98 (a08ece3d48c3c40bf1b501772af9933249c11c5b, committed 2019-02-12). This put me on Linux 4.14.98-v7+ #1200 SMP Tue Feb 12 20:27:48 GMT 2019 armv7l GNU/Linux and LIRC worked. Woohoo!
The next update goes all the way to 4.19.23. I upgraded to 1c60d16af8cc43214495f18549228dde83e99265 and ended up on Linux 4.19.23-v7+ #1202 SMP Mon Feb 18 15:55:19 GMT 2019 armv7l GNU/Linux. LIRC did not work; the warning about /dev/lirc0 was back.
gpio-ir on 4.19
I was all set to call it a day and leave my pi on 4.14, but then I found this: https://www.raspberrypi.org/forums/viewtopic.php?t=235256.
The TL;DR is that 4.19 does not include lirc_dev so one must use gpio-ir. It’s simply a change to the dtoverlay in /boot/config.txt and it works as before. For sending IR codes that’s all that’s required.
For recording there’s more to do but I’ll leave it as an exercise for the reader to follow the instructions in the aforementioned raspberrypi.org forum post. For me sending IR codes worked both with and without the patched LIRC; I don’t record IR codes in this project so I stuck with the stock, unpatched LIRC.
Footnotes
[1] Other projects around the internet tend to be built using 0.9.0, leading to some frustration while configuring, even though configuring 0.9.4 is a nicer experience. I hope this project can help others in the same boat!
[2] Alec Leamas, LIRC maintainer, states here that “0.9.4 does not use hardware.conf.”
[3] “How can this be!? The Raspberry Pi 3 B uses the BCM2837, a 64-bit ARMv8 SoC!” you exclaim. “That is correct,” I reply, “but Raspbian is 32-bit only so the chip runs in 32-bit mode. It therefore cannot execute ARMv8 binaries.”
Using LIRC on the Raspberry Pi 3 (Raspbian Stretch)
I found a few guides on how to use LIRC (a mature library to read and write IR signals) and they seem to be a little dated. I am thankful for those guides I found but I just needed to provide the necessary updates in case anyone runs into the same issues I had.
The really cool thing about LIRC is that once the lirc module is loaded, the lircd daemon runs and provides a way to read decoded infrared signals on a Unix Socket! (/var/run/lirc/lircd). In this way you can just read and write that socket in your custom programs as if it were a network stream.
Setup Guide
You will need to correctly install, configure, enable and run lirc. These steps will help you do that.
1. Install LIRC
sudo apt-get install lirc
2. Load the module at boot time
Pick an input and an output pin for the LIRC module to use. The pin number is the Broadcom BCM pin number. In my case I have chosen 22 as output and 23 as input; see the file contents below.
Edit the Modules File: sudo nano /etc/modules
It should look something like like this (I chose pins GPIO.23 and GPIO.22)
i2c-dev
lirc_dev
lirc_rpi gpio_in_pin=23 gpio_out_pin=22
3. Add the module’s hardware configuration
Create the hardware.conf file:
sudo nano /etc/lirc/lircd.conf.d/hardware.conf
Enter the text so the file ends up looking like this:
DRIVER="default"
DEVICE="/dev/lirc0"
MODULES="lirc_rpi"
4. Change the coot configuration slightly
sudo nano /boot/config.txt
find the line where dtoverlay=lirc was commented out and change it so it looks like this:
dtoverlay=lirc-rpi,gpio_in_pin=23,gpio_out_pin=22,gpio_in_pull=up
Usage Guide
Starting, Stopping and Restarting the Service
Once you ar all set, you can start or stop the daemon that exposes the scoket very easily:
sudo /etc/init.d/lircd stop
sudo /etc/init.d/lircd start
sudo /etc/init.d/lircd restart
Testing IR Input
You can test your receiver by first stopping the lircd daemon and then running lirc’s mode2 utility which is simply used to dump lirc’s driver kernel messages to the console.
sudo /etc/init.d/lircd stop
sudo mode2 -d /dev/lirc0
Testing IR Output
You can test your IR LED is correctly sending IR signals using the irsend utility. Check out the guide on how to do this in the following link. This requires you to record and assign certain IR sequences and save them to your configuration file.
http://www.instructables.com/id/How-To-Useemulate-remotes-with-Arduino-and-Raspber/
Using lirc from your own programs
As stated before the IR signals are written and decoded to and from a socket. So all you need to do is connect to that Unix socket and normally read and write signals.
A c# example of how to read signals is available here: https://github.com/shawty/raspberrypi-csharp-lirc Basically, all you need to do is parse the incoming socket data as ACII as follows:
Example:
0000000000f40bf0 00 KEY_UP ANIMAX
In any case, you can always get to the documentation of the lircd socket here: http://www.lirc.org/html/lircd.html
This Gist also looks like a pretty good setup guide https://gist.github.com/prasanthj/c15a5298eb682bde34961c322c95378b
另外附两个教程的完整图片