利用红外技术实现硬件控制:从电视遥控到继电器操作

本文详细介绍了如何利用红外技术进行硬件控制,包括红外协议解析、树莓派与Linux驱动配置、Arduino继电器控制,并探讨了红外技术在安全领域的潜在应用。

利用红外技术实现硬件控制

Ray Felch

概述

红外技术已存在很长时间,是一种通过红外辐射传输数据的无线技术。红外线是波长略超出可见光谱的电磁辐射(EMR),因此肉眼无法看到。有趣的是:虽然我们的眼睛看不到红外线,但手机摄像头可以完美捕捉并显示这些传输!

红外技术广泛应用于热成像相机、医疗应用、军事应用(目标获取、夜视等)、加热与冷却以及计算机外围设备通信等领域。

本文旨在展示捕获红外通信并重放传输的简易性。首先,我将展示如何使用Linux仓库中常见的红外工具捕获家中几个遥控器的IR信号。

乍看之下,黑客攻击红外电视遥控器可能有些不切实际,但实际上操作非常简单且成本几乎为零。关于红外过程的信息丰富,绝对值得投入精力。作为研究的一部分,我决定捕获Kodi(开源媒体播放器)遥控器、Arduino通用遥控器和HDMI切换器遥控器的红外按键信号。我惊讶于获取这些数据的速度和简便性!

目标

  • 熟悉NEC IR协议
  • 使用树莓派和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是飞利浦的两种不同协议,均基于曼彻斯特编码。它们的载波频率设置为36KHz,推荐PWM占空比为1/4或1/3,但不是强制性的。

在曼彻斯特编码中,位时间由恒定时钟提供,因此值1和0都需要相同的时间,但在一种情况下脉冲先于暂停(此处为逻辑0),另一种情况则相反(此处为逻辑1)。

传输和接收红外信号

使用树莓派和Linux IR驱动程序

使用树莓派和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信号之上。

最终,我发现配置硬件以利用红外线的力量并通过按键控制继电器非常容易。红外硬件控制的好处几乎是无限的,仅受硬件设计师想象力的限制。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计