红外遥控器发出的信号是一连串的二进制脉冲码。为了使其在无线传输过程当中免受其余红外信号的干扰,一般都是先将其调制在特定的载波频率上,而后再经红外发射二极管发射出去,而红外线接收装置则要滤除其余杂波,只接收该特定频率的信号并将其还原成二进制脉冲码,也就是解调.
红外接收头如附件中所示:
这里举一个Arduino接受遥控器信号的例子。红外接受头占用Arduino的数8。
(也能够选择nine_09y的帖子Arduino电子积木之红外发射接收编解码中的模块)
先来看看遥控器的编码方式,
遥控器发出的二进制脉冲码载波频率是38kHz,采用脉冲宽度调制,每一位的时间为1.125ms或2.25ms ,逻辑0和逻辑1的定义如附件中图2所示
而一个消息是由一个9ms的高电平开始,随后有一个4.5ms的低电平,以后就是信息码了.
例子接收图中遥控器的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 编辑 ] php
2011-7-16 00:15 git
luoji.JPG (19.84 KB)2011-7-16 00:15 函数