Arduino初初教程9——红外遥控

红外遥控器发出的信号是一连串的二进制脉冲码。为了使其在无线传输过程中免受其他红外信号的干扰,通常都是先将其调制在特定的载波频率上,然后再经红外发射二极管发射出去,而红外线接收装置则要滤除其他杂波,只接收该特定频率的信号并将其还原成二进制脉冲码,也就是解调.
红外接收头如附件中所示:


这里举一个Arduino接受遥控器信号的例子。红外接受头占用Arduino的数8。
(也可以选择nine_09y的帖子Arduino电子积木之红外发射接收编解码中的模块)
先来看看遥控器的编码方式,
遥控器发出的二进制脉冲码载波频率是38kHz,采用脉冲宽度调制,每一位的时间为1.125ms或2.25ms ,逻辑0和逻辑1的定义如附件中图2所示
20110716_e8c79a7acd52c6833b7fnGahEvlOo6eh 
而一个消息是由一个9ms的高电平开始,随后有一个4.5ms的低电平,之后就是信息码了.
1309252422_2 
例子接收图中遥控器的VOL+按钮的信号(信息码0xfe01),然后让引脚13上的LED闪烁一下.
程序如下(直接粘贴到Arduino开发环境下就可直接应用):
#define LED_RED 13//红灯
#define IR_IN  8  //红外接收
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 0xfe01://VOL+
    digitalWrite(LED_RED,HIGH);//灯亮
    delay(500);
    digitalWrite(LED_RED,LOW);//灯不亮
    break;
  }
}
//判断逻辑值“0”和“1”子函数
char logic_value()
{
  while(!(digitalRead(8))); //低等待
  Pulse_Width=TCNT1;
  TCNT1=0;
  if(Pulse_Width>=7&&Pulse_Width<=10)//低电平560us
  {
    while(digitalRead(8));//是高就等待
    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;
  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(8))//是高就等待
  {
    if(TCNT1>=1563)  //当高电平持续时间超过100ms,表明此时没有按键按下
    {
      ir_code = 0xff00;
      return;
    }  
  }
  //如果高电平持续时间不超过100ms
  TCNT1=0X00;
  while(!(digitalRead(8))); //低等待
  Pulse_Width=TCNT1;
  TCNT1=0;
  if(Pulse_Width>=140&&Pulse_Width<=141)//9ms
  {
    while(digitalRead(8));//是高就等待
    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(8)));//低等待
      Pulse_Width=TCNT1;
      TCNT1=0;
      if(Pulse_Width>=7&&Pulse_Width<=10)//560us
      {
        return;
      }
    }
  }
}
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
void setup()
{
  unsigned char i;
  pinMode(LED_RED,OUTPUT);//设置与红灯连接的引脚为输出模式
  pinMode(IR_IN,INPUT);//设置红外接收引脚为输入
}
void loop()
{  
  timer1_init();//定时器初始化
  while(1)
  {
    remote_decode();  //译码
    remote_deal();   //执行译码结果
  }  
}
/////////////////////////////////////////////////////////////////
关于红外遥控的学习,个人建议先用示波器捕捉遥控器发出的二进制编码,通过捕捉到的内容能够解读出按键的信息码,然后再认真看一下程序中的译码子函数
红外遥控的程序调起来可能会比较麻烦,可能需要反复的调试几次
需要多些耐心
[ 本帖最后由 晨光熹微 于 2011-7-16 00:17 编辑 ]

附件   untitled.JPG  (20.83 KB)

2011-7-16 00:15

20110716_41558630e29cf4713e50W86JshXPGQNL

  luoji.JPG  (19.84 KB)

2011-7-16 00:15

20110716_e8c79a7acd52c6833b7fnGahEvlOo6eh

你可能感兴趣的:(教程,arduino)