Google Home×ESP32で「ただの照明」をIoTする 

この記事は、 [**すごくなりたいがくせいぐるーぷ** GWアドベントカレンダー](https://gw-advent.9wick.com/calendars/2020/87)**7日目**の記事です。

---


## まだ照明リモコンさわってんの?
ごめんなさい。
まださわってます。

というわけで、今回は「ただの照明」をIoTしてみた紹介です。


<iframe width="560" height="315" src="https://www.youtube.com/embed/uaQoZDnSp1Q" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


## 背景
- Philips Hueは高い
- Google Home miniはもらったのである
- ESP32とはたくさん遊んできているので仲がいい
- お部屋のライトは赤外線リモコン

ということで、ESP32とGoogle Homeを使って**IoTな照明**でない**ただの赤外線リモコン**な照明をインターネットにつなげます。


## 構成

<img width="433" alt="スクリーンショット 2020-05-05 13.14.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200465/99076ff9-539c-56f5-c8e8-200d967cd21a.png">

この図はホワイトボードに書いてiPhoneでスキャンしました。
こういうことができるからいいんだよな。おうちホワイトボードはおすすめです。

## 環境

### 開発環境

- これ
<img width="300" alt="スクリーンショット 2020-05-05 12.10.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200465/198b3216-f37b-a706-e2a7-d996364b8939.png">

- VSCode(を使ってくださいこれは布教です)
- Arduino for VSCode(VSCodeでArduinoをやる環境です。残念なArduino IDEと比して最高なのでぜひ使ってください。)
- BlynkのArduino Library (v.0.6.1)
- ESP32のボードパッケージ (v.1.0.1)


### おうち環境
Panasonicの照明です。
正式な型番とか知らないのですが、おそらくこのリモコンが使えるやつならいけると思います。
なお、今回のやり方では学習リモコン的に作るので、他の形式のものでも教師信号が与えられる赤外線リモコンがあれば大丈夫なはずです。

![イメージ 2.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200465/4fd38661-a467-e095-5782-004b0446f72d.jpeg)
## ハードウェアの準備

今回は手元にESP32の開発ボードがなかったので、ESP32-WOORM-32のモジュールを直接使ってやりました。

![qiita_schematic.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200465/68b38aeb-0b63-c8cf-4687-05fe7160115a.png)

回路図には書いていませんが、リセット用のスイッチとかもついてます。IR部分以外のところは、よくあるESP32な構成だと思います。

[ESP32で赤外線学習リモコンを作る](https://qiita.com/td2sk/items/4c0ef83bcc7e74e5e8d5#%E9%83%A8%E5%93%81)を参考にしています。

ここからの特筆すべき変更として、 **LEDの出力増強のためトランジスタで増幅しています。**


本来はここに、IRレシーバの出力部のRCフィルタやIR-LEDの電流制限抵抗,バイアス回路なんかも必要なはずですが、面倒なので省きました。

また、今回作ったものでは、電源をいれるように三端子レギュレータも使ってますが、その辺りはESP32-DevkitC的なボードを使ってしまえば解決します。

昨日の午後だけでやったので、さくっとユニ基実装です。
こうしてみるとはんだづけが汚いですね……あとで直します……

![イメージ.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200465/2506e57f-4348-ee24-b431-563096b75a89.jpeg)


このほかに、indicator用のLEDとかつけると便利だと思うのですが、寝室で光ると邪魔なので今回はつけませんでした。

## Coding

[ESP32で赤外線学習リモコンを作る](https://qiita.com/td2sk/items/4c0ef83bcc7e74e5e8d5#%E9%83%A8%E5%93%81)のスケッチを書き込んで、

```zsh
$ curl http://<ESP32のIP>/recv
```

とやってから、赤外線レシーバに向けてリモコンで照明を切る信号を送り、受信に成功したら

```zsh
$ curl http://<ESP32のIP>/dump --data-binary turnOff
```

とします。

これを照明をつける信号`turnOn`に関してもやってください。


```zsh
$ curl http://<ESP32のIP>/send @turnOff
```
```zsh
$ curl http://<ESP32のIP>/send @turnOn
```

とやってそれぞれ部屋の照明がついたり消えたりすることを確認したら、この学習して得たバイナリ `turnOn` `turnOff`をダンプしてESP32に書き込みます。


```zsh
$ od -tx  turnOn > turnOff_dump
```
とやって、この　`turnOff_dump`　をVSCodeで編集します。
余分なアドレス部を切り取って、 `0x`をつけ、カンマ区切りにしてやることで、C配列の形にします。

```c
uint32_t turnOff_data[] = {0x054b8af1, 0x01318180,  ... , 0x3aadd678};
```

みたいな感じです。

それを `turnOn`についても行い、Cのコードのglobalなところに書いてあげてから、


```cpp
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;
 }
}

```


というような関数を作って、

```cpp

 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 を光らせてみた](https://www.mgo-tec.com/blog-entry-esp32-googlehome-ifttt-webhooks-blynk.html)を参考にしました。
ただし、 turn **On** the light / turn **Off** the lightと単語で言いたかったので、

<img width="431" alt="スクリーンショット 2020-05-04 21.22.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200465/c32f1dda-46c3-fc28-0a24-fe865a7f83ff.png">


<img width="374" alt="スクリーンショット 2020-05-04 21.24.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200465/1f00287d-923b-ce9a-2c3f-0977233230c3.png">

のように text ingredientで対応するappletにしています。
日本語だとうまく使えないみたいなので今回は英語で行きます。

また、元記事と大きく異なるのはBlynkの信号を受け付けた時のハンドラで、

```cpp

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ができるはずです。
お疲れ様でした!

この記事には続きがあります。
次回は、こんな感じのモニタリング画面を出せるようにします。


<img width="306" alt="スクリーンショット 2020-05-05 13.06.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200465/eecea254-d9e2-2110-a466-b891585c224a.png">

また、これの脇道記事で、ESP32の電力消費についての記事も書く予定ですので、ぜひそちらも。
書き終わったらここにリンクを貼りますね!

そちらもぜひお読みくださいませ〜!

## ソースコード

[GitHubリポジトリ](https://github.com/YuseiIto/IoTLight)にあります!

この記事でやってるのは Commit `11b38989cbbe0366e7237fa2a3795cc6b4a4f490` までです!


---
さて、  [**すごくなりたいがくせいぐるーぷ** GWアドベントカレンダー](https://gw-advent.9wick.com/calendars/2020/87)、明日の最終回は@shinbunbun_ による俺的超おもしろ記事ですので、ご期待ください。