利用红外技术实现硬件控制与信号重放

本文详细介绍了如何利用红外技术捕获和重放遥控器信号,包括NEC、SIRC等红外协议解析,使用树莓派和Linux驱动进行信号处理,以及通过Arduino Mega2560控制继电器实现硬件开关功能。

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

概述

红外技术是一种利用红外辐射传输数据的无线技术,其波长位于可见光谱之外,因此人眼无法直接观察。有趣的是,手机摄像头能够捕捉并显示这些红外传输信号。

红外技术广泛应用于热成像相机、医疗设备、军事应用(如目标获取和夜视)、温度调节以及计算机外围设备通信等领域。本文旨在展示如何轻松捕获和重放红外通信信号。

目标

  • 熟悉NEC红外协议
  • 使用树莓派和Linux驱动检测和传输红外遥控代码
  • 利用红外和Mega2560模块控制继电器

红外协议概述

红外协议是一组规则,用于指定如何传输比特或字节组。发射设备(红外发射二极管)以特定频率发送脉冲,持续特定时间后暂停。每个比特(0或1)通过特定的时间组合编码,以便红外接收器正确读取传输内容。

NEC协议

NEC协议由NEC开发,被广泛采用。其波形由起始帧、比特流和消息结束符组成。协议使用脉冲距离编码,每个脉冲 burst 长度为562.5µs,载波频率为38kHz。

逻辑比特传输方式:

  • 逻辑‘0’:562.5µs脉冲 burst 后跟562.5µs空间,总传输时间1.125ms
  • 逻辑‘1’:562.5µs脉冲 burst 后跟1.6875ms空间,总传输时间2.25ms

按键按下时,传输的消息包括:

  • 9ms前导脉冲 burst
  • 4.5ms空间
  • 8位接收设备地址
  • 8位地址逻辑反码
  • 8位命令
  • 8位命令逻辑反码
  • 结束消息传输的562.5µs脉冲 burst

数据字节以最低有效位优先发送。

SIRC协议

SIRC是索尼的专有协议,有三种变体(12、15或20位)。所有变体中,命令字段固定为7位,信息比特以最低有效位优先流式传输。

  • 12位版本:7位命令,5位地址
  • 15位版本:7位命令,8位地址
  • 20位版本:7位命令,5位地址,8位扩展位

采用脉冲宽度调制,载波频率40kHz,比特时间1.2ms或0.6ms。

PHILIPS RC5和RC6协议

RC5和RC6是飞利浦的两种协议,基于曼彻斯特编码。载波频率36kHz,推荐PWM占空比1/4或1/3。曼彻斯特编码中,比特时间由恒定时钟提供,逻辑0和1传输时间相同,但脉冲和暂停顺序相反。

传输和接收红外信号

使用树莓派和Linux红外驱动

通过树莓派(Raspbian Buster)、红外Linux工具、TSOP38238接收器、940nm发射二极管、220欧姆电阻和连接线,可以快速熟悉红外通信的传输和接收。Linux驱动已处理各种协议的复杂性。

使用ir-keytable工具和上述电路,可以检测和解码遥控器按键。配置config.txt文件以启用红外传输(如不需要传输,可排除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
2
pi@rasp11:~/infra-red $ lsmod | grep gpio
gpio_ir_recv      16384 0

列出设备并安装ir-keytable

1
2
pi@rasp11:~/infra-red $ sudo apt-get install ir-keytable -y
pi@rasp11:~/infra-red $ ir-keytable

测试遥控器并确认IR接收器设备工作正常。

使用红外和Mega2560模块控制继电器

本项目使用Elegoo Mega2560 R3微控制器板,基于ATmega2560,具有54个数字输入/输出引脚(其中15个可用于PWM输出)、16个模拟输入、4个UART和16MHz晶体振荡器。

连接Sainsmart 4通道继电器模块,通过控制输入引脚(IN1–IN4)拉低(接地)来激活继电器和LED。

电路图略。

使用Arduino IDE刷写Mega2560

以下草图监控Arduino通用遥控器的按键(电源、静音、模式和播放按钮,代码分别为0x45、0x46、0x47、0x44),发现后触发相应继电器通道(IN1–IN4)切换LED。

Mega2560的引脚39、37、35和33定义为输出(通常高电平),发现特定IR代码时拉低。

 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
// 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 32 //Mega2560
IRdecode myDecoder; //Decoder object

int play  = 39;
int mute  = 37;
int mode  = 35;
int power = 33;

bool CH_1 = false;
bool CH_2 = false;
bool CH_3 = false;
bool CH_4 = false;

void setup() {
  pinMode(power, OUTPUT);
  pinMode(mode, OUTPUT);
  pinMode(mute, OUTPUT);
  pinMode(play, OUTPUT);

  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) {
      switch(myDecoder.value) {
        case 0xffa25d:  //Power
          Serial.println("Power");
          if (CH_1 == false) digitalWrite(power, LOW);
          if (CH_1 == true) digitalWrite(power, HIGH);
          CH_1 = !CH_1;
          break;
        
        case 0xff629d:  //Mode
          Serial.println("Mode");
          if (CH_2 == false) digitalWrite(mode, LOW);
          if (CH_2 == true) digitalWrite(mode, HIGH);
          CH_2 = !CH_2;
          break;
        
        case 0xffe21d:  //Mute
          Serial.println("Mute");
          if (CH_3 == false) digitalWrite(mute, LOW);
          if (CH_3 == true) digitalWrite(mute, HIGH);
          CH_3 = !CH_3;
          break;

        case 0xff22dd:  //Play
          Serial.println("Play");
          if (CH_4 == false) digitalWrite(play, LOW);
          if (CH_4 == true) digitalWrite(play, HIGH);
          CH_4 = !CH_4;
          break;
      }
    myReceiver.enableIRIn(); //Restart the receiver
    }
  }
}

结论

本项目展示了利用开源工具研究红外通信的简便性。红外波长位于可见光谱之外,人眼不可见,但可用于数据传输。研究人员甚至利用红外照明脉冲在气隙安全摄像头网络上进行双向隐蔽通信,渗透和渗出数据。

配置硬件以利用红外技术控制继电器非常简单,只需按下按钮即可。红外硬件控制的优势仅受硬件设计师想象力的限制。

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