赤外線LEDでリモコンごっこ

IMG_3128 他の方のサイトでも、赤外線LEDを買ってきてArduinoで便利なリモコンを作る、ということをやっているので、私も真似したく、赤外線LEDを買ってきた。

 10個も入っていて100円である。

 受信機はこの前800円で買ったリモコンと受信モジュールのセットがあるから、これでよい。

 この赤外線LEDは50mA流す規格なので、20mAしか流せないArduinoで光らせるには少し大き過ぎる。1kΩばかり抵抗をつけて5mAくらいにする。暗くてリモコンが反応しないのじゃないかな、とも思ったが、受光部に近づければ大丈夫だ。しかし、デジカメで観察するとかなり暗い。もし、ちゃんとしたものを組み立てるのなら、FETなどでリレーして、他の電源から50mA流したほうがいいだろう。

 今回は遊びなので、5mAで光らせる。

 先達のサイトでは、スクラッチビルドのコードで市販のリモコンの信号を受信し、ミリ秒単位でオンオフ時間を計測して記録し、その通りに赤外線LEDを光らせてうまく行っている方が多いようだ。

 一方、Arduinoには、「IRremote」というライブラリをGitHubで公開しておられる方がいるので、これを使えば簡単である。

 GitHubのページからzip玉をもらって解凍し、できたディレクトリ(IRremote)をArduinoのインストールディレクトリの「libraries」の下にコピーすればよい。

 今日は私の家のリビングの扇風機のリモコンで試してみよう。

 リビングの扇風機のリモコン信号をコピーしてテストするには、ライブラリをインストールするとできるサンプルスケッチのうち、「IRrecord」というのを使う。コマンドメニューは「ファイル→スケッチの例→IRremote→IRrecord」と辿る。

 これは、「1回こっきりの学習リモコン」のスケッチだと思えばよい。市販のリモコンを受信して記憶し、次いでボタンを押すとそのままそっくり信号のコピーを赤外線LEDから送出するスケッチだ。

 赤外線LEDは1kΩの抵抗と直列にしてデジタル3番ピンに、受信機は11番ピンに、タクトボタンを12番ピンにつなぐ。タクトボタンの入力側は10kΩの抵抗できちんとプルダウンしておくのが行儀がいい。そうしないと、手を触れたくらいのことでスイッチが入ってしまう。

 ブレッドボードが出来たら、使いたいリモコンを受信機に近づけ、ボタンを押す。

 それから今度は、ブレッドボード上の赤外線LEDを電気製品に近づけ、タクトボタンを押す。

 そっくりコピーされた信号が送出され、扇風機が動く。

 これで、ハードウェアは正しく動くことが分かったので、今度は単純にデータをハードコーディングで配列に書き出し、これを送出して扇風機のスイッチをオンオフさせる。

 まず、データを記録する。それにはサンプルスケッチの「IRrecvDumpV2」を使う。今度は受信機を6番ピンにつなぎ換え、シリアルモニタを起動してデータを観測する。そうすると、そのまま使える形の配列の初期化定義の格好でダンプが出てくる。

 これをクリップボードにコピーして、今度はサンプルスケッチの「IRSendDemo」にペーストし、送出してやればよい。

 ところが、ここでハマッた、ハマッた。そのままではうまくいかないのである。

 はじめ、私の扇風機では、「IRrecvDumpV2」のダンプはこうなった。

Encoding  : UNKNOWN
Code      : 1FB3782D (32 bits)
Timing[68]: 
     -22598
     +4500, -2150     + 650, - 500     + 600, - 500     + 500, - 600
     + 550, - 550     + 650, -1600     + 600, -1600     + 550, -1700
     + 600, - 500     + 550, -1700     + 600, -1600     + 600, -1650
     + 550, - 550     + 600, -1600     + 600, - 500     + 650, - 500
     + 600, - 500     + 600, -1600     + 650, - 500     + 600, - 500
     + 600, - 500     + 600, - 500     + 600, - 500     + 650, -1600
     + 600, - 500     + 600, - 500     + 550, - 600     + 600, -1600
     + 600, -1600     + 550, -1700     + 600, -1600     + 650, - 500
     + 500, - 600     + 550, 
unsigned int  rawData[69] = {9627, 90,43, 13,10, 12,10, 10,12, 11,11, 13,32, 12,32, 11,34, 12,10, 11,34, 12,32, 12,33, 11,11, 12,32, 12,10, 13,10, 12,10, 12,32, 13,10, 12,10, 12,10, 12,10, 12,10, 13,32, 12,10, 12,10, 11,12, 12,32, 12,32, 11,34, 12,32, 13,10, 10,12, 11,0};  // UNKNOWN 1FB3782D

そこで私は、この「rawData[69]」をコピペし、次のようにした。

#include <IRremote.h>

IRsend irsend;

void setup()
{
  Serial.begin(9600);
}

