长话短说,Arduino下的红外遥控器实验。需要一跟10欧电阻。面包线 子对子 *3.遥控一个。红外接收头一个。
已经做好按下每一个键的处理,屏幕上会输出你按下的那个键。
红外遥控器长这样子
线这样子接: 看好线的颜色
最后是代码部分,已经设置好按下指定键进行指定操作
#define IR_IN 8 //红外接收
int Pulse_Width = 0;//存储脉宽
int ir_code = 0x00;// 用户编码值
char adrL_code = 0x00;//命令码
char adrH_code = 0x00;//命令码反码
void timer1_init(void)//定时器初始化函数
{
TCCR1A = 0X00;
TCCR1B = 0X05;//给定时器时钟源
TCCR1C = 0X00;
TCNT1 = 0X00;
TIMSK1 = 0X00; //禁止定时器溢出中断
}
void remote_deal(void)//执行译码结果函数
{
if(adrL_code != 0x00) //如果没有检测到信号则不输出
{
switch(adrL_code){
case 0x45:
Serial.println("CH-");
break;
case 0x46:
Serial.println("CH");
break;
case 0x47 :
Serial.println("CH+");
break;
case 0x44 :
Serial.println("|<<");
break ;
case 0x40 :
Serial.println(">>|");
break;
case 0x43 :
Serial.println(">||");
break;
case 0x07 :
Serial.println("-");
break;
case 0x15 :
Serial.println("+");
break;
case 0x09:
Serial.println("EQ");
break;
case 0x16:
Serial.println("0");
break;
case 0x19:
Serial.println("100+");
break;
case 0x0d:
Serial.println("200+");
break;
case 0x0c:
Serial.println("1");
break;
case 0x18:
Serial.println("2");
break;
case 0x5e:
Serial.println("3");
break;
case 0x08:
Serial.println("4");
break;
case 0x1c:
Serial.println("5");
break;
case 0x5a:
Serial.println("6");
break;
case 0x42:
Serial.println("7");
break;
case 0x52:
Serial.println("8");
break;
case 0x4a:
Serial.println("9");
break;
}
}
}
char logic_value()//判断逻辑值“0”和“1”子函数
{
TCNT1 = 0X00;
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;
int j;
ir_code=0x00;// 清零
adrL_code=0x00;// 清零
adrH_code=0x00;// 清零
//解析遥控器编码中的用户编码值
for(i = 0 ; i < 16; i++)
{
if(logic_value() == 1) //是1
ir_code |= (1<<i);//保存键值
}
//解析遥控器编码中的命令码
for(i = 0 ; i < 8; i++)
{
if(logic_value() == 1) //是1
adrL_code |= (1<<i);//保存键值
}
//解析遥控器编码中的命令码反码
for(j = 0 ; j < 8; j++)
{
if(logic_value() == 1) //是1
adrH_code |= (1<<j);//保存键值
}
}
void remote_decode(void)//译码函数
{
TCNT1=0X00;
while(digitalRead(IR_IN))//是高就等待
{
if(TCNT1>=1563) //当高电平持续时间超过100ms,表明此时没有按键按下
{
ir_code=0x00ff;// 用户编码值
adrL_code=0x00;//键码前一个字节值
adrH_code=0x00;//键码后一个字节值
return;
}
}
//如果高电平持续时间不超过100ms
TCNT1=0X00;
while(!(digitalRead(IR_IN))); //低等待
Pulse_Width=TCNT1;
TCNT1=0;
if(Pulse_Width>=140&&Pulse_Width<=141)//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()
{
Serial.begin(9600);
pinMode(IR_IN,INPUT);//设置红外接收引脚为输入
Serial.flush();
}
void loop()
{
timer1_init();//定时器初始化
while(1)
{
remote_decode(); //译码
remote_deal(); //执行译码结果
}
}
最后是运行结果: