2012年4月10日火曜日

リモコンの赤外線信号を解読

家電製品で使用されている赤外線信号の解読を試みます。


まずは、前回使った、赤外線信号受信用の回路図を復習です。

赤外線リモコン受信モジュールOSRB38C9AAは、Arduinoの2番ピンへ接続し信号を受け取ります。
受信確認のためのLEDは13番ピンに接続します。

赤外線リモコン受信モジュールOSRB38C9AAの電源として、Arduinoの5Vラインと、GNDラインへ接続しています。












次にスケッチです。

  int IR_in=2;
  int LED_out=13;
  int Status=0; //センサーは受信するとLow それ以外はHigh
  int val;
  int i;
  int count=0;
  unsigned int data[512]={};
  unsigned long us=micros();
  unsigned long us_tmp=micros();
  int ReceiveIR=0;
 
void setup(){
  Serial.begin(57600);
  pinMode(IR_in,INPUT);
  pinMode(LED_out,OUTPUT);
}
void loop(){
  while((val=digitalRead(IR_in))==Status){ //入力信号のon/off切替までループ
    if(++count==30000){ //トータル30000回分の時間稼ぎをしている間に切り替わらなかった、入力信号は一段落したと見切る
    //Serial.println(""); //シリアル表示を改行する
    count=0; //変数の初期化
    i=0; //変数の初期化
    if( ReceiveIR==1){
      Serial.println(""); //シリアル表示を改行する
      ReceiveIR=0;
    }
    }
  }
 
  // 30000回ループを一塊として受信があったか、なかったかのフラグを制御
  ReceiveIR=1;
 
  //入力信号が切替が発生したので記録/表示する
  //data[0]には、初めてoffからonへ切り替わるまでの時間が格納されている(送信する時は不要)
  //data[最後]には、最後のoffになってから、30000回に達する時間が格納されている(送信する時は不要)
  us_tmp=micros();
  data[i]=(us_tmp-us)/10; //10us単位で配列へ代入
  if(val==1){
    Serial.print("ON-");
  }else{
    Serial.print("OFF-");
  }
  Serial.print("[");
  Serial.print(data[i++],DEC); //シリアルモニターへ表示後、添え字をインクリメント
  Serial.print("]-");
  Status=val;
  us=us_tmp;
 
  //モニター用LEDの点滅
  if(Status==HIGH){
    digitalWrite(LED_out,LOW);
  } else {
    digitalWrite(LED_out,HIGH);
  }
}

このスケッチでは、モニター用LEDでも受信したことが分かるように点滅することと、受信した信号のOn と OFFの状態を、シリアルモニターへ表示することを行っています。

下の画面ショットは、パイオニアのDVDプレイヤーのリモコンの信号を取得したときのものです。

 2行目の表示は、電源ボタンを押したときの信号、3行目の表示は、消音ボタンを押したときの信号です。

なお、1行目のON-[7]-はゴミです。

2行の信号を例に見てみます。

OFF-[31502]-ON の部分は、OFFの状態が、31502×10マイクロ秒間 続いたことを示しています。
-ON-[850]-OFF の部分は、ONの状態が、850×10マイクロ秒間 続いたことを示しています。

つまり、ONとOFFの間の数値が、その状態が続いた秒数(正確には、×10マイクロ秒)を示すようにスケッチを作りました。

初めのOFFからONに切り替わるまでの時間が、1回目(2行目)と2回目(3行目) で異なるのは、私がリモコンの操作をするまでの時間が異なるからです。ループは、1~30000までを繰り返しています。

両方の受信した信号の状態を見ると、リモコンのボタンを押した後、8500マイクロ秒間ONの状態、次に4240マイクロ秒間OFFの状態になっています。次に、ONが550マイクロ秒、OFFが500マイクロ秒続いています。

若干の誤差が出ていますが、計測値なので、小さいことは気にしないことにします。

赤外線信号の解読 準備編で調べたように、各社オリジナルな信号フォーマットですが、おおよそ、リーダー部があり、次にカスタムコード部やデータ部があると推測されます。

はじめの ON 8500マイクロ秒とOFF 4240マイクロ秒あたりが、リーダー部だと推測できるわけです。また、ONの一番短くても500マイクロ秒程度だったことから 1T=500マイクロ秒と推測できます。

ONとOFFをおよそ86回繰り返す信号だったことから、ONの時間とOFFの時間の組み合わせで、1と0を示していると考えると43ビットの信号を、リモコンから本体に向かって送っていると思われます。

だだし、家電製品協会フォーマットも、NECフォーマットも、ONの時間は一定なはずですが、このリモコンの場合には、ONの時間は最大で4T分(2000マイクロ秒)、OFFの時間も最大で4T分(2000マイクロ秒)程度あったので、別なフォーマットだと思われます。

読み取った信号を赤外線LEDで再現すれば、ArduinoでDVDプレイヤーを制御することが可能になると思われますが、機器の不具合につながってもつまらないので、受信し読み取れたことまでで終わりにします。

赤外線LEDを使って信号を送信する為には、OFFの時は何もしなくて良いですが、ONの時には38KHzの速さのチカチカさせなければ、赤外線受信モジュールは反応しないことは調べた通りです。

今後、もう一台、Arduinoを用意して、赤外線通信させてみたいです。 その時には、自分のオリジナルフォーマットで構わないわけですから。

今日はここまでです。


0 件のコメント:

コメントを投稿