M5Stackで赤外線リモコンの信号を表示させてみた

ちょっと赤外線リモコンの信号を読み取りたいな〜〜って思うこと、ありますよね。

というわけで、先日買ったM5Stack + IR unitで、簡易的なやつを作ってみました。パルスの幅を読み取れるわけでもなく、目で見て楽しむ以上の実用性はありません(ですが、「目で見て楽しい」のって大事ですよね!?)。

プログラム

プログラムは以下の通りです。M5StackのPort AにIR unitが挿さっていることを想定しています。

#include <M5Stack.h>

/* IR unit を Port A に挿す場合は GPIO 22, M5GO 等の Port B に挿す場合は GPIO 36 を使う */
const int IR_RECEIVE_PIN = GPIO_NUM_22;

void setup() {
  M5.begin();
  M5.Power.begin();
  M5.Lcd.print("Press Button A");
  pinMode(IR_RECEIVE_PIN, INPUT);
}

int prevValue = 1;
int currX = 0;
int currY = 10;
const int X_DELTA = 2;
const int Y_DELTA = 8;
enum {
  STANDBY,
  ACTIVE,
  REACHED_END
} state;

void loop() {
  M5.update();
  if (M5.BtnA.wasPressed()) {
    currX = 0;
    currY = 10;
    M5.Lcd.fillScreen(0x000000);
    M5.Lcd.setCursor(0, 0);
    M5.Lcd.print("Ready");
    state = STANDBY;
  }
  if (state == STANDBY || state == ACTIVE) {
    int currValue = digitalRead(IR_RECEIVE_PIN);
    if (state == STANDBY ? (currValue == 0) : state == ACTIVE) {
      if (state == STANDBY) {
        M5.Lcd.fillScreen(0x000000);
        state = ACTIVE;
      } else if (prevValue != currValue) {
        M5.Lcd.drawLine(currX, currY-Y_DELTA, currX, currY+Y_DELTA, 0xffffff);
      }
      if (currValue) {
        M5.Lcd.drawLine(currX, currY+Y_DELTA, currX+X_DELTA, currY+Y_DELTA, 0xffffff);
      } else {
        M5.Lcd.drawLine(currX, currY-Y_DELTA, currX+X_DELTA, currY-Y_DELTA, 0xffffff);
      }
      prevValue = currValue;
      currX += X_DELTA;
      // 画面サイズ:320x240
      if (currX > 320) {
        currX = 0;
        currY += 20;
      }
      if (currY > 240) {
        state = REACHED_END;
      }
    }
  }
  delayMicroseconds(100); // ここの値は適当に変える(100μs = 10kHzくらい)
}

動作としては、

  • リセット時に「Press Button A」と表示し、
  • ボタンA(3つ並んだうち、左端のボタン)が押されると信号待ちに移る。
  • 信号を受信するとそれを表示する。画面が埋まったら受信をやめる。

となります。

一定間隔で delayMicroseconds を呼んでいますが、もっと真面目にやるならタイマーとかを使った方が良いと思われます。今回は実験・お遊び的な感じなのでこれで良しとします。

動作風景

実際にその辺のリモコンの信号を観測してみた様子です。矩形波として表示されています。

この前作った、M5StickCをデジカメ用の赤外線リモコンにしたやつを観測してみました。パルスが16個来ているのが分かります(後半にもパルスが16個あるはずですが、今回表示できる枠には入っていません)。

ところで、以前作ったカメラ用の赤外線リモコンは37〜38kHzの搬送波を使っていました。しかし、今回の出力にはそのようは搬送波の痕跡は見当たりません。

これは、サンプリング周波数が低いとかそういう問題ではなく、今回使っているIR unitに入っているのが「素のフォトダイオードやフォトトランジスター」ではなく「赤外線リモコン受信モジュール」であるためです。赤外線リモコン受信モジュールはリモコン信号の搬送波の部分を「ならして」、38kHz程度の点滅を受信している間は常に “Active”(出力ピンがLow)を出力します。(筆者はこの仕様を今回初めて知りました)

フォトダイオードやフォトトランジスターを使えば搬送波の部分も見えるかもしれませんが、そのためには雑に delayMicroseconds を呼ぶだけのコードでは綺麗な波形が見えないかもしれません。

関連記事

赤外線リモコンの分析といえば、昔Raspberry Piでも似たようなことをやりました。この時は赤外線リモコンの信号の解析をツールに任せ、解析結果を使ってラズパイを赤外線リモコンの送信側として利用していました。