Arduino勉強会

2014/05/03からのアクセス回数 7771

赤外線リモコンのフォーマット

赤外線リモコンには、以下の3つのフォーマットがありますが、ここではNEC方式を使用します。 *1

  • NEC(現ルネサスエレクトロニクス)フォーマット
  • AEHA(家製協)フォーマット
  • SONYフォーマット

NECフォーマットについて

最もよく使われているNECフォーマットを使って実験することにします。

NECフォーマットでは、ビット情報は38KHz(1/3duty)で送信され、Frameと呼ばれるデータ単位 に続いてRepeatと呼ばれるFrameの終わりを表すデータがボタンが押されている間繰り返されます。

Frameは、以下の形式を持っています。データが1の時には、0.56msのON, 1.69msのOFFを送り、 データが0の場合には、0.56msのON, 1.69msのOFFを送ります。

  • Leader(9msのON, 4.5msのOFF)
  • Customer Code(16bitのカスタマコードをLSBから順に送信)
  • Data(8bit)
  • Dataのビット反転値(8bit)
  • Stopビット

Arduinoを使ってNECフォーマットのデータを送る

38KHzでオン・オフを繰り返すには、digitalWriteでは時間がかかるため、PORTDに直接ビットをセットします。 このため使用可能なデジタルピンは、0から7番までとなっています。

Arduinoを使って赤外線リモコンを送信する例題は、いくつかありましたが、今回参考にさせて頂いたのは、以下の3サイトです。

ここでは、Arduinoで遊ぶページをメインに参考にさせて頂き、東芝REGZAの電源オン・オフを試みます。

リモコン側のブレッドボード

ちょっと乱暴ですが、動作を確認するだけなので、赤外線LEDの線の長い方を直接2番と短い方をGNDに接続して試してみます。

今回使った赤外線LEDは、スイッチサイエンスの SIR-34ST3F です。

IR_Send_Bread.png

リモコン側のスケッチ

使用するスケッチは、以下の様にします。

class IrControlNecFormat {
  public:
    // constructor
    IrControlNecFormat(byte ledPin, byte custom0, byte custom1);
    void sendCommand(byte data);
  private:
    byte _ledPinMask;   // the pin mask which the LED is connected
    byte _custom0;  // custom code
    byte _custom1;  // custom code'
  
    void sendData(byte date);
    void on(int num);
};

IrControlNecFormat::IrControlNecFormat(byte ledPin, byte custom0, byte custom1) {
  _ledPinMask = 1 << ledPin;
  _custom0 = custom0;
  _custom1 = custom1;
 
  pinMode(ledPin, OUTPUT);  // set the ledPin as an OUTPUT
}

void IrControlNecFormat::sendCommand(byte data){
  on(346);                  // leader code(ON)
  delayMicroseconds(4500);  // leader code(OFF)
 
  sendData(_custom0);       // custom code
  sendData(_custom1);       // custom code
 
  sendData(data);           // data
  sendData(~data);          // ~data
 
  on(22);                   // stop bit
}

void IrControlNecFormat::sendData(byte data) {
  for(int i = 0; i < 8; i++) {
    on(22);
    int delayU_Sec = ( data & 0x01 ) ? 1690 : 565;
    delayMicroseconds( delayU_Sec );
    data = data >> 1;
  }
}

void IrControlNecFormat::on(int num) {
  for(int i = 0; i < num; i++) {
    PORTD |= _ledPinMask;
    delayMicroseconds(9);
    PORTD &= ~_ledPinMask;
    delayMicroseconds(17);
  }
}

// 赤外線LEDを2番ピンとGNDに接続
// 東芝REGZAのカスタマコードは、 0x40, 0xBF
IrControlNecFormat controller(2, 0x40, 0xBF);

void setup() {
}

void loop() {
  // REGZAの電源コードは、0x12
  controller.sendCommand(0x12);
  // 5秒間隔でオン・オフを繰り返す
  delay(5000);
}

スケッチの以下の部分で2番ピンにカスタマコードとして、0x40, 0xBFとして、IrControlNecFormatクラスのインスタンスを生成します。

IrControlNecFormat controller(2, 0x40, 0xBF);

これで、東芝REGZAのコントロールができるcontrollerができます。 これに、0x12(電源のコード)をsendCommandで送ると電源のオン・オフを繰り返します。

実際に動かしてみる。

ブレッドボードを組み立てて、LEDをテレビに向けてリセットスイッチを押してみて下さい。 5秒間隔でオン・オフを繰り返します。*2

IR_Send_Setting.png

他の操作方法

上記のスケッチのカスタマコードとコードを変えるといろんな処理ができるようになります。

以下のPDFに各種テレビのカスタムコードとデータの意味がまとめられています。

赤外線受信機

赤外線リモコンのコードが公開されていない場合には、どうしたらよいのでしょう。

今回は、スイッチサイエンスの RPM6938リモコン受光モジュール を使って実験してみます。

RPM6938_master_10.jpg

ピンの配置は、データシートから引用します。丸い突起のある面の左からRout, GND, Vccとなっています。

IR_Receiver.png

赤外線受光器のブレッドボード

以下の様にブレッドボードを組み立てます。受光モジュールが同じものがなかったので、形の似たもので表示しています。

IR_Rec_Bread.png

赤外線コード解析

Arduinoで遊ぶページの赤外線リモコンコード解析(NECフォーマット) に紹介されている赤外線リモコン解析スケッチが重宝します。

以下に引用して表示します。

#define COUNT_NUM 68

