ESP32-BLE-Gamepad ライブラリの使用方法


# ESP32-BLE-Gamepad の使用方法

ESP32をBlueToothゲームパッド化するライブラリです。

https://github.com/lemmingDev/ESP32-BLE-Gamepad

## ライブラリのインストール
Arduino-IDE,PlatformIOとも、通常のライブラリ追加処理でOKです。
2024/4現在のバージョンでは、BlueToothライブラリとしてNimBLEが使用されるので、このライブラリもインストールします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221204/3326a85e-cf40-972d-e1e7-b03349ee8e5e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221204/ca8d6b4a-ceda-9219-1661-f686e41d3427.png)

## 簡単な利用方法

BleGamepadオブジェクトを生成して、ボタンや軸設定をするだけです。

``` main.cpp
#include <BleGamepad.h>

BleGamepad bleGamepad;
void setup()
{
  bleGamepad.begin();
}

void loop()
{
  if (!bleGamepad.isConnected()){
    return;
  }
  bleGamepad.press(BUTTON_1);  // ボタン１を押す
  bleGamepad.press(BUTTON_2);  // ボタン２を押す
  bleGamepad.setAxes(32767,32767/2);   // X,Y軸を設定
}
```

何も指定しないと、"ESP32 BLE Gamepad" という名前でBlueTooth上に現れるので追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221204/df0a3f06-cec3-6794-e768-c0fcb370f9f0.png)

なにも指定しない場合、8軸16ボタンのハット付きのデバイスになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221204/38c7d817-b3e0-9e4d-7e19-cb78cbf8ea0e.png)

上記のプログラムではボタンは１，２が押しっぱなしで、軸はXが最大（右）、Yが中央になっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221204/af824a7b-ba4c-c873-fc39-452e30cf24cf.png)

## 設定

### デバイス名の指定
BleGamepadのコンストラクタの第１引数で名前を指定できます。
第２引数は製造者名、第３引数はバッテリーレベル(100が最高)です。
``` main.cpp
BleGamepad bleGamepad("MyGamepad","Home",50);
```

## ボタン数などの設定
BleGamepadConfigurationクラスのオブジェクトに設定値を書き込み、begin()に渡します。
なお、 **Configurationを変更した場合、デバイスは再接続（削除して接続）しないと、設定が反映されない** ことがあるようです。（OS、環境などに依存すると思います）

``` main.cpp
  BleGamepadConfiguration config;
  config.setButtonCount(4);     // 4ボタン
  config.setHatSwitchCount(0);  // ハットスイッチなし
  config.setWhichAxes  (true,true,false,false,false,false,false,false); // 2軸
  config.setIncludeBrake(true);  // オプションでブレーキペダルをつける
  bleGamepad.begin(&config);
```

## その他の設定

BleGamepadConfigurationクラスに対して、以下のメンバがあります。全部試していませんが、名前で推察できるものが多いです。

```BleGamepadConfiguration.h
    void setControllerType(uint8_t controllerType);
    void setAutoReport(bool value);
    void setHidReportId(uint8_t value);
    void setButtonCount(uint16_t value);
    void setHatSwitchCount(uint8_t value);
    void setIncludeStart(bool value);
    void setIncludeSelect(bool value);
    void setIncludeMenu(bool value);
    void setIncludeHome(bool value);
    void setIncludeBack(bool value);
    void setIncludeVolumeInc(bool value);
    void setIncludeVolumeDec(bool value);
    void setIncludeVolumeMute(bool value);
    void setWhichSpecialButtons(bool start, bool select, bool menu, bool home, bool back, bool volumeInc, bool volumeDec, bool volumeMute);
    void setIncludeXAxis(bool value);
    void setIncludeYAxis(bool value);
    void setIncludeZAxis(bool value);
    void setIncludeRxAxis(bool value);
    void setIncludeRyAxis(bool value);
    void setIncludeRzAxis(bool value);
    void setIncludeSlider1(bool value);
    void setIncludeSlider2(bool value);
    void setWhichAxes(bool xAxis, bool yAxis, bool zAxis, bool rxAxis, bool ryAxis, bool rzAxis, bool slider1, bool slider2);
    void setIncludeRudder(bool value);
    void setIncludeThrottle(bool value);
    void setIncludeAccelerator(bool value);
    void setIncludeBrake(bool value);
    void setIncludeSteering(bool value);
    void setWhichSimulationControls(bool rudder, bool throttle, bool accelerator, bool brake, bool steering);
    void setVid(uint16_t value);
    void setPid(uint16_t value);
    void setAxesMin(int16_t value);
    void setAxesMax(int16_t value);
    void setSimulationMin(int16_t value);
    void setSimulationMax(int16_t value);
    void setModelNumber(char *value);
    void setSoftwareRevision(char *value);
    void setSerialNumber(char *value);
    void setFirmwareRevision(char *value);
    void setHardwareRevision(char *value);
```

### AutoReport
AutoReportは、ソースを参照したところ、trueにしておくと（既定値はtrue）BleGamepad.press()などの値設定メンバを実行した時に随時データを送信しています。
逆に、値を全部設定してから一括でデータを送りたい場合は、falseに設定し、全部のデータをセットしおわった後に BleGamepad.sendReport() を実行すれば良いようです。

``` main.cpp

void setup()
{
  BleGamepadConfiguration config;
  config.setAutoReport(false);    // <----
  bleGamepad.begin(&config);
  ...
}

void loop()
{
  ...
  bleGamepad.release(BUTTON_3);
  bleGamepad.press(BUTTON_4);
  bleGamepad.sendReport();      // <----
}
```

### AxesMin/Max
AxesMin/Maxはそれぞれ、軸の値の最小値、最大値を指定します（-32768～32767）。
デフォルトは0,32767なので、軸にX,Y=(0,0)を入れると中央ではなくて、左上を入力していることになります。
この場合、(16383,16383)が中央になります。
たとえば、Min,Max = (-100,100)などに設定すれば、０が中央値になります。

### Vid/Pid
それぞれベンダーID、プロダクトIDになります。

### ControllerType
CONTROLLER_TYPE_JOYSTICK,CONTROLLER_TYPE_GAMEPAD,CONTROLLER_TYPE_MULTI_AXIS が指定できます。既定値はGAMEPADです。
試したところ、JOYSTICKでは特に変化なし（デバイスを表すアイコンが変わりました）、MULTI_AXISはゲームコントローラとして認識しませんでした。