對於 紅外遙控的訊號處理 每一個按鍵都會有單獨的操作【Arduino】
阿新 • • 發佈:2019-02-05
長話短說,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(); //執行譯碼結果 } }