const int pin = 2;              /* 赤外線センサの出力を接続するデジタルピン */
unsigned long time[COUNT_NUM];  /* 時刻を格納する配列 */

void setup () {
  pinMode(pin, INPUT);
  Serial.begin(9600);
}

void loop () {
  int repeat = 0;
  int mode; /* 読み取るデータを決める */
  char str[64];
 
  /* 68回データを読み取る */
  mode = HIGH; /* 最初はHIGH */
  for (int i = 0; i < COUNT_NUM; i++) {
    while(digitalRead(pin) == mode) { /* 状態が変わるまで待つ */
        ;
    }
    time[i] = micros(); /* 時刻を記録する */
   
    if (mode == HIGH) { /* onとoffが交互に来るので,待つべき状態を変える */
      mode = LOW;
    } else {
      mode = HIGH;
    }
   
    /* リーダコードのoffが2.25msだと次にストップビットが来て終了 */
    /* 3000ms以下かどうかで判定 */
    if ((i == 3) && ((time[2] - time[1])) < 3000)  {
      repeat = 1;
      break;
    }
  }
 
  /* データの出力 */
  Serial.print("--------- BEGIN ---------\n");
 
  sprintf(str, "Leader:\n  HIGH %dms\n", (time[1] - time[0]));
  Serial.print(str);
  sprintf(str, "  LOW  %4dms\n\n", (time[2] - time[1]));
  Serial.print(str);
 
  if(repeat) {
    Serial.println("Repeat");
  } else {
    Serial.println("Custom Code:");
    print_data(2);
    print_data(18);

    Serial.println("");
 
    Serial.println("Data:");
    print_data(34);
    print_data(50);
   
    Serial.print("---------  END  ---------\n\n");
  }
}

void print_data(int start) {
  int code = 0;
  char str[32];
 
  sprintf(str, "  ");
  for (int i = 0; i < 8; i++) {
    if ((time[2 * i + start + 2] - time[2 * i + start]) > 1500) {
      code |= 1 << i;
      sprintf(&str[2 * (i + 1)], "1 ");
    } else {
      sprintf(&str[2 * (i + 1)], "0 ");
    }
  }
 
  sprintf(&str[17], ", %02x", code);
  Serial.println(str);
}

赤外線コード解析を動かしてみる

それでは、赤外線コード解析スケッチを動かしてみます。

IR_Recv_Setting.png

シリアルモニターを起動し、テレビ(REGZA)の電源ボタンを押すと以下の様に返ってきます。

IR_Recv_monitor.png

最初に作った通り、カスタマコード0x40, 0xBFとデータ0x12が受信されていることが確認できます。

これを使えば、他のリモコンの解析もできます。

再確認

小出さまのご質問で、再度実験をしてみました。

もしかしてCPUのクロックが影響しているのかと思い、今回はDuemilanoveを使いました。

confirm.png

起動直後は、きちんと動いていましたが、蛍光灯の明かりを消すと急に以下の様にシリアスコンソールに 表示されました。

--------- BEGIN ---------
Leader:
  HIGH 2152ms
  LOW   324ms

Repeat
--------- BEGIN ---------
Leader:
  HIGH 80ms
  LOW  2572ms

Repeat

出力を遡ってみると、東芝のリモコンを押したときには、きちんとCustom Codeの出力でていました。

--------- BEGIN ---------
Leader:
  HIGH 72ms
  LOW  -18344ms

Custom Code:
  1 1 1 1 1 1 1 1, ff
  0 1 0 1 1 1 1 0, 7a

Data:
  1 0 0 0 0 1 0 0, 21
  0 0 0 1 0 1 0 0, 28
---------  END  ---------

コメント

選択肢 投票
おもしろかった 15  
そうでもない 0  
わかりずらい 1  

皆様のご意見、ご希望をお待ちしております。勉強会で分からなかったこと等、お気軽に問い合わせて下さい。

スパム防止に画像の文字列も入力してください。

  • たいへん興味深く、赤外線コード解析作製したのですが、東芝のリモコンを入力しても際限なくスクロールしていきます。受信されてないのか?同期が取れてないのでしょうか? -- 小出? 2015-07-10 (金) 08:22:36
  • 小出さま、「再確認」を見てください。状況によってはシリアル画面が流れることがありましたが、Leaderの検出がずっと出ているみたいです。キーを押したときの情報がないか探してみてください。 -- 竹本 浩? 2015-07-10 (金) 21:19:08
  • ありがとうございます。調べてみます。arduino興味深いんですが まだまだ始めたばかりでして。 -- 小出? 2015-07-11 (土) 09:42:28
  • Leader が流れるので 箱の中に入れたりしたのですが、電池2本で動作するよう3.3Vのmini使ってまして、センサーの電圧も不足してますね。お恥ずかしい限りです。 -- 小出? 2015-07-13 (月) 08:24:53

(Input image string)


*1 赤外線リモコンの通信フォーマットを参考にしました
*2 どうもREGZAでは電源オフで上手くできないことがあります

添付ファイル: fileconfirm.png 358件 [詳細] fileRPM6938_master_10.jpg 500件 [詳細] fileIR_Send_Setting.png 586件 [詳細] fileIR_Recv_monitor.png 609件 [詳細] fileIR_Send_Bread.png 579件 [詳細] fileIR_Recv_Setting.png 581件 [詳細] fileIR_Receiver.png 529件 [詳細] fileIR_Rec_Bread.png 638件 [詳細] fileIR_Oscillo.png 254件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2017-06-17 (土) 21:37:56 (8d)
SmartDoc