ESP32+PlatformIO+PS4Controller



![SS 192.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/a41cd967-f549-8677-1efa-2e99bf69518d.png) ちょい沼なれど解決方法がフォーラムにあり

## やること
ESP32+PlatformIOの組み合わせでPS4Controllerを使う時の注意点です。
要点のみメモ。

## 動作環境
- ESP32devkitC
- PS4純正コントローラー
- PlatformIO(ESPのボードバージョン設定は3.3.2)

## PlatformIOでDLしたライブラリを使うには

作成したプロジェクトのlibディレクトリにライブラリを入れます。
ツリー構造は、

PlatformIO
└Projects
　├＜該当の自作プロジェクト＞
　　├lib
　　　└＜DLしたライブラリのディレクトリ＞
　　　　└＜src＞
　　　　　└＜.cppファイル、.hファイル＞

となるようにします。
DLしたライブラリによっては解凍後にsrcが第一階層にない場合もあるので、
libとsrcの階層関係が上記になるようにライブラリの親フォルダを外すなど、適宜調整します。
PlatformIOのmain.cppにインクルードした際、インクルード文にエラーの赤線がでていなければライブラリ導入の第一段階は成功です。

また、DLしたライブラリはそのままではPlatformIOに対応していない場合があります。
その場合はエラーを修正していく必要があります。

## PS4Controller.h を導入する

#### ダウンロードとインストール

https://github.com/aed3/PS4-esp32

の「CODE」ボタンよりzipファイルをDLして解答します。
「PS4-esp32-master」のフォルダを該当プロジェクトのlibディレクトリ内にコピーします。

#### コードの修正

https://forum.arduino.cc/t/error-compiling-for-board-esp32-dev-module-with-ps4controller-library/933405

を参考に、
「src/ps4_spp.c」のコードを下記のものに差し替えます。

```c++:ESP32系
#include "esp_bt.h"
#include "esp_bt_device.h"
#include "esp_bt_main.h"
#include "esp_gap_bt_api.h"
#include "esp_log.h"
#include "esp_spp_api.h"
#include "ps4.h"
#include "ps4_int.h"

#define PS4_TAG "PS4_SPP"

/********************************************************************************/
/*              L O C A L    F U N C T I O N     P R O T O T Y P E S            */
/********************************************************************************/
static void sppCallback(esp_spp_cb_event_t event, esp_spp_cb_param_t* param);

/********************************************************************************/
/*                      P U B L I C    F U N C T I O N S                        */
/********************************************************************************/

/*******************************************************************************
**
** Function         sppInit
**
** Description      Initialise the SPP server to allow to be connected to
**
** Returns          void
**
*******************************************************************************/
void sppInit() {
  esp_err_t ret;

#ifndef ARDUINO_ARCH_ESP32
  esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
  if ((ret = esp_bt_controller_init(&bt_cfg)) != ESP_OK) {
    ESP_LOGE(PS4_TAG, "%s initialize controller failed: %s\n", __func__, esp_err_to_name(ret));
    return;
  }

  if ((ret = esp_bt_controller_enable(BT_MODE)) != ESP_OK) {
    ESP_LOGE(PS4_TAG, "%s enable controller failed: %s\n", __func__, esp_err_to_name(ret));
    return;
  }

  if ((ret = esp_bluedroid_init()) != ESP_OK) {
    ESP_LOGE(PS4_TAG, "%s initialize bluedroid failed: %s\n", __func__, esp_err_to_name(ret));
    return;
  }

  if ((ret = esp_bluedroid_enable()) != ESP_OK) {
    ESP_LOGE(PS4_TAG, "%s enable bluedroid failed: %s\n", __func__, esp_err_to_name(ret));
    return;
  }
#endif

  if ((ret = esp_spp_register_callback(sppCallback)) != ESP_OK) {
    ESP_LOGE(PS4_TAG, "%s spp register failed: %s\n", __func__, esp_err_to_name(ret));
    return;
  }

  if ((ret = esp_spp_init(ESP_SPP_MODE_CB)) != ESP_OK) {
    ESP_LOGE(PS4_TAG, "%s spp init failed: %s\n", __func__, esp_err_to_name(ret));
    return;
  }
}

/********************************************************************************/
/*                      L O C A L    F U N C T I O N S                          */
/********************************************************************************/

/*******************************************************************************
**
** Function         sppCallback
**
** Description      Callback for SPP events, only used for the init event to
**                  configure the SPP server
**
** Returns          void
**
*******************************************************************************/
static void sppCallback(esp_spp_cb_event_t event, esp_spp_cb_param_t* param) {
  if (event == ESP_SPP_INIT_EVT) {
    ESP_LOGI(PS4_TAG, "ESP_SPP_INIT_EVT");
    esp_bt_dev_set_device_name("ESP Host");

//#if CONFIG_IDF_COMPATIBILITY >= IDF_COMPATIBILITY_MASTER_D9CE0BB
//    esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_NON_DISCOVERABLE);
//#elif CONFIG_IDF_COMPATIBILITY >= IDF_COMPATIBILITY_MASTER_21AF1D7
    esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE);
//#endif

    esp_spp_start_srv(ESP_SPP_SEC_NONE, ESP_SPP_ROLE_SLAVE, 0, "ESP SERVER");
  }
}
```
ライブラリのインストールについて、自分の環境ではこれでうまくいきました。
ESP32のバージョンなどによっては、
>esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_NON_DISCOVERABLE);

のコメントアウトをはずし、
>esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE);

をコメントアウトすることでうまくビルドできることもあるようです。
フォーラムには追加の修正についての記事が続いていますので、うまく動かない場合は試してみてください。

# 動かしてみる

PS4コントローラーの設定は導入後の具体的な使い方については下記の記事が参考になります。

https://qiita.com/Geek493/items/8402ad875b88822e75ab