この記事は、 すごくなりたいがくせいぐるーぷ GWアドベントカレンダー7日目の記事です。
まだ照明リモコンさわってんの?
ごめんなさい。
まださわってます。
というわけで、今回は「ただの照明」をIoTしてみた紹介です。
背景
- Philips Hueは高い
- Google Home miniはもらったのである
- ESP32とはたくさん遊んできているので仲がいい
- お部屋のライトは赤外線リモコン
ということで、ESP32とGoogle Homeを使ってIoTな照明でないただの赤外線リモコンな照明をインターネットにつなげます。
構成
この図はホワイトボードに書いてiPhoneでスキャンしました。
こういうことができるからいいんだよな。おうちホワイトボードはおすすめです。
環境
開発環境
- これ
- VSCode(を使ってくださいこれは布教です)
- Arduino for VSCode(VSCodeでArduinoをやる環境です。残念なArduino IDEと比して最高なのでぜひ使ってください。)
- BlynkのArduino Library (v.0.6.1)
- ESP32のボードパッケージ (v.1.0.1)
おうち環境
Panasonicの照明です。
正式な型番とか知らないのですが、おそらくこのリモコンが使えるやつならいけると思います。
なお、今回のやり方では学習リモコン的に作るので、他の形式のものでも教師信号が与えられる赤外線リモコンがあれば大丈夫なはずです。
ハードウェアの準備
今回は手元にESP32の開発ボードがなかったので、ESP32-WOORM-32のモジュールを直接使ってやりました。
回路図には書いていませんが、リセット用のスイッチとかもついてます。IR部分以外のところは、よくあるESP32な構成だと思います。
ESP32で赤外線学習リモコンを作るを参考にしています。
ここからの特筆すべき変更として、 LEDの出力増強のためトランジスタで増幅しています。
本来はここに、IRレシーバの出力部のRCフィルタやIR-LEDの電流制限抵抗,バイアス回路なんかも必要なはずですが、面倒なので省きました。
また、今回作ったものでは、電源をいれるように三端子レギュレータも使ってますが、その辺りはESP32-DevkitC的なボードを使ってしまえば解決します。
昨日の午後だけでやったので、さくっとユニ基実装です。
こうしてみるとはんだづけが汚いですね……あとで直します……
このほかに、indicator用のLEDとかつけると便利だと思うのですが、寝室で光ると邪魔なので今回はつけませんでした。
Coding
ESP32で赤外線学習リモコンを作るのスケッチを書き込んで、
$ curl http://<ESP32のIP>/recv
とやってから、赤外線レシーバに向けてリモコンで照明を切る信号を送り、受信に成功したら
$ curl http://<ESP32のIP>/dump --data-binary turnOff
とします。
これを照明をつける信号turnOn
に関してもやってください。
$ curl http://<ESP32のIP>/send @turnOff
$ curl http://<ESP32のIP>/send @turnOn
とやってそれぞれ部屋の照明がついたり消えたりすることを確認したら、この学習して得たバイナリ turnOn
turnOff
をダンプしてESP32に書き込みます。
$ od -tx turnOn > turnOff_dump
とやって、この turnOff_dump
をVSCodeで編集します。
余分なアドレス部を切り取って、 0x
をつけ、カンマ区切りにしてやることで、C配列の形にします。
uint32_t turnOff_data[] = {0x054b8af1, 0x01318180, ... , 0x3aadd678};
みたいな感じです。
それを turnOn
についても行い、Cのコードのglobalなところに書いてあげてから、
int turnOff()
{
received = sizeof(turnOff_data) / sizeof(rmt_item32_t);
memcpy(signals, turnOff_data, sizeof(turnOff_data));
if (ir_use)
{
return 409;
}
else
{
ir_use = true;
xTaskCreate(rmt_tx_task, "rmt_tx_task", 2048, NULL, 10, NULL);
return 202;
}
}
int turnOn()
{
received = sizeof(turnOn_data) / sizeof(rmt_item32_t);
memcpy(signals, turnOn_data, sizeof(turnOn_data));
if (ir_use)
{
return 409;
}
else
{
ir_use = true;
xTaskCreate(rmt_tx_task, "rmt_tx_task", 2048, NULL, 10, NULL);
return 202;
}
}
というような関数を作って、
else if (strcmp(url, "/off") == 0)
{
int res = turnOff();
if (res == 409)
{
send_409(client);
}
else
{
send_202(client);
}
}
else if (strcmp(url, "/on") == 0)
{
int res = turnOn();
if (res == 409)
{
send_409(client);
}
else
{
send_202(client);
}
}
という部分を
元記事の中に入れてやります。
そうすることで、 http://<ESP32のIPアドレス>/on
http://<ESP32のIPアドレス>/off
にアクセスして照明をOn/Offすることが可能になります。
続いて Google Home連携の設定です。Google Home Mini を使って、声で ESP32 の LED を光らせてみたを参考にしました。
ただし、 turn On the light / turn Off the lightと単語で言いたかったので、
のように text ingredientで対応するappletにしています。
日本語だとうまく使えないみたいなので今回は英語で行きます。
また、元記事と大きく異なるのはBlynkの信号を受け付けた時のハンドラで、
BLYNK_WRITE(V1)
{ //Blynk Virtual Pin
Serial.println("-------Blynk Request--------");
const char *word = param[0].asString();
Serial.printf("Said: '%s'\r\n", word);
if (strncmp(word, "off", 3) == 0 || strncmp(word, " off", 4) == 0)
{
turnOff();
Serial.println("Handled : turn OFF");
}
else if (strncmp(word, "on", 2) == 0 || strncmp(word, " on", 3) == 0)
{
turnOn();
Serial.println("Handled : turn ON");
}
}
とすることで先に作っておいた関数たちを呼び出しています。
綺麗に on
off
だけが来ないことの方が多く、大抵スペースが入るので、strncmp(word, " off", 4) == 0
の条件も入れています。
ここまでできれば、とりあえずGoogle Homeに turn On the light または turn off the lightと言うことで照明のON/OFFができるはずです。
お疲れ様でした!
この記事には続きがあります。
次回は、こんな感じのモニタリング画面を出せるようにします。
また、これの脇道記事で、ESP32の電力消費についての記事も書く予定ですので、ぜひそちらも。
書き終わったらここにリンクを貼りますね!
そちらもぜひお読みくださいませ〜!
ソースコード
GitHubリポジトリにあります!
この記事でやってるのは Commit 11b38989cbbe0366e7237fa2a3795cc6b4a4f490
までです!
さて、 すごくなりたいがくせいぐるーぷ GWアドベントカレンダー、明日の最終回は@shinbunbun_ による俺的超おもしろ記事ですので、ご期待ください。