红外接收头介绍
1、什么是红外接收头?
红外遥控器发出的信号是一连串的二进制脉冲码。为了使其在无线传输过程中免受其他红外信号的干扰,通常都是先将其调制在特定的载波频率上, 然后再经红外发射二极管发射出去,而红外线接收装置则要滤除其他杂波,只接收该特定频率的信号并将其还原成二进制脉冲码,也就是解调.
2、工作原理
内置接收管将红外发射管发射出来的光信号转换为微弱的电信号,此信号经由IC内部放大器进行放大,然后通过自动增益控制、带通滤波、解调变、 波形整形后还原为遥控器发射出的原始编码,经由接收头的信号输出脚输入到电器上的编码识别电路。
3、红外接收头的引脚与连线
红外接收头有三个引脚如下图:
 
D为数据输出
GND为电源地
VCC为电源正
红外遥控实验
1、实验器件 红外遥控器 1个 IR Receiver Module 1个 数字传感器连接线 1根
2、实验原理 要想对某一遥控器进行解码必须要了解该遥控器的编码方式,这就叫知己知彼,百战不殆 。本产品使用的遥控器的编码方式为:NEC协议。下面就介绍一下NEC协议:
•NEC协议介绍:
特点: (1)8位地址位,8位命令位
(2)为了可靠性地址位和命令位被传输两次
(3)脉冲位置调制
(4)载波频率38khz
(5)每一位的时间为1.125ms或2.25ms
•逻辑0和1的定义如下图:
 
协议如下:
•按键按下立刻松开的发射脉冲:
 
上面的图片显示了NEC的协议典型的脉冲序列。注意:这是首先发送LSB(最低位)的协议。在上面的脉冲传输的地址为0x59命令为0x16。一个消息是由一个9ms的高电平开始,随后有一个4.5ms的低电平, (这两段电平组成引导码)然后由地址码和命令码。地址和命令传输两次。第二次所有位都取反,可用于对所收到的消息中的确认使用。总传输时间是恒定的,因为每一点与它取反长度重复。如果你不感兴趣, 你可以忽略这个可靠性取反,也可以扩大地址和命令,以每16位!
•按键按下一段时间才松开的发射脉冲:
 
一个命令发送一次,即使在遥控器上的按键仍然按下。当按键一直按下时,第一个110ms的脉冲与上图一样,之后每110ms重复代码传输一次。这个重复代码是由一个9ms的高电平脉冲和一个2.25ms低电平和560μs的高电平组成。
•重复脉冲
 
