Edited at

ESP32とBluetoothコントローラーをHID(Bluetooth Classic)で接続する簡単な方法

前回の記事では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

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

(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


・ボタン処理を実装する

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");
}
以下略

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

以上です。


コントローラーについて

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

8Bitdo ゲームパッド (ZERO ブルー)(終売?)

https://www.amazon.co.jp/dp/B071Z3XQ13

GameSir G3v ワイヤレス Bluetoothコントローラー

https://www.amazon.co.jp/dp/B01LYL229G/

※G3vは売り切れたようで類似品のG3sが表示されます。