Arduino 紅外線接收實習

學習如何學習!

設備與材料

個人電腦 × 1
arduino Uno × 1
麵包板 × 1
紅外線接收器 模組 × 1
冷氣遙控器 × 1
連接線 若干

實體接線圖

NEC紅外線編碼

資料透過紅外線傳送時,會將資料轉成串列傳輸,低位元先傳送,高位元後送,除了資料位元外,還會加上啟始位元與結束位元,每個位元由高電位與低電位組成,藉由高低電位的持續時間來判斷是啟始位元、資料位元或停止位元。
下圖是4位元的紅外線編碼B0001(資料會反過來變1000),除了4位元資料碼之外,前面會加上1個啟始位元,後面會加上1個結束位元。
啟始位元(Leader):
啟始位元的高電位與低電位持續時間會比較長,以NEC紅外線傳輸協定說明,高電位持續時間9000μs,低電位持續時間4500μs(不同的廠商有不同的格式)。
資料位元(data):
1的資料位元由短時間(562.5μs)的高電位與長時間(1687.5μs)的低電位組成。
0的資料位元由短時間(562.5μs)的高電位與短時間(562.5μs)的低電位組成。
因此只要判斷低電位的持續時間就能判斷傳送的資料是1或0。
結束位元(stop):
結束位元由短時間(562.5μs)的高電位與超長時間的(30000μs~48000μs)低電位組成。超長時間會依不同的廠牌而有不同,範例程式是用25000μs來判斷。

高電位表示發射紅外線,低電位表示不發射紅外線,因為自然界有很多東西會產生紅外線,會對紅外線接收造成干擾。所以發射紅外線時,並不是一直發射紅外線,而是以一定頻率一定工作週期來發射紅外線(如下圖)。發射紅外線時稱為 mark,沒發射紅外線時稱為 space。

參考程式

/* 
 * 紅外線接收解碼程式
 * 目前支援 NEC HERAN HITACHI DAIKIN 格式
 */
//#define   NEC 
//#define   HERAN 
//#define   HITACHI 
#define   DAIKIN


#define   CODE_NUMBER  50     //50*4=200 最多可以接收 200位元

#if defined (NEC )
  #define   D_START     4000   // 判斷為啟始位元最小持續時間,單位 us
  #define   D_IDLE       25000  // 一段時間沒變化就進入 Idle,單位 us
  #define   D_MAX       2000    // 電壓狀態不變的最大持續時間,單位 us
  #define   D_MIN       300    // 電壓狀態不變的最小持續時間,單位 us
  #define   D_HI        1000   // 判斷為高電位最小持續時間,單位 us
#endif

#if defined (HERAN )
  #define   D_START     4000   // 判斷為啟始位元最小持續時間,單位 us
  #define   D_IDLE      25000  // 一段時間沒變化就進入 Idle,單位 us
  #define   D_MAX       25000    // 電壓狀態不變的最大持續時間,單位 us
  #define   D_MIN       300    // 電壓狀態不變的最小持續時間,單位 us
  #define   D_HI        1000   // 判斷為高電位最小持續時間,單位 us
#endif

#if defined (HITACHI )
  #define   D_START     1500   // 判斷為啟始位元最小持續時間,單位 us
  #define   D_IDLE       25000  // 一段時間沒變化就進入 Idle,單位 us
  #define   D_MAX       2000    // 電壓狀態不變的最大持續時間,單位 us
  #define   D_MIN       300    // 電壓狀態不變的最小持續時間,單位 us
  #define   D_HI        1000   // 判斷為高電位最小持續時間,單位 us
#endif

#if defined (DAIKIN )
  #define   D_START     1500   // 判斷為啟始位元最小持續時間,單位 us
  #define   D_IDLE      20000  // 一段時間沒變化就進入 Idle,單位 us
  #define   D_MAX       2000    // 電壓狀態不變的最大持續時間,單位 us
  #define   D_MIN       300    // 電壓狀態不變的最小持續時間,單位 us
  #define   D_HI        1000   // 判斷為高電位最小持續時間,單位 us
#endif

  
byte              startBit      = 0;      // 是否出現啟始位元
const int         IR_rec_pin    = 2;      // IR 接收器輸出腳位
boolean           IRstate       = LOW;    // IR 接收器輸出腳位狀態
boolean           IRstate_last  = LOW;    // IR 接收器輸出腳位狀態(上一次)
unsigned long int time_last     = 0;      // 上一次 IRstate 變化的時間
unsigned long int hTime         = 0;      // 高電位時間
unsigned long int lTime         = 0;      // 低電位時間
boolean           isIdle        = true;   // 是否在等待 IR 訊號模式Idle)
int               number        = 0;      // 接收多少位元
unsigned long int factor        = 1;      // 2進位加權
byte              code[CODE_NUMBER]      ;         // 紅外線傳送碼
byte              index         =0;       // code陣列索引


void setup( ) {
  Serial.begin( 115200 );
  pinMode( IR_rec_pin, INPUT );        // 設定針腳 I/O 模式
  IRstate = digitalRead( IR_rec_pin ); // 取得腳位元狀態初始值
  IRstate_last = IRstate;
  Serial.println( "紅外線接收解碼程式" );
}
void loop( ) {
  IRRecCode();  
  delayMicroseconds( 5 );
}

void IRRecCode() {
  IRstate = digitalRead( IR_rec_pin );// 讀取腳位狀態
 
  if ( (micros( ) - time_last >= D_IDLE) && !isIdle && number>0 ) { // 時間間隔大於設定的時間,且原本的狀態為接收中狀態
      if(number>0){
        Serial.print(hTime);
        Serial.print(" ");
        Serial.print(micros( ) - time_last);
        Serial.println("");
        Serial.print("紅外線16進制碼:0x");
        for(int i=index-1;i>=0;i--){
          Serial.print(code[i], HEX);
        }  
      
        Serial.print("(");
        Serial.print(number);
        Serial.println( "位元)" );     
      }  
      isIdle = true; //進入等待狀態
      startBit=0;
      number=0;      
      index=0;
  }
  
  //狀態改變
  if ( IRstate != IRstate_last ) {    

      long int timeNow = micros( );      // 記錄目前時間
      long int dTime = timeNow - time_last; // 與上一次腳位變化的時間差    

      if ( (dTime < D_MAX) && (dTime > D_MIN) && !isIdle) {         
          //判斷低電位的時間間隔
          if (IRstate == LOW) {  
              Serial.print(hTime);   
              Serial.print(" ");
              Serial.print(0-dTime);            
              Serial.print(" ");
              
              //如果是1,加上其位元的權數,不是1就不用加了
              if (dTime > D_HI) {              
                    code[index] += factor;
              }           
              factor = factor * 2;
              number++;        
              if(number%4==0){
                factor=1;
                index++;
              }
          }else{
              //HIGH
              hTime=dTime;
              //Serial.print("h");
          }
      }   
      
      // 記錄此次時間
      time_last = timeNow;
            //判斷啟始位元訊號
      if(isIdle && dTime > D_START && startBit==0 && IRstate == HIGH){
        //高電位一段時間
        startBit=1;
        hTime=dTime;        
      }else if(isIdle && dTime > D_START && startBit==1 && IRstate == LOW){
        //低電位一段時間 
        isIdle = false; //進入接收中狀態        
        lTime=dTime;
        startBit=0;        
        //啟始位元
        for(int i=0;i<CODE_NUMBER;i++){
          code[i] = 0;
        }  
        number = 0;
        factor = 1;
        index = 0;
        Serial.print(hTime);
        Serial.print(" -");
        Serial.print(lTime);        
        Serial.print(" ");
      }

  }
  // 記錄此次狀態
  IRstate_last = IRstate;
}//end IRRecCode

功能

參考程式的功能是能將紅外線遙控器發射的紅外線解碼,並傳回電腦。傳回電腦的第1筆資料為高低電位持續時間,前面有 號表示低電位的持續時間,第2筆資料是將第1筆資料為轉成16進制碼。此實習是為下一個實習做準備,將紅外線解碼後,即將進入 arduino 紅外線發射實習,用 arduino 來控制電器用品。

序列埠監控視窗

開啟 Arduino IDE 序列埠監控視窗,選擇115200baud,按遙控器可以從監控視窗看到接收情形,下圖是按一次NEC紅外線傳輸協定遙控器“數字 1” 按鈕,會傳送1筆32位元的資料分別是0xE916FF00,第2行資料為高低電位持續的時間,第2行第1組資料 8956 -4504,代表高電位持續了8956μs,低電位持續了4504μs(-代表低電位的時間)。
傳送的資料雖然有32位元但實際有效只有16位元,第1組8位元(最右邊) 0x00 在 NEC 紅外線傳輸協定中代表位址,第2組8位元 0xFF 是 0x00的補數,所以傳送了位址:0x00,第3組8位元 0x16是命令碼,同理可証,0xE9 是0x16的補數。

下圖是按一次EPSON 投影機遙控器電源按鈕,會傳送1筆32位元的資料分別是0x6F905583,其中0x5583是位址,這支遙控器位置並沒有傳送補數,第3組8位元 0x90是命令碼,第4組0x6F,是命令碼的補數,所以傳送了位址0x5583,命令碼:0x90。


HERAN 冷氣遙控器解碼

下圖是按HERAN冷氣遙控器溫度調整按鈕,會傳送2筆68位元的資料,第1筆是控制碼、第2筆是結束碼,68位元的資料包含32位元資料+4位元0xA 分隔碼+32位元資料共68位元,分隔碼最高位元低電位持續時間約20000μs。

實驗數據

0x0000C111 0x50600049 ON 冷氣 16℃ 風速自動 左右風擺 上下風擺 清淨
0x8000C111 0x50200041 OFF 冷氣 16℃
0x1000C111 0x50600149 ON 冷氣 17℃ 風速自動 左右風擺 上下風擺 清淨
0x9000C111 0x50200141 OFF 冷氣 17℃
0x2000C111 0x50600249 ON 冷氣 18℃ 風速自動 左右風擺 上下風擺 清淨
0xA000C111 0x50200241 OFF 冷氣 18℃
0x3000C111 0x50600349 ON 冷氣 19℃ 風速自動 左右風擺 上下風擺 清淨
0xB000C111 0x50200341 OFF 冷氣 19℃
0x4000C111 0x50600449 ON 冷氣 20℃ 風速自動 左右風擺 上下風擺 清淨
0xC000C111 0x50200441 OFF 冷氣 20℃
0x5000C111 0x50600549 ON 冷氣 21℃ 風速自動 左右風擺 上下風擺 清淨
0xE000C111 0x50600E49 ON 冷氣 30℃ 風速自動 左右風擺 上下風擺 清淨
0xE000C111 0x50600E59 ON 冷氣 30℃ 風速1 左右風擺 上下風擺 清淨
0xE000C111 0x50600E69 ON 冷氣 30℃ 風速2 左右風擺 上下風擺 清淨
0xE000C111 0x50600E79 ON 冷氣 30℃ 風速3 左右風擺 上下風擺 清淨
0xE000C110 0x50600E09 ON 冷氣 30℃ 風速自動 左右風擺 清淨
0xD000C101 0x50600E49 ON 冷氣 30℃ 風速自動 上下風擺 清淨
0xD000C100 0x50600E09 ON 冷氣 30℃ 風速自動 清淨
0xE000C100 0x51200E09 ON 冷氣 30℃ 風速自動 屋內換氣
0xE000C100 0x51600E09 ON 冷氣 30℃ 風速自動 屋內換氣 清淨
0xD000C100 0x50200E09 ON 冷氣 30℃ 風速自動
0xE000C100 0x50200E1A ON 除濕 30℃ 風速1(只能風速1)
0xF000C110 0x50200E5A ON 除濕 30℃ 風速1(只能風速1) 左右風擺
0xF000C111 0x50200E5A ON 除濕 30℃ 風速1(只能風速1) 左右風擺 上下風擺
0xF000C111 0x50600E5A ON 除濕 30℃ 風速1(只能風速1) 左右風擺 上下風擺 清淨
0x7000C111 0x50200E52 OFF 除濕
0x0000C111 0x50600E4B ON 送風 30℃ 風速自動 左右風擺 上下風擺 清淨
0x8000C111 0x50200E43 OFF 送風 30℃
0x1000C111 0x50600E4C ON 暖氣 30℃ 風速自動 左右風擺 上下風擺 清淨
0x9000C111 0x50200E44 OFF 暖氣 30℃
0x8000C111 0x50600948 ON 自動(無法設定溫度) 風速自動 左右風擺 上下風擺 清淨
0x0000C111 0x50200940 OFF 自動 風速自動
0x8000C111 0x50600958 ON 自動(無法設定溫度) 風速1 左右風擺 上下風擺 清淨
0x0000C111 0x50200950 OFF 自動 風速1
0x8000C111 0x50600968 ON 自動(無法設定溫度) 風速2 左右風擺 上下風擺 清淨
0x0000C111 0x50200960 OFF 自動 風速2
0x8000C111 0x50600978 ON 自動(無法設定溫度) 風速3 左右風擺 上下風擺 清淨
0x0000C111 0x50200970 OFF 自動 風速3
0x8000C110 0x50600928 ON 自動(無法設定溫度) 風速2 左右風擺 清淨
0x7000C100 0x50600928 ON 自動(無法設定溫度) 風速2 清淨
0x4000C010 0x50600409 冷氣 20℃ 風速自動 左右風擺 清淨
0x3000C000 0x50600409 冷氣 20℃ 風速自動 清淨
0x2000C000 0x50600309 冷氣 19℃ 風速自動 清淨
0x1000C000 0x50600209 冷氣 18℃ 風速自動 清淨
0x1000C000 0x50600219 冷氣 18℃ 風速1 清淨
0x1000C000 0x50600229 冷氣 18℃ 風速2 清淨
0x1000C000 0x50600239 冷氣 18℃ 風速3 清淨
0x1000C100 0x50200239 冷氣 18℃ 風速3
0x2000C100 0x51200239 冷氣 18℃ 風速3 房間
0x3000C100 0x5060023B 送風 18℃ 風速3 清淨


新款大金冷氣遙控器解碼

實驗數據

//OFF 32℃ 冷氣 風2 上下
0x02000000F027DA11
0x910000C00000000000004F004030000027DA11

//ON 32℃ 冷氣 風2 上下
0x920000C00000000000004F004031000027DA11
//ON 31℃ 冷氣 風2 上下
0x900000C00000000000004F003E31000027DA11
//ON 30℃ 冷氣 風2 上下
0x8E0000C00000000000004F003C31000027DA11
//ON 29℃ 冷氣 風2 上下
0x8C0000C00000000000004F003A31000027DA11
//ON 28℃ 冷氣 風2 上下
0x8A0000C00000000000004F003831000027DA11
//ON 18℃ 冷氣 風2 上下
0x760000C00000000000004F002431000027DA11
//ON 18℃ 冷氣 風3 上下
0x860000C00000000000005F002431000027DA11
//ON 18℃ 冷氣 風4 上下
0x960000C00000000000006F002431000027DA11
//ON 18℃ 冷氣 風5 上下
0xA60000C00000000000007F002431000027DA11
//ON 18℃ 冷氣 風自動 上下
0xD60000C0000000000000AF002431000027DA11
//ON 18℃ 冷氣 風眠 上下
0xE60000C0000000000000BF002431000027DA11
//ON 18℃ 冷氣 風1 上下
0x660000C00000000000003F002431000027DA11
//ON 18℃ 冷氣 風1
0x570000C000000000000030002431000027DA11
//ON 18℃ 冷氣 風1 左右
0x660000C000000000000F30002431000027DA11
//ON 18℃ 冷氣 風1 上下 左右
0x750000C000000000000F3F002431000027DA11
//ON 送風 風1 上下 左右
0xB30000C000000000000F3F003261000027DA11
//OFF 送風 風1 上下 左右
0xB20000C000000000000F3F003260000027DA11
//OFF 除濕 風自動 上下 左右
0x700000C000000000000FAF00C020000027DA11
//ON 除濕 風自動 上下 左右
0x710000C000000000000FAF00C021000027DA11

新款大金 開頭8位元 控制 19位元 共 27位元

開頭
code[0]=0x11,code[1]= 0xDA,code[2]=0x27,code[3]=0xF0,code[4]=0x00,code[5]=0x00,code[6]=0x00,code[7]= 0x02
控制
code[0]=0x11,code[1]=0xDA,code[2]=0x27,code[3]=0x00,code[4]=0x00,
code[5] 功能 送風關(0x60) 送風開(0x61) 冷氣開(0x31) 冷氣關(0x30) 除濕開(0x21) 除濕關(0x20)
code[6]溫度 32℃(0x40) 31℃(0x3E) 30℃(0x3C) 29℃(0x3A) 28℃(0x38) 27℃(0x36) 19℃(0x26) 18℃(0x24)
[公式 (溫度)*2 ]
code[7]=0x00
code[8] 高4位元 風1(0x3?) 風2(0x4?) 風3(0x5?) 風4(0x6?) 風5(0x7?) 風自動(0xA?) 風睡眠(0xB?)
code[8] 低4位元 風擺上下(0x?F)
code[9] 低4位元 風擺左右(0xF?) 高4位元 0
code[10] =0x00,code[11] =0x00,code[12] =0x00,code[13] =0x00,code[14] =0x00
code[15] =0xC0
code[16] =0x00
code[17] =0x00
code[18] 檢查碼=code[0]+…+code[17]


舊款大金冷氣遙控器解碼

實驗數據

5108 -2116 476 -1688 416 -672 408 -668 420 -664 412 -1756 404 -672 420 -668 408 -664 424 -664 408 -1756 412 -668 412 -1752 424 -1732 424 -664 420 -1744 416 -1752 416 -1740 416 -1756 404 -1752 424 -664 416 -660 416 -1748 424 -668 416 -656 416 -680 408 -664 408 -680 408 -664 420 -1748 416 -1740 428 -1740 416 -1752 412 -1748 420 -668 416 -1748 412 -1740 568 -524 408 -676 408 -668 420 -664 412 -664 420 -668 420 -664 408 -668 420 -664 408 -680 408 -664 416 -672 412 -1752 412 -1744 424 -1740 416 -1752 420 -660 408 -680 408 -664 420 -668 444 20164
紅外線16進制碼:0x0F000DF027DA11(56位元)
5096 -2128 476 -1680 420 -668 404 -672 412 -660 416 -1744 416 -676 408 -664 420 -680 408 -668 420 -1732 428 -660 408 -1756 420 -1764 408 -656 416 -1736 412 -1760 408 -1764 416 -1740 432 -1752 416 -648 420 -656 408 -1768 416 -664 408 -676 416 -660 424 -660 416 -660 412 -660 416 -672 416 -688 408 -668 408 -652 444 -1736 416 -1752 428 -648 408 -680 408 -1744 428 -664 412 -1752 408 -1748 424 -656 424 -672 416 -664 408 -656 420 -680 408 -1756 404 -1764 416 -648 420 -668 420 -652 408 -680 408 -664 416 -684 416 -660 412 -660 416 -672 412 -660 416 -672 440 -652 420 -656 420 -664 420 -668 420 -664 408 -668 420 -680 408 -652 420 -652 420 -668 408 -680 420 -664 416 -660 412 -660 440 -660 412 -672 416 -1752 408 -664 420 -652 408 -1760 416 -660 420 -680 408 -1756 416 -664 408 -1744 420 -668 416 -672 412 -660 428 -660 412 -660 440 -648 416 -676 408 -668 408 -1768 416 -648 420 -656 408 -664 420 -668 420 -668 420 -1756 416 -1740 424 -656 412 -1752 424 -1744 424 -1740 416 -664 444 20164
紅外線16進制碼:0x7608052400000060D30027DA11(104位元)
開頭先 0x0F000DF027DA11

0x4908052600000031D30027DA11 //ON 29℃冷氣 風3
0x4A08062600000031D30027DA11 //ON 29℃冷氣 風4
0x4B08072600000031D30027DA11// ON 29℃冷氣 風5
0x3C0807260000F131D30027DA11// ON 29℃冷氣 風5 風上下
0x4E080A2600000031D30027DA11// ON 29℃冷氣 風自動
0x4C080A2400000031D30027DA11// ON 28℃冷氣 風自動
0x4A080A2200000031D30027DA11// ON 27℃冷氣 風自動
0x48080A2000000031D30027DA11// ON 26℃冷氣 風自動
0x47080A2000000030D30027DA11// OFF 26℃冷氣 風自動
0x260807100000F131D30027DA11// ON 18℃冷氣 風5 風上下
0x2E0807180000F131D30027DA11// ON 22℃冷氣 風5 風上下
0x78080A2000000061D30027DA11 // ON 送風 風自動
0x7108032000000061D30027DA11 // ON 送風 風1
0x7208042000000061D30027DA11 // ON 送風 風2
0x7308052000000061D30027DA11 // ON 送風 風3
0x7408062000000061D30027DA11 // ON 送風 風4
0x7508072000000061D30027DA11 // ON 送風 風5
0x7408072000000060D30027DA11 // OFF 送風 風5

舊大金 開頭7位元 控制 13位元 共 20位元

開頭
code[0]=0x11,code[1]= 0xDA,code[2]=0x27,code[3]=0xF0,code[4]=0x0D,code[5]=0x00,code[6]=0x0F
控制
code[0]=0x11,code[1]=0xDA,code[2]=0x27,code[3]=0x00,code[4]=0xD3
code[5] 功能 送風關(0x60) 送風開(0x61) 冷氣開(0x31) 冷氣關(0x30) 除濕開(0x21) 除濕關(0x20)
code[6] 風上下擺(0xF1) 無(0x00)
code[7] 0x00
code[8] 0x00
code[9]溫度 32℃(0x32) 31℃(0x30) 30℃(0x28) 29℃(0x26) 28℃(0x24) 27℃(0x22) 20℃(0x18) 16℃(0x10) [公式 (溫度-18)*2+16 ]
code[10]風量 風5(07) 風4(06) 風3(05) 風2(04) 風1(03) 風自動(0A)
code[11]0x08
code[12]檢查碼=code[0]+…+code[12]


課程學習成果

課程學習成果,請用專題報告的方式呈現,以下所附的 專題報告檔案 僅授權給學生用在學習歷程,不可移作它用,所附的專題報告檔並不完整,你必需親自完成它,本網站的資料、圖片授權您在學習歷程上使用。

入門
知識
語法
流程
函式
實習

發佈留言