本介绍是参考 https://www.sbprojects.com/knowledge/ir/nec.htm
注意:脉冲波形进入一体化接收头以后,因为一体化接收头里要进行解码、信号放大和整形,故要注意在没有红外信号时,其输出端为高电平,有信号时为低电平,故其输出信号电平正好和发射端相反。接收端脉冲大家可以通过示波器看到,结合看到的波形理解程序。
•本实验编程思想
根据NEC编码的特点和接收端的波形,本实验将接收端的波形分成四部分:引导码(9ms和4.5ms的脉冲)、地址码16位(包括8位的地址位和8位的地址的取反)、命令码16位(包括8位命令位和8位命令位的取反)、重复码(9ms、2.25ms、560us脉冲组成)。 利用定时器对接收到的波形的高电平段和低电平段进行测量,根据测量到的时间来区分:逻辑“0”、逻辑“1”、引导脉冲、重复脉冲。引导码和地址码只要判断是正确的脉冲即可,不用存储,但是命令码必须存储,因为每个按键的命令码都不同, 根据命令码来执行相应的动作。设置遥控器上的几个按键VOL+:控制LED灯亮的;VOL-:作为控制蜂鸣器响;
实例代码
程序功能:对遥控器发射出来的编码脉冲进行解码,根据解码结果执行相应的动作。按下"VOL+"红灯亮,松开红灯灭;按下"VOL-"蜂鸣器响,松开蜂鸣器停止响;这样大家就可以用遥控器遥控你的器件了,让它听你的指挥。其它按键的译码方式与这几个键一样,只要大家用示波器测出它们各自的波形,了解各自的命令码,在执行译码结果的函数中写上对应的命令码和要执行的动作即可。
  #define BUZZER 10//蜂鸣器
  #define LED_RED 11//红灯
  #define IR_IN  2  //红外接收
  int Pulse_Width=0;//存储脉宽
  int  ir_code=0x00;//命令值
  void timer1_init(void)//定时器初始化函数
  {
    TCCR1A = 0X00;
    TCCR1B = 0X05;//给定时器时钟源
    TCCR1C = 0X00;
    TCNT1 = 0X00;
    TIMSK1 = 0X00;  //禁止定时器溢出中断
  }
  void remote_deal(void)//执行译码结果函数
  {
    switch(ir_code)
    {
      case 0xff00://停止
      digitalWrite(LED_RED,LOW);//红灯不亮
      digitalWrite(BUZZER,LOW);//蜂鸣器不响
      break;
      case 0xfe01://VOL+
      digitalWrite(LED_RED,HIGH);//红灯亮
      break;
      case 0xf609://VOL-
      digitalWrite(BUZZER,HIGH);//蜂鸣器响
      break;
   }
  }
  char logic_value()//判断逻辑值“0”和“1”子函数
  {
    while(!(digitalRead(IR_IN))); //低等待
    Pulse_Width=TCNT1;
    TCNT1=0;
    if(Pulse_Width>=7&&Pulse_Width<=10)//低电平560us
    {
      while(digitalRead(IR_IN));//是高就等待
      Pulse_Width=TCNT1;
      TCNT1=0;
      if(Pulse_Width>=7&&Pulse_Width<=10)//接着高电平560us
        return 0;
      else if(Pulse_Width>=25&&Pulse_Width<=27) //接着高电平1.7ms
        return 1;
    }
    return -1;
  }
  void pulse_deal()//接收地址码和命令码脉冲函数
  {
    int i;
    //执行8个0
    for(i=0; i<8; i++)
    {
      if(logic_value() != 0) //不是0
          return;
    }
    //执行6个1
    for(i=0; i<6; i++)
    {
      if(logic_value()!= 1) //不是1
          return;
    }
    //执行1个0
    if(logic_value()!= 0) //不是0
        return;
    //执行1个1
    if(logic_value()!= 1) //不是1
        return;
    //解析遥控器编码中的command指令
    ir_code=0x00;//清零
    for(i=0; i<16;i++ )
    {
      if(logic_value() == 1)
      {
        ir_code |=(1<<i);
      }
    }
  }
  void remote_decode(void)//译码函数
  {
    TCNT1=0X00;
    while(digitalRead(IR_IN))//是高就等待
    {
      if(TCNT1>=1563)  //当高电平持续时间超过100ms,表明此时没有按键按下
      {
        ir_code = 0xff00;
        return;
      }
    }
    //如果高电平持续时间不超过100ms
    TCNT1=0X00;
    while(!(digitalRead(IR_IN))); //低等待
    Pulse_Width=TCNT1;
    TCNT1=0;
    if(Pulse_Width>=140&&Pulse_Width<=143)//9ms
    {
      while(digitalRead(IR_IN));//是高就等待
      Pulse_Width=TCNT1;
      TCNT1=0;
      if(Pulse_Width>=68&&Pulse_Width<=72)//4.5ms
      {
        pulse_deal();
        return;
      }
      else if(Pulse_Width>=34&&Pulse_Width<=36)//2.25ms
      {
        while(!(digitalRead(IR_IN)));//低等待
        Pulse_Width=TCNT1;
        TCNT1=0;
        if(Pulse_Width>=7&&Pulse_Width<=10)//560us
        {
          return;
        }
      }
    }
  }
  void setup()
  {
    pinMode(LED_RED,OUTPUT);//设置与红灯连接的引脚为输出模式
    pinMode(BUZZER,OUTPUT);//设置与蜂鸣器连接的引脚为输出模式
    pinMode(IR_IN,INPUT);//设置红外接收引脚为输入
    }
  void loop()
  {
    timer1_init();//定时器初始化
    while(1)
    {
      remote_decode();  //译码
      remote_deal();   //执行译码结果
    }
  }
