1. 程式人生 > >對於 紅外遙控的訊號處理 每一個按鍵都會有單獨的操作【Arduino】

對於 紅外遙控的訊號處理 每一個按鍵都會有單獨的操作【Arduino】

長話短說,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();   //執行譯碼結果
  }  
}

最後是執行結果: