Arduinoで赤外線リモコンの受信データをハック

Amazonで購入したサインスマート Arduino(Uno) をはじめよう互換キットについていた赤外線リモコンを使ってみた。

大変参考になったサイト
ArduinoとRubyで赤外線リモコン作ってWebから操作できるようにした
赤外線リモコンの通信フォーマット

材料

・Arduino pro mini 328 5V
・赤外線リモコン
・赤外線リモコン受信モジュール
・タクトスイッチ
rimocon

回路

まずはリモコンの受信データを解析する為の回路をつくってみた。スイッチを押すと受信モードになり、受信モード中にリモコンからデータを受信するとその結果をシリアル通信で出力できるような回路をつくってみた。
回路
IMG_201501091616

ソースコード

//IRリモコン解析用
 
#define BUTTON 9
#define IR_IN 10
#define IR_DATA_SIZE 100

byte ir_data[IR_DATA_SIZE];
byte ir_code[32];
 
void setup() {
  Serial.begin(9600);
  pinMode(IR_IN, INPUT_PULLUP);     
  pinMode(BUTTON, INPUT_PULLUP);
}

void loop() {
  if(digitalRead(BUTTON) == 0){
    digitalWrite(13,HIGH);
    ir_read(IR_IN);
    ir_print_1();
    ir_print_2();
    digitalWrite(13,LOW);
  }else{
    digitalWrite(13,LOW);
  }
}

//データ受信
void ir_read(byte ir_pin){
  for(int i = 0; i < IR_DATA_SIZE; i++){
    ir_data[i] = 0;
  }
  unsigned long now, last, start_at;
  boolean stat;
  start_at = micros();
  
  //2.5秒以上入力がなかったら終了
  while(stat = digitalRead(ir_pin)){
    if(micros() - start_at > 2500000) return;
  }
  
  start_at = last = micros();
  for(int i = 0; i < IR_DATA_SIZE; i++){
    //入力が反転するまで待ち(上限25ms)
    while(1){
      if(stat != digitalRead(ir_pin)) break;
      if(micros() - last > 25000) return;
    }
    now = micros();
    ir_data[i] = (now - last)/100;  //byteに格納するあため
    last = now;
    stat = !stat;
  }
  
}

//生データ出力
void ir_print_1(){
  for (int i = 0; i < IR_DATA_SIZE; i++){
    Serial.print(ir_data[i]);
    if(ir_data[i] < 1) break;
    Serial.print(",");
  }  
  Serial.println();
}

//解析データ出力
void ir_print_2(){
  int j = 0;
  byte result = 0;
  
  //1or0判定
  for (int i = 3; i < 66; i+=2){
    if(ir_data[i] > 10){
      ir_code[j] = 1;
    }else{
      ir_code[j] = 0;
    }
    j++;
  }
  
  //データを数値化
  for (int i = 0; i < 8; i++){
    if(ir_code[i+16] == ir_code[i+24]){  //反転データチェック
      result = 0;
      break;
    }else{
      bitWrite(result,i,ir_code[i+16]);
    }
  }
  
  //出力
  for(int i = 0; i < 32; i++){
    Serial.print(ir_code[i]);
    Serial.print(",");
  }  
  Serial.println();
  Serial.println(result,DEC);

}

結果確認

91,43,6,4,5,5,6,5,6,5,6,4,6,4,6,4,6,4,6,15,7,15,7,15,6,15,6,15,7,15,6,15,6,15,6,15,6,4,5,16,7,4,5,5,6,5,6,16,7,4,5,5,6,16,6,4,6,16,6,15,6,15,7,4,5,16,6,0
0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,1,0,0,0,1,0,0,1,0,1,1,1,0,1,
69

1行目はリモコンの受信状態がHIGHとLOWが切り替わるタイミングの時間の羅列である。9100us:HIGH, 4300us:LOW, 600us:HIGH, 400us:LOW,,,,,,という感じ。
赤外線リモコンの通信フォーマットのページと比較すると、NECフォーマットであることが予想できる。

2行目はカスタマーコードの部分とデータの部分を”0″,”1″で書き換えた結果である。今回はLOWの時間が1000us以上の箇所を”1″、1000usより短い箇所を”0″として判定した。
1番目から8番目:カスタマーコード
9番目から16番目:1番目から8番目の反転データ
17番目から24番目:データ
25番目から32番目:17番目から24番目の反転データ

3行目は2行目のデータの部分を1バイトの数値に変換したもの。左から下位ビットであることに注意。

結果一覧
result

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です