void loop() {
  static unsigned int  rawData[] = {9627, 90,43, 13,10, 12,10, 10,12, 11,11, 13,32, 12,32, 11,34, 12,10, 11,34, 12,32, 12,33, 11,11, 12,32, 12,10, 13,10, 12,10, 12,32, 13,10, 12,10, 12,10, 12,10, 12,10, 13,32, 12,10, 12,10, 11,12, 12,32, 12,32, 11,34, 12,32, 13,10, 10,12, 11,0};  // UNKNOWN 1FB3782D
  if (Serial.read() != -1) {
    for (int i = 0; i < 3; i++) {
      irsend.sendRaw(rawData,sizeof(rawData) / sizeof(rawData[0]), 38); // Sony TV power code
      delay(40);
    }
  }
}

 ところが、これではまったくダメなのである。

 最初は赤外線LEDの電流が足りないのかなあ、などと思い、半日ほどあっちこっちをいじくりまわして、ダメだった。

 「IRrecord」での丸ごと信号コピーはうまく行っているのだから、電流が足りないわけではないらしい。

 そこで、「IRrecord」のダンプ部分にコードを書き足し、「sendRaw()」関数にどんな値を渡しているかを見てみた。

  else if (codeType == UNKNOWN /* i.e. raw */) {
    // Assume 38 KHz
    irsend.sendRaw(rawCodes, codeLen, 38);
    Serial.println("Sent raw");
    Serial.println(codeLen);
    for(int cnt = 0; cnt <= codeLen; cnt++){
      Serial.print(rawCodes[cnt]);
      Serial.print(",");
    }
    Serial.println("\n");
  }

 そうしたら、どうも、ダンプされた値の50倍が渡されているらしい。

4400,2250,550,600,500,600,500,600,500,600,550,1700,500,1700,500,1750,500,600,400,1800,550,1700,500,1650,550,600,550,1700,500,600,500,600,550,600,500,1700,550,550,450,650,550,600,500,600,500,600,450,1800,550,550,550,550,550,600,500,1700,550,1650,550,1700,500,1700,650,500,500,600,500,0,

 そこで、「IRrecvDumpV2」のダンプ出力部分を次のようにカスタマイズした。

  // Dump data
  for (int i = 0;  i < results->rawlen;  i++) {
//    Serial.print(results->rawbuf[i], DEC);
    Serial.print(results->rawbuf[i] * 50, DEC);
    Serial.print(",");
    if (!(i&1))  Serial.print(" ");
  }

 そうすると、ダンプは……

ncoding  : UNKNOWN
Code      : FBB100E8 (32 bits)
Timing[68]: 
     -24324
     +4550, -2150     + 650, - 450     + 650, - 450     + 650, - 500
     + 650, - 450     + 650, -1550     + 650, -1600     + 650, -1550
     + 650, - 450     + 650, -1600     + 650, -1550     + 700, -1550
     + 650, - 450     + 650, -1550     + 650, - 500     + 650, - 450
     + 650, - 450     + 650, -1600     + 600, - 500     + 650, - 450
     + 650, - 500     + 600, - 450     + 700, - 450     + 650, -1550
     + 650, - 500     + 650, - 450     + 650, - 450     + 650, -1600
     + 600, -1600     + 650, -1550     + 650, -1600     + 650, - 450
     + 650, - 450     + 650, 
unsigned int  rawData[69] = {24324, 4550,2150, 650,450, 650,450, 650,500, 650,450, 650,1550, 650,1600, 650,1550, 650,450, 650,1600, 650,1550, 700,1550, 650,450, 650,1550, 650,500, 650,450, 650,450, 650,1600, 600,500, 650,450, 650,500, 600,450, 700,450, 650,1550, 650,500, 650,450, 650,450, 650,1600, 600,1600, 650,1550, 650,1600, 650,450, 650,450, 650,0};  // UNKNOWN FBB100E8

……となる。

 で、この先頭の「24324」は送信前の空き時間なので、捨ててよいようだ。「IRsendDemo」のほうにこれをコピペし、先頭の24324は消す。

#include <IRremote.h>

IRsend irsend;

void setup()
{
  Serial.begin(9600);
}

void loop() {
  static unsigned int  rawData[] = {4550,2150, 650,450, 650,450, 650,500, 650,450, 650,1550, 650,1600, 650,1550, 650,450, 650,1600, 650,1550, 700,1550, 650,450, 650,1550, 650,500, 650,450, 650,450, 650,1600, 600,500, 650,450, 650,500, 600,450, 700,450, 650,1550, 650,500, 650,450, 650,450, 650,1600, 600,1600, 650,1550, 650,1600, 650,450, 650,450, 650,0};  // UNKNOWN 1FB3782D
  if (Serial.read() != -1) {
    for (int i = 0; i < 3; i++) {
      irsend.sendRaw(rawData,sizeof(rawData) / sizeof(rawData[0]), 38); // Sony TV power code
      delay(40);
    }
  }
}

 これで、赤外線LEDを扇風機に近づけ、シリアルモニタの「送信」ボタンをクリックすると、扇風機がオン・オフされる。

IMG_3129 ブレッドボードは結局、最後はこんな感じ。

「赤外線LEDでリモコンごっこ」への1件のフィードバック

コメントを残す