遥控器键值附表
| 遥控器字符 | 键值 | 
|---|---|
| 红色按钮 | 0xff00 | 
| VOL+ | 0xfe01 | 
| FUNC/STOP | 0xfd02 | 
| 左2个三角 | 0xfb04 | 
| 暂停键 | 0xfa05 | 
| 右2个三角 | 0xf906 | 
| 向下三角 | 0xf708 | 
| VOL- | 0xf609 | 
| 向上三角 | 0xf50a | 
| 0 | 0xf30c | 
| EQ | 0xf20d | 
| ST/REPT | 0xf10e | 
| 1 | 0xef10 | 
| 2 | 0xee11 | 
| 3 | 0xed12 | 
| 4 | 0xeb14 | 
| 5 | 0xea15 | 
| 6 | 0xe916 | 
| 7 | 0xe718 | 
| 8 | 0xe619 | 
| 9 | 0xe51a | 
Arduino库文件
Mind+ 上传模式编程
1、下载及安装软件。下载地址:https://www.mindplus.cc 详细教程:Mind+基础wiki教程-软件下载安装
2、切换到“上传模式”。 详细教程:Mind+基础wiki教程-上传模式编程流程
3、“扩展”中选择“主控板”中的“Arduino Uno”,然后选择“通讯模块”中的“红外接收模块”, 详细教程:Mind+基础wiki教程-加载扩展库流程
4、进行编程,程序如下图:(注意新建字符串变量,名称为“红外编码”)
5、菜单“连接设备”,“上传到设备”

实现效果
红外接收模块插板子D2口,按下遥控器按钮1打开板载LED灯,按下遥控器按钮0关闭板载LED灯。
遥控器键值附表(上传模式)
| 遥控器字符 | 键值 | 
|---|---|
| 红色按钮 | FD00FF | 
| VOL+ | FD807F | 
| FUNC/STOP | FD40BF | 
| 左2个三角 | FD20DF | 
| 暂停键 | FDA05F | 
| 右2个三角 | FD609F | 
| 向下三角 | FD10EF | 
| VOL- | FD906F | 
| 向上三角 | FD50AF | 
| 0 | FD30CF | 
| EQ | FDB04F | 
| ST/REPT | FD708F | 
| 1 | FD08F7 | 
| 2 | FD8877 | 
| 3 | FD48B7 | 
| 4 | FD28D7 | 
| 5 | FDA857 | 
| 6 | FD6897 | 
| 7 | FD18E7 | 
| 8 | FD9867 | 
| 9 | FD58A7 | 
Mind+ Python模式编程(行空板)
Mind+Python模式为完整Python编程,因此需要能运行完整Python的主控板,此处以行空板为例说明
连接图
 
操作步骤
1、下载及安装官网最新软件。下载地址:https://www.mindplus.cc 详细教程:Mind+基础wiki教程-软件下载安装
2、切换到“Python模式”。“扩展”中选择“官方库”中的“行空板”和“pinpong库”中的”pinpong初始化“和“红外接收模块”。切换模式和加载库的详细操作链接
3、进行编程
4、连接行空板,程序点击运行后,可在终端查看数据。行空板官方文档-行空板快速上手教程 (unihiker.com)

代码编程
以pinpong库为例,行空板官方文档-行空板快速上手教程 (unihiker.com)
#  -*- coding: UTF-8 -*-
# MindPlus
# Python
from pinpong.extension.unihiker import *
from pinpong.board import Board,Pin
from pinpong.board import IRRecv
from pinpong.board import Board
# 事件回调函数
def event(data):
    if (data == 16580863):
        print(data)
        p_p25_out=Pin(Pin.P25, Pin.OUT)
        p_p25_out.write_digital(1)
    if (data == 16613503):
        print(data)
        p_p25_out=Pin(Pin.P25, Pin.OUT)
        p_p25_out.write_digital(0)
Board().begin()
ir1 = IRRecv(Pin((Pin.P21)),event)
while True:
    pass
遥控器键值附表(python模式)
| 遥控器字符 | 键值 | 
|---|---|
| 红色按钮 | 16580863 | 
| VOL+ | 16613503 | 
| FUNC/STOP | 16597183 | 
| 左2个三角 | 16589023 | 
| 暂停键 | 16621663 | 
| 右2个三角 | 16605343 | 
| 向下三角 | 16584943 | 
| VOL- | 16617583 | 
| 向上三角 | 16601263 | 
| 0 | 16593103 | 
| EQ | 16625743 | 
| ST/REPT | 16609423 | 
| 1 | 16582903 | 
| 2 | 16615543 | 
| 3 | 16599223 | 
| 4 | 16591063 | 
| 5 | 16623703 | 
| 6 | 16607383 | 
| 7 | 16586983 | 
| 8 | 16619623 | 
| 9 | 16603303 | 

 购买
购买