前回の記事では、M5StackおよびM5StickCでHello world!をやった。次は、Lチカならぬ赤外線チカをやってみたいと思う。
筆者が持っている一眼レフはCanon製だ。Canon製一眼レフの赤外線リモコンについては、以前の記事に書いた:
赤外線リモコンを作る際は純正品の信号を解析するところから始めるのが王道なのだろうが、一眼レフについてはすでに有志の解析結果があるので、自分で解析する必要はない(純正品を持っている必要はない)。
M5StickCには赤外線LEDが内蔵されているので、別途部品を用意しなくても赤外線リモコンとして使用することができる。M5Stackには赤外線LEDは内蔵されていないので、前回購入した「M5Stack用赤外線送受信ユニット」を使う(または「M5GO」のような赤外線送受信ユニットを含むキットを買う)。
M5StickCの内蔵赤外線LEDを制御するには、GPIO9を使う。本体裏面のシールに「IR G9」と書かれているので、わざわざインターネット上のドキュメントを参照するまでもない。
M5Stackに「赤外線送受信ユニット」を取り付ける場合、本体側のGroveポートによってGPIOの番号が変わる。具体的には、M5GOに付属するボトムの「Port B」に取り付ける場合は26番だが、M5Stack BasicやM5Stack Grayの本体のGroveポートに取り付ける場合は21番を使うことになる。ネット上に転がってるサンプルコードはM5GOを前提にしている(ので26番を使っている)ことが多いが、筆者のようにM5Stack BasicとIR unitを個別に購入した場合は気をつけよう。

例えば、M5StackオフィシャルのGitHubにある赤外線ユニットのサンプルコードでは、赤外線の送信にGPIO 26を使っている:
(ちなみに、M5StickCのGroveポートに赤外線送受信ユニットを取り付ける場合は、多分GPIO32を使うことになる。)
では、実際に一眼レフ向けの赤外線を送出するコードを書いてみよう。
M5StickC向けのコードは、例えば次のようになる。
#include <M5StickC.h>
/* M5StickC 本体の赤外線LEDは GPIO 9 */
const int IR_SEND_PIN = GPIO_NUM_9;
void setup() {
M5.begin();
M5.Lcd.print("Hello IR Remote!");
pinMode(IR_SEND_PIN, OUTPUT);
}
/* 32700 Hz で点滅させるための待ち時間(マイクロ秒) */
const double t = 1e6 / 32700.0 / 2.0;
void loop() {
/* M5StickC 前面のボタンは BtnA, 右側面のボタンは BtnB */
M5.update();
if (M5.BtnA.wasPressed() != 0) {
M5.Lcd.print("Pressed");
for (int j = 0; j < 16; ++j) {
digitalWrite(IR_SEND_PIN, HIGH);
delayMicroseconds(t);
digitalWrite(IR_SEND_PIN, LOW);
delayMicroseconds(t);
}
/* 即時シャッターの場合は 7.33 ms 待つ、2秒後シャッターの場合は 5.36 ms 待つ */
delayMicroseconds(7.33 * 1000);
for (int j = 0; j < 16; ++j) {
digitalWrite(IR_SEND_PIN, HIGH);
delayMicroseconds(t);
digitalWrite(IR_SEND_PIN, LOW);
delayMicroseconds(t);
}
}
delay(100);
}
M5Stackに赤外線送受信ユニットを取り付ける場合のコードは次のようになる。先述のように、M5Stack Basic + IR unit の場合と、M5GOの場合で赤外線LEDのGPIOの番号が違うので注意しよう。
#include <M5Stack.h>
/* IR unit を Port A に挿す場合は GPIO 21, M5GO 等の Port B に挿す場合は GPIO 26 を使う */
const int IR_SEND_PIN = GPIO_NUM_21;
void setup() {
// put your setup code here, to run once:
M5.begin();
M5.Power.begin();
M5.Lcd.print("Hello IR remote!");
pinMode(IR_SEND_PIN, OUTPUT);
digitalWrite(IR_SEND_PIN, LOW);
}
/* 32700 Hz で点滅させるための待ち時間(マイクロ秒) */
const double t = 1e6 / 32700.0 / 2.0;
void loop() {
M5.update();
/* M5Stack 前面のボタンは左から順に BtnA, BtnB, BtnC */
if (M5.BtnA.wasPressed() != 0) {
M5.Lcd.print("Pressed");
for (int j = 0; j < 16; ++j) {
digitalWrite(IR_SEND_PIN, HIGH);
delayMicroseconds(t);
digitalWrite(IR_SEND_PIN, LOW);
delayMicroseconds(t);
}
/* 即時シャッターの場合は 7.33 ms 待つ、2秒後シャッターの場合は 5.36 ms 待つ */
delayMicroseconds(7.33 * 1000);
for (int j = 0; j < 16; ++j) {
digitalWrite(IR_SEND_PIN, HIGH);
delayMicroseconds(t);
digitalWrite(IR_SEND_PIN, LOW);
delayMicroseconds(t);
}
}
delay(100);
}
実際にM5StackやM5StickCにこのプログラムを書き込んで一眼レフを制御してみた動画を載せておこう:
(動画の中で動いているプログラムとここに載せたプログラムは微妙に違うが、まあ気にしないでほしい)
単体の赤外線送受信ユニットを使う場合は1mくらい離れても信号が届いているが、M5StickC内蔵の赤外線LEDを使う場合はあまり信号が安定しない。サクッと試すにはM5StickC内蔵の赤外線LEDは便利だが、実用的なリモコンとして使う場合は別途赤外線LEDを取り付けた方が良いかもしれない。
数m離れた位置からカメラを制御したい場合は、M5StickC内蔵の赤外線LEDでも既製品の赤外線送受信ユニットでもなく、もっと強力な赤外線LEDを使った送信機を自作した方が良さそうだ。
次回予告:今度は赤外線ではなく有線でカメラを制御してみたい。
ピンバック: M5Stackを一眼レフの有線リモコン(レリーズ)にする | 雑記帳
ピンバック: M5Stackで赤外線リモコンの信号を表示させてみた | 雑記帳