ESP32を、スマートフォンで操作する。

私は、以前、micro:bitをスマートフォンから操作するアプリ「micropad」を開発しました。

https://qiita.com/secile/items/1a411db01f8d1484f274

これまではmicro:bitの操作しかできませんでしたが、今回、ESP32を操作できるようになりましたので、その方法を説明します。

# micropadとは

[micropad](https://github.com/secile/micropad)とは、ボタン・スライダー・アナログスティックなどを備えた仮想コントローラーです。HTML+JavaScriptで作成されており、Androidのchrome, iOSの「[Bluefy](https://apps.apple.com/jp/app/bluefy-web-ble-browser/id1492822055)」など、Web Bluetooth APIに対応したブラウザから、BLE経由で、micro:bitを操作することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245196/7d6cdfa5-3b99-4020-a77f-25af5b0bb7e2.png)

これをESP32で利用するためには、ESP32側に、micropadとのデータ送受信に対応したプログラムを準備する必要があります。今回、このひな形となるプログラムを作成し、以下の場所で公開しています。

https://github.com/secile/micropad_server_esp32

# 使い方

このプログラムは、ESP32に書き込んで使用するプログラムです。
上記リポジトリからクローンまたはzipをダウンロードして解凍してください。ここではzipをダウンロードした場合で説明します。

解凍すると中に「micropad_server_esp32」というフォルダがあり、その中に「micropad_server_esp32.ino」というファイルがあります。これを「Arduino IDE」で開いてください。

プログラムを開いたら、あなたの行いたい処理を実行するように、プログラムを少し修正する必要があります。プログラムの修正方法について、[後ほど](#プログラムの修正箇所)説明します。

プログラムの修正が完了したら、ESP32にプログラムを書き込んでください。リセット後、「micropad」からの接続待機状態となります。

[micropadの公開ページ](https://secile.github.io/micropad/)を開き、「🚩」ボタンを押すとペアリングダイアログが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245196/28561401-cc64-4acc-a59d-6118324c919f.png)

ここに表示されている「BBC micro:bit ESP32」が、あなたのESP32のデバイス名です。なぜ「BBC micro:bit」が付いているのかというと、「micropad」はデバイス名が「BBC micro:bit」から始まるデバイスだけを表示する仕様だからです。

もちろん、micropadのプログラムを1行修正するだけで、ESP32に自由な名前を付けることができるようになります。どうしても気になる方は、micropadの以下の部分を修正してください。

```js
uBitDevice = await navigator.bluetooth.requestDevice({
    filters: [{ namePrefix: "BBC micro:bit" }], // 👈ここ！ここです！
    optionalServices: [UART_SERVICE_UUID]
});
```

# プログラムの修正箇所

## micropadからデータを受け取った時
micropadのボタン・スライダー・アナログスティックなどを操作すると、「receiveFromMicropad関数」が呼ばれます。

```c
// called when receive cmd from micropad.
void receiveFromMicropad(String controlId, String value1, String value2) {
  // debug. delete if you do not need.
  Serial.println("id:" + controlId + ", value1:" + value1 + ", value2:" + value2);
  
  // branch by controlID and do your task.
  if (controlId == "s1") { // slider
    // for example, pwm LED.
    // int value = value1.toFloat() * 255;
    // ledcWrite(LED_PIN, value);
  }
}
```

この関数の第一引数はcontrolIdで、micropadのどのコントロールが操作されたかを表します。例えばアナログスティック左なら「a1」、右なら「a2」、スライダーなら「s1」などが渡されます。

第二引数のvalue1と第三引数のvalue2は、コントロールIDによって意味が異なります。
- 例えばアナログスティックなら、第二引数はスティックの入力角度、第三引数は入力の強さです。
- 例えばスライダーなら、第二引数は0.0～1.0までの値が入ります。第三引数は使用しません。
- 例えばボタンなら、第二引数は押したときは1、離したときは0が入ります。第三引数は使用しません。

これらの引数にしたがって、処理を実行します。例えばスライダーの値によって、LEDの明るさをPWMで変更する場合は、コメントのようにします。

## micropadにデータを送信するとき。
ESP32からmicropadにデータを送信することもできます。送信したデータは主に、micropadのラベルに表示するために使用します。micropadにデータを送信するには、「sendToMicropad関数」を呼び出してください。

```c
void loop() {
  static int loopCount = 0;
  sendToMicropad("l1", String(loopCount++));
  delay(1000);
}
```

- 第一引数は送信先のcontrolIdです。通常ラベルですので「l1」などを指定します。
- 第二引数は送信したいデータを、文字列で指定します。

micropad側では、デフォルトでは、ラベルは1つしか用意していません。もし複数のデータ表示が必要な場合は、micropad側のプログラムを変更して、ラベルを追加する必要があります。手順については、[micropad](https://github.com/secile/micropad)のリポジトリページを参照してください。

# おわりに
マイコンボードで作品を作るとき、それをどうやって操作するか、は課題でした。電子工作初心者としては、LEDライトが点灯するだけ、モーターが回るだけ、でも、それをスマホから操作できれば、嬉しいものです。このアプリがそんな人たちの役に立てれば嬉しいです