紅外遙控器發出的信號是一連串的二進制脈衝碼。爲了使其在無線傳輸過程當中免受其餘紅外信號的干擾,一般都是先將其調製在特定的載波頻率上,而後再經紅外發射二極管發射出去,而紅外線接收裝置則要濾除其餘雜波,只接收該特定頻率的信號並將其還原成二進制脈衝碼,也就是解調.
紅外接收頭如附件中所示:
這裏舉一個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 函數