トラブル
Arduino IDEで、Bluepad32 ボードパッケージをインストールし、ボード選択で esp32_bluepad32 > M5Stack-Core-ESP32 を選択してスケッチ例の ESP32_Bluepad32 > Controller をビルド&書き込みして動作確認できた。
ところが、スケッチ例 M5Stack > Basics > Display をビルドするとエラーが発生する。
c:\Users\***\Documents\Arduino\libraries\M5Stack\src\utility\Power.cpp:10:10: fatal error: esp_bt_main.h: No such file or directory #include <esp_bt_main.h> ^~~~~~~~~~~~~~~ compilation terminated.
原因
M5StackのボードパッケージとBluepad32とでは使用しているBluetoothプロトコルスタックが異なる。
- M5Stack : Bluedroid
- Bluepad32 : btstack
そのためヘッダファイルおよびAPIが異なる。上記のエラーは、POWER::powerOFF() で esp_bluedroid_disable() を呼び出すために esp_bt_main.h をインクルードしているために発生している。
修正
Arduino/libraries/M5Stack/src/utility/Power.cpp を下記のように修正すればビルドは通る。だたし、esp_bluedroid_disable() の代わりになにか処理が必要な気がする。
#if CONFIG_BLUEDROID_ENABLED #include <esp_bt_main.h> #endif
// stop bt #if CONFIG_BLUEDROID_ENABLED esp_bluedroid_disable(); #endif
動作確認用スケッチ
#include <Bluepad32.h> #include <M5Stack.h> ControllerPtr myControllers[BP32_MAX_GAMEPADS]; TFT_eSprite sprite = TFT_eSprite(&M5.Lcd); // スプライト作成 void onConnectedController(ControllerPtr ctl) { bool foundEmptySlot = false; for (int i = 0; i < BP32_MAX_GAMEPADS; i++) { if (myControllers[i] == nullptr) { Serial.printf("CALLBACK: Controller is connected, index=%d\n", i); ControllerProperties properties = ctl->getProperties(); Serial.printf("Controller model: %s, VID=0x%04x, PID=0x%04x\n", ctl->getModelName().c_str(), properties.vendor_id, properties.product_id); myControllers[i] = ctl; foundEmptySlot = true; break; } } if (!foundEmptySlot) { Serial.println("CALLBACK: Controller connected, but could not found empty slot"); } } void onDisconnectedController(ControllerPtr ctl) { bool foundController = false; for (int i = 0; i < BP32_MAX_GAMEPADS; i++) { if (myControllers[i] == ctl) { Serial.printf("CALLBACK: Controller disconnected from index=%d\n", i); myControllers[i] = nullptr; foundController = true; break; } } if (!foundController) { Serial.println("CALLBACK: Controller disconnected, but not found in myControllers"); } } void processGamepad(ControllerPtr ctl) { sprite.fillScreen(BLACK); sprite.setCursor(10, 30); sprite.printf("DPad: 0x%02x", ctl->dpad()); sprite.setCursor(10, 60); sprite.printf("Btn: 0x%04x", ctl->buttons()); sprite.setCursor(10, 90); sprite.printf("St-L: %4d, %4d", ctl->axisX(), ctl->axisY()); sprite.setCursor(10, 120); sprite.printf("St-R: %4d, %4d", ctl->axisRX(), ctl->axisRY()); sprite.setCursor(10, 150); sprite.printf("L2:%4d R2:%4d", ctl->brake(), ctl->throttle()); sprite.pushSprite(0, 0); } void processControllers() { for (auto myController : myControllers) { if (myController && myController->isConnected() && myController->hasData()) { if (myController->isGamepad()) { processGamepad(myController); }else{ Serial.println("Unsupported controller"); } } } } void setup() { M5.begin(); M5.Power.begin(); pinMode(25, OUTPUT); digitalWrite(25, LOW); // アンプを無効化(スピーカーOFF) M5.Lcd.fillScreen(BLACK); sprite.setColorDepth(8); // 色深度を8ビットに設定(メモリ節約) sprite.createSprite(320, 240); // スプライトのサイズを画面サイズに設定 sprite.setTextColor(WHITE, BLACK); sprite.setTextSize(3); Serial.printf("Firmware: %s\n", BP32.firmwareVersion()); const uint8_t* addr = BP32.localBdAddress(); Serial.printf("BD Addr: %2X:%2X:%2X:%2X:%2X:%2X\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); BP32.setup(&onConnectedController, &onDisconnectedController); BP32.forgetBluetoothKeys(); BP32.enableVirtualDevice(false); } void loop() { bool dataUpdated = BP32.update(); if (dataUpdated) processControllers(); delay(150); }
PlatformIO
PlatformIOで Arduino + Bluepad32 なプロジェクトもテンプレートが提供されている。
ただ、そこまでして Bluepad32 を使うかは疑問。当方では動作確認していない。
参考
M5StickCでBluepad32を使い画面表示をしている例はある。
gijin77.blog.jp