12.1 认识红外线

可见光、红外线和电波,都是电磁波的一种,
远红外线和近红外线,人体在常温下所释放的红外线波长约10um(微米)。靠近可见光部分的近红外线,几乎不会散发热能,通常用于红外线通信、遥控和距离传感器。

12.2 人体红外线传感器

被动式(Passive)红外移动传感器,而红外线(Infrared)英文简称IR,所以此传感器又称为PIR移动传感器,一般通称为“人体红外线传感器”,所谓“被动式”侦测,代表这种传感器内部有两个侦测“窗口”,被侦测物体必须要水平移动,它才能比较出红外线的变化,若朝向它的正面移动,就比较不容易被侦测到。
热释电型传感器,热释电(pyroelectric)代表该模块会随着温度变化产生电子信号。传感器模块上的IC电路将会接收并处理传感器的信号,以高电位或低电位的形式输出。总之,人体红外线侦测模块,相当于电子开关,平常输出低电位(0V),侦测到人体移动时,变成高电位(3.3V)。

动手做12-1 监测人体移动

实验说明: 使用人体红外线传感器来点亮位于Arduino板子13端口的LED
**程序:**由于人体红外线传感器模块只会返回0与1两种状态值。

const byte pirPin = 12;  //红外线传感器信号端口
const byte ledPin = 13;  //LED端口
void setup() {
  pinMode(pirPin, INPUT);
  pinMode(ledPin, OUTPUT);  //LED端口设定成“输出”
}

void loop() {
  boolean val = digitalRead(pirPin);  //读取传感器值
  if (val) {
    digitalWrite(ledPin, HIGH);
  } else {
    digitalWrite(ledPin, LOW);
  }
}

12.3 红外线遥控

红外发射

红外发射的遥控器发射的38K红外载波信号是由遥控器里的编码芯片对其进行编码。下面用TC9012芯片了解下编码方式。它是以一段引导码,用户码,数据码,数据反码组成,利用脉冲的时间间隔来区别是0还是1信号(高电平低电平之比约为1:1时被认为是信号0,),而编码就是由这些0 、1信号组成。同一个遥控器的用户码是不变的,用数据吗不同来分辨遥控器按的键不同。当按下遥控器按键时,遥控器发送出红外载波信号,红外接收器接收到信号时程序对载波信号进行解码,通过数据码的不同来判断按下的是哪个键。单片机由接收到的01信号进行解码,由此判断遥控器按下的是什么键。
(编码方式详细参考附件) TC9012红外遥控集成芯片.pdf
在这里插入图片描述
红外线遥控接收器,都只对特定的频率信号(正确的名字叫做载波,通常是36kHZ或38kHZ)和“通关密语”有反应。这个“通关密语”称为协议。
红外线遥控接收元器件,它的内部包含红外线接收元器件以及信号处理IC,常见的型号是TSOP4836和TSOP4838(后面两个数字代表载波频率)。
普通的红外线接收元器件不含信号处理IC,其主要规格是感应的红外线波长范围。

动手做12-2 使用IRremote扩展库解析红外线遥控值

实验说明: 将组装一个Arduino万用红外线遥控接收器,并通过IRremote扩展库(网址:https://github.com/z3t0/Arduino-IRremote),读取各大品牌的红外线遥控器信号。

安装Arduino IDE的时候就已经安装过一个RobotIRremote库,如果有的话,就把原来的删除,然后解压这个库文件。

程序: 请先把“IRremote”扩展库文件复制到Arduino的libraries文件夹。选择文件→示例→IRremote→IRrecvDemo。

#include <IRremote.h>
int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);  //声明一个红外接收对象,名叫irrecv,接收端口是11
decode_results results;   //  声明一个存储接收值得变量

void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn();  //启动红外接收功能
}

void loop() {
  //解析红外接收值,若decode()返回true,代表有收到新的数据。
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);  //读取解析后的数字,并以16进位格式输出。
    irrecv.resume();  //准备进行接收下一组数据
  }
}

遥控器的每个按键都对应了不同的编码,不同的遥控器使用的编码也不相同。

出现“FFFFFFFF”编码,是因为我使用的是NEC协议的遥控器,当按住某按键不放时,其会发送一个重复编码“FFFFFFFF”。而其他协议的遥控器,则会重复发送对应的编码。
你可以在以下网址找到常见品牌遥控器的编码http://lirc.sourceforge.net/remotes/

读取红外线原始(raw)格式

IRremote扩展库提供另一个“IRrecvDump”示例程序,能辨别并显示红外线遥控信号的格式名称,并输出接收器所收到的原始数据。

动手做12-3 使用红外线遥控器控制舵机

实验说明:取得红外线遥控器的句柄之后,你就可以用遥控器来控制Arduino,本例将示范通过红外线遥控舵机。
实验程序:将依据遥控器的左、右箭头键,调整舵机的旋转角度,以及“录像”按键打开或关闭板子上第13脚的LED。

#include <IRremote.h>
#include <Servo.h>

Servo servo;
const byte RECV_PIN = 11;  //
const byte LED_PIN = 13;   //
const byte SERVO_PIN = 8;  //
boolean sw = false;        //
byte servoPos = 90;        //

IRrecv irrecv(RECV_PIN);   //
decode_results results;    //

void setup() {
  irrecv.enableIRIn();       //
  pinMode(LED_PIN, OUTPUT);  //
  servo.attach(SERVO_PIN);   //
  servo.write(servoPos);     //

}

void loop() {
  if (irrecv.decode(&results)) {  //
    switch (results.value) {   //
      case 0xC1C7C03F:       //若此数值等于“录像”
        sw = !sw;          //
        digitalWrite(LED_PIN, sw);  //
        break;
      case 0xC1C7C43B:   //
        if (servoPos > 10) {  //
          servoPos -= 10; //
          servo.write(servoPos);  //
        }
        break;
      case 0xC1C744BB:
        if (servoPos < 170) {
          servoPos += 10;  //
          servo.write(servoPos);  //
        }
        break;
    }
    irrecv.resume();  //
  }
}

动手做12-4 从Arduino发射红外线遥控电器

实验说明: IRremote扩展库也具备发射红外线遥控信号的功能,本单元将组装一个Arduino红外线遥控发射器,并从“串口监视器”指挥它来遥控家电
实验电路: 根据IRremote扩展库的设定,红外线发射LED必须接在第3端口,而且最好先串联一个330Ω电阻保护LED。
实验程序: 使用IRremote扩张库发射红外线信号之前,必须先声明一个“I”类型的对象IRsend irsend;,程序将通过此对象发射制定格式的信号,以发出NEC红外线为例,指令:irsend.sendNEC(红外线编码, 位数);
示例: 从串口获得任何字符时,Arduino发射红外线上面的信号;

#include <IRremote.h>
IRsend irsend;

void setup() {
  Serial.begin(9600);
}

void loop() {
  if (Serial.read() != -1) {
    irsend.sendNEC(0xC1C7C03F, 32);
    Serial.println("Action!");
  }
}

更多推荐