使用红外技术实现硬件控制
Ray Felch //
概述
红外技术已存在很长时间,是一种通过红外辐射传输数据的无线技术。红外是电磁辐射(EMR),波长略超出可见光谱。因此,红外无法被肉眼看到。有趣的是:虽然我们的眼睛看不到红外,但手机摄像头可以捕获并显示这些传输!
您可能知道,红外技术用于许多应用,如热成像相机、医疗应用、军事应用(目标获取、夜视等)、加热和冷却,以及计算机外围设备通信,仅举几例。
本文的目标是展示捕获红外通信并重放传输是多么容易。首先,我将展示如何使用大多数Linux仓库中可用的红外工具,捕获家中几个遥控器的IR信号。
乍一看,黑客攻击红外电视遥控器可能有点不切实际,但它可以非常容易地完成,成本几乎为零。关于红外过程的信息丰富,绝对值得努力。作为研究的一部分,我决定捕获Kodi(开源媒体播放器)遥控器、Arduino通用遥控器和HDMI开关遥控器的红外按钮按下。我对检索这些数据的速度和简便性感到惊讶!
目标
- 熟悉NEC IR协议
- 使用Raspberry Pi和Linux驱动程序检测和传输IR遥控代码
- 使用IR和Mega2560模块控制继电器
IR协议(一般信息)
通常,IR协议是一组规则,指定如何传输一组位或字节。有一个传输设备(IR发射二极管)以特定频率发送这些脉冲特定时间,然后暂停特定时间。每个位,0或1,用这些定时的指定组合编码,从而使IR接收器能够正确读取传输。有许多红外协议,但三个更流行的如下:
NEC 是一个知名协议,也许是最广泛使用的。它由NEC开发,已被许多公司采用。其波形由起始帧、位流和消息结束终止符组成。
NEC IR传输协议使用消息位的脉冲距离编码。每个脉冲突发长度为562.5µs,载波频率为38kHz。逻辑位传输如下:
- 逻辑‘0’ – 562.5µs脉冲突发后跟562.5µs空间,总传输时间1.125ms
- 逻辑‘1’ – 562.5µs脉冲突发后跟1.6875ms空间,总传输时间2.25ms
当遥控器上按下键时,传输的消息按顺序包括:
- 9ms前导脉冲突发(逻辑数据位脉冲突发长度的16倍)
- 4.5ms空间
- 8位接收设备地址
- 8位地址的逻辑反码
- 8位命令
- 8位命令的逻辑反码
- 最终562.5µs脉冲突发表示消息传输结束
四个字节的数据位每个都先发送最低有效位。
SIRC 是SONY的专有协议,存在三种变体(12、15或20位)。在所有变体中,命令字段固定长度为7位。所有信息位都先流式传输最低有效位。
- 12位版本,7命令位,5地址位。
- 15位版本,7命令位,8地址位。
- 20位版本,7命令位,5地址位,8扩展位。
- 脉冲宽度调制。
- 载波频率40kHz。
- 位时间1.2ms或0.6ms。
PHILIPS RC5 & RC6 PROTOCOL
RC5 / RC6 Manchester
RC5和RC6是Philips的两种不同协议,都基于曼彻斯特编码。它们的载波频率设置为36KHz,推荐PWM占空比为1/4或1/3,但不是强制性的。
在曼彻斯特编码中,位时间由恒定时钟提供,因此值1和0都花费相同时间,但在一种情况下脉冲先于暂停(这里是逻辑0),另一种相反(这里是逻辑1)。
传输和接收红外信号
使用Raspberry Pi和Linux IR驱动程序
使用Raspberry Pi与Raspbian(Buster)、红外Linux工具、一些组件(TSOP38238接收器、940nm发射二极管和220欧姆电阻)以及一些连接线,可以相当快地熟悉传输和接收红外通信。不需要理解各种协议的复杂性,因为工作已在Linux驱动程序中完成。
使用ir-keytable
(处理遥控器的瑞士军刀工具)和上述电路,我们可以检测和解码遥控器按钮按下。http://manpages.ubuntu.com/manpages/bionic/man1/ir-keytable.1.html
自定义config.txt:
作为此配置的一部分,IR传输也配置了。如果不需要传输,排除dtoverlay=gpio-ir-tx,gpio_pin=15
。一些输出可能因此不同。
更新config.txt变量:
1
2
3
4
5
|
pi@rasp11:~/infra-red $ sudo nano /boot/config.txt
# BEGIN ADDED
dtoverlay=gpio-ir,gpio_pin=14
#dtoverlay=gpio-ir-tx,gpio_pin=15
# END ADDED
|
重启:
1
|
pi@rasp11:~/infra-red $ sudo reboot
|
确认gpio模块加载:
1
2
|
pi@rasp11:~/infra-red $ lsmod | grep gpio
gpio_ir_recv 16384 0
|
列出设备:
1
2
3
4
5
6
7
8
9
10
11
12
|
cat /proc/bus/input/devices
I: Bus=0019 Vendor=0001 Product=0001 Version=0100
N: Name="gpio_ir_recv"
P: Phys=gpio_ir_recv/input0
S: Sysfs=/devices/platform/ir-receiver@e/rc/rc0/input4
U: Uniq=
H: Handle rs=kbd event4
B: PROP=20
B: EV=100017
B: KEY=fff 0 0 4200 108fc32e 2376051 0 0 0 7 158000 4192 4001 8e9680 0 0 10000000
B: REL=3
B: MSC=10
|
安装ir-keytable:
1
|
pi@rasp11:~/infra-red $ sudo apt-get install ir-keytable -y
|
确认安装:
1
2
3
4
5
6
7
8
9
10
|
pi@rasp11:~/infra-red $ ir-keytable
Found /sys/class/rc/rc0/ (/dev/input/event4) with:
Name: gpio_ir_recv
Driver: gpio_ir_recv, table: rc-rc6-mce
LIRC device: /dev/lirc0
Attached BPF protocols: Operation not permitted
Supported kernel protocols: other lirc rc-5 rc-5-sz jvc sony nec sanyo mce_kbd rc-6 sharp xmp imon
Enabled kernel protocols: lirc rc-6
bus: 25, vendor/product: 0001:0001, version: 0x0100
Repeat delay = 500 ms, repeat period = 125 ms
|
测试遥控器:
1
2
|
pi@rasp11:~/infra-red $ sudo ir-keytable -p all
Protocols changed to other lirc rc-5 rc-5-sz jvc sony nec sanyo mce_kbd rc-6 sharp xmp imon
|
确认IR接收器设备工作:
1
2
3
4
5
6
7
8
9
10
|
pi@rasp11:~/infra-red $ sudo ir-keytable
Found /sys/class/rc/rc0/ (/dev/input/event4) with:
Name: gpio_ir_recv
Driver: gpio_ir_recv, table: rc-rc6-mce
LIRC device: /dev/lirc0
Attached BPF protocols:
Supported kernel protocols: other lirc rc-5 rc-5-sz jvc sony nec sanyo mce_kbd rc-6 sharp xmp imon
Enabled kernel protocols: lirc rc-5 rc-5-sz jvc sony nec sanyo mce_kbd rc-6 sharp xmp imon
bus: 25, vendor/product: 0001:0001, version: 0x0100
Repeat delay = 500 ms, repeat period = 125 ms
|
注意设备找到为rc0
关于rc0和rc1的说明:
通常IR接收器分配给/sys/class/rc/rc0。然而,由于多线程设备探测的性质,接收器设备可以分配给/sys/class/rc/rc1。
在以下说明中,当使用-s rc0调用ir-keytable且没有响应或错误时,使用-s r1。如果未指定-s,则rc0是默认值。然而,由于接收器在启动期间可能分配给rc1,建议始终指定-s。这样,如果使用“错误”设备,将出现错误。
使用rc0测试遥控器(扫描按钮按下加载所有协议):
1
2
|
pi@rasp11:~/infra-red $ ir-keytable -t -s rc0
Testing events. Please, press CTRL-C to abort.
|
Kodi遥控器的样本读数
所有三个遥控器的捕获代码
使用红外进行硬件控制
使用IR和Mega2560模块控制继电器
- 通用遥控器
- Sainsmart 4通道继电器模块
- Mega2560模块
对于这个项目,我们将使用Elegoo Mega2560 R3。Mega2560是基于ATmega2560的微控制器板。它有54个数字输入/输出引脚(其中15个可用作PWM输出)、16个模拟输入、4个UART(硬件串行端口)和16 MHz晶体振荡器。
这个模块类似于增强版的Arduino Uno,在撰写本文时,价格合理,略低于40美元。它与大多数为Uno设计的屏蔽兼容,并支持使用Arduino IDE软件环境配置闪存。
对于这个演示,我选择将LED连接到四个继电器中的每一个,以视觉指示继电器闭合。应注意,Sainsmart继电器可以配置为控制各种AC/DC硬件,如照明、电机、传感器等,仅受所选继电器的电压/电流额定值限制。本演示中使用的模块是一个四通道5伏继电器模块,能够处理高达10A @ 120VAC或10A @ 28VDC。每个继电器提供常开或常闭配置。我选择使用常开端子(LED通常关闭)。
控制四个独立继电器相当简单,如下所示。要接合特定继电器并激活其对应的LED,需要将特定输入控制引脚(IN1 – IN4)拉低(GND)。
电路图
使用Arduino IDE刷新Mega2560
以下草图将查找Arduino通用遥控器上的按钮按下。具体来说,此草图将监视“电源”、“静音”、“模式”和“播放”按钮(代码分别为:0x45、0x46、0x47、0x44),并在发现时接合相应的继电器通道(IN1 – IN4)以切换通道的LED。
Mega2560上的引脚39、37、35和33定义为输出(通常高电平),并在发现特定IR代码时拉低。
SainsmartIR.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
// Arduino sketch to capture infrared codes and close/open relays based on matching criteria
// Modified NeoPixel_IR sketch from Adafruit_CircuitPlayground, using IRLibAll library
// Written to interface with Sainsmart 4 relay module.
// Author: R.F. Felch 01/28/2021
#include <IRLibAll.h>
//IRrecv myReceiver(11);//receiver on pin 11 //Arduino Uno
IRrecv myReceiver(11);//receiver on pin 32 //Mega2560
IRdecode myDecoder;//Decoder object
// Arduino Uno
//int play = 8;
//int mute = 7;
//int mode = 4;
//int power = 2;
// Mega2560
int play = 39;
int mute = 37;
int mode = 35;
int power = 33;
// Channel status false = Relay open true = Relay closed
bool CH_1 = false;
bool CH_2 = false;
bool CH_3 = false;
bool CH_4 = false;
void setup() {
pinMode(power, OUTPUT); // Relay channel 1
pinMode(mode, OUTPUT); // Relay channel 2
pinMode(mute, OUTPUT); // Relay channel 3
pinMode(play, OUTPUT); // Relay channel 4
// Set channels high open relay
digitalWrite(power, HIGH);
digitalWrite(mode, HIGH);
digitalWrite(mute, HIGH);
digitalWrite(play, HIGH);
Serial.begin(115200);
Serial.println("Scanning for IR codes");
myReceiver.enableIRIn(); // Start the receiver
}
void loop() {
if (myReceiver.getResults()) {
myDecoder.decode();
if (myDecoder.protocolNum == NEC) {
//Serial.println(myDecoder.value); // uncomment to view captured values
switch(myDecoder.value) {
case 0xffa25d: //Power
Serial.println("Power");
if (CH_1 == false) digitalWrite(power, LOW); // close relay ch-1
if (CH_1 == true) digitalWrite(power, HIGH); // open relay ch-1
CH_1 = !CH_1;
break;
case 0xff629d: //Mode
Serial.println("Mode");
if (CH_2 == false) digitalWrite(mode, LOW); // close relay ch-2
if (CH_2 == true) digitalWrite(mode, HIGH); // open relay ch-2
CH_2 = !CH_2;
break;
case 0xffe21d: //Mute
Serial.println("Mute");
if (CH_3 == false) digitalWrite(mute, LOW); // close relay ch-3
if (CH_3 == true) digitalWrite(mute, HIGH); // open relay ch-3
CH_3 = !CH_3;
break;
case 0xff22dd: //Play
Serial.println("Play");
if (CH_4 == false) digitalWrite(play, LOW); // close relay ch-4
if (CH_4 == true) digitalWrite(play, HIGH); // open relay ch-4
CH_4 = !CH_4;
break;
}
myReceiver.enableIRIn(); //Restart the receiver
}
}
}
|
Arduino通用遥控器按钮按下的典型运行
结论
对我来说,这是一个从开始就令人愉快的项目,尽管红外通信已经存在很长时间,但知道我们有开源工具可用于研究是很好的。
此外,有趣的是了解到红外波长刚好在可见光谱之外,肉眼不可见。我最近发现一组研究人员利用这些信息作为手段,在气隙安全摄像头网络上渗透和渗出专有数据。https://arxiv.org/abs/1709.05742
通过内部安装在网络上的恶意软件,他们通过控制(脉冲)IR照明,在组织内部网络和远程攻击者之间建立了双向隐蔽通信。研究人员表示,他们能够以20位/秒的速率渗出PIN码、密码和加密密钥,并以100位/秒的速率将数据渗入网络。他们继续说,二进制数据如命令和控制(C2)和信标消息被编码在IR信号之上。
最终,我发现配置硬件以利用红外力量并通过按钮按下控制继电器相当容易。红外硬件控制的好处几乎无限,仅受硬件设计者想象力的限制。