ESP32とBluetooth(3.0)コントローラーをESP-IDFで接続する

前回の記事ではBLE(Bluetooth4)のコントローラを使用しましたが、
入手性が悪かった(Amazonでは売ってない)ので
Amazonで普通に売っているBluetooth3のコントローラーをESP32と接続します。

##・ESP-IDFを導入する

こちらの記事を参考にESP-IDFを導入しましょう。

ESP-IDF ( ESP32 開発環境 ) の使い方 | mgo-tec電子工作
https://www.mgo-tec.com/esp32-idf-howto-01

##・Btstackを導入する

ESP-IDFが導入出来たら任意のディレクトリ(homeディレクトリなど)で

```
git clone https://github.com/bluekitchen/btstack.git
```

を実行します。
参照：
https://bluekitchen-gmbh.com/btstack/quick_start/#getting-btstack-from-github

ダウンロードが終わったら
任意のディレクトリ/btstack/port/esp32で

```
./integrate_btstack.py
```

を実行するとexample以下にサンプルが作成されます

##・コントローラーのアドレスを確認

ここで接続するコントローラーのアドレスを確認します

Bluetooth Profiles Scannerなどを使います
https://play.google.com/store/apps/details?id=com.sanji.jasper_hsieh.sdpscanner&hl=ja

![DSC_0954.JPG](https://qiita-image-store.s3.amazonaws.com/0/298776/fa74bb30-54cc-f2f5-b1fa-cc5652e3ba2b.jpeg)

Discoverd ProfilesにHuman Interface Deviceが表示されることを確認します。
もし別のProfileが表示されるときはモードを変更しましょう。
たいていのコントローラーにはAndroid用、iPhone用、HID用などモードを変更する機能が内蔵されています。
確認出来たらアドレスをメモしておきます。

##・hid_host_demoを使用する

/btstack/port/esp32/example/hid_host_demo/mainに移動しhid_host_demo.cを編集する

```
static const char * remote_addr_string = "E4:17:D8:16:47:23";
```

ここをメモしたアドレスに変更します。

BTキーボードを持っているならここで一度確認してみましょう。
アドレスをキーボードの物にして
キーボードを接続待機状態にしてhid_host_demoを実行すると繋がります。

![DqVzl0KVsAAzZNl.jpg](https://qiita-image-store.s3.amazonaws.com/0/298776/5fb6a7fe-74b7-41ce-779f-6732be881645.jpeg)
(testと打ち込んだ状態)

この状態でコントローラーを接続すると
HID Connection established
と表示された後何も表示されませんが、ボタンを押すたびにpacket_handler()内のL2CAP_DATA_PACKETイベントが発生しているので処理を追加します。

```
        case L2CAP_DATA_PACKET:
            printf_hexdump(packet, size); // この処理を追加
```


そうするとボタンを押すたびに
A1 03 0F 7F 7F 7F 7F 00 00 00 00 
等と表示されるのでボタンのコードを書き出しましょう。
(コントローラーによって違うと思われる)

![DSC_0961.JPG](https://qiita-image-store.s3.amazonaws.com/0/298776/89f7793d-645a-7cda-ae7c-9c9148eeac1b.jpeg)


##・ボタン処理を実装する

L2CAP_DATA_PACKET部分でコードを処理します。
自分は関数を作ってますがお好みでどうぞ。

```
呼び出し部分
        case L2CAP_DATA_PACKET:
            printf_hexdump(packet, size);
            decodeData(packet, size);

処理部分
const int INDEX_UP_DOWN = 4;
const uint8_t LEVER_UP = 0x00;    // 00000000
const uint8_t LEVER_DOWN = 0xFF;  // 11111111

const int INDEX_BUTTON = 9;
const uint8_t BUTTON_Y = 0x10;    // 00010000
const uint8_t BUTTON_A = 0x01;    // 00000001

void decodeData(const void *data, int size) {

    uint8_t upDown = ((uint8_t *)data)[INDEX_UP_DOWN];
    uint8_t button = ((uint8_t *)data)[INDEX_BUTTON];

    // 同時押し無し(十字ボタン)
    if (upDown == LEVER_UP) {
        printf("%02X ",upDown);
        printf("UP\n");
    }
    else if (upDown == LEVER_DOWN) {
        printf("%02X ",upDown);
        printf("DOWN\n");
    }

    // 同時押しあり
    if (button & BUTTON_Y) {
        printf("BUTTON Y(up)\n");
    }
    if (button & BUTTON_A) {
        printf("BUTTON A(down)\n");
    }
以下略
```

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/btstack?src=hash&amp;ref_src=twsrc%5Etfw">#btstack</a> で <a href="https://twitter.com/hashtag/esp32?src=hash&amp;ref_src=twsrc%5Etfw">#esp32</a> とBluetooth3なコントローラを繋ぐ簡単な方法が分かりました<br>時間がある時にQiitaとかにまとめようと思います＼(^o^)／ <a href="https://t.co/QO6phUJOBw">pic.twitter.com/QO6phUJOBw</a></p>&mdash; もけ@ムギ㌠ (@coppercele) <a href="https://twitter.com/coppercele/status/1058759005068189697?ref_src=twsrc%5Etfw">2018年11月3日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/ESP32?src=hash&amp;ref_src=twsrc%5Etfw">#ESP32</a> を内蔵したラジコン戦車を <a href="https://twitter.com/hashtag/btstack?src=hash&amp;ref_src=twsrc%5Etfw">#btstack</a> のBluetooth classicで接続して操作するようにしました。<br><br>市販のBluetooth3.0コントローラーで安定、安価、簡単に操作できるのがいいですね(ﾟ∀ﾟ) <a href="https://t.co/amugpSQaoB">pic.twitter.com/amugpSQaoB</a></p>&mdash; もけ@ムギ㌠ (@coppercele) <a href="https://twitter.com/coppercele/status/1059481380424273920?ref_src=twsrc%5Etfw">2018年11月5日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

実際にラジコンに組み込んでみました。

以上です。

##コントローラーについて
Amazonで2000円程度で売っているコントローラーで確認しています。

8Bitdo ゲームパッド (ZERO ブルー)(終売？)
https://www.amazon.co.jp/dp/B071Z3XQ13

GameSir G3v ワイヤレス Bluetoothコントローラー
https://www.amazon.co.jp/dp/B01LYL229G/
※G3vは売り切れたようで類似品のG3sが表示されます。