2026年3月1日日曜日

ESP32 - Bluepad32 PS4コントローラー

Bluetooth (Classic / BLE)対応のBluepad32ライブラリー使用して、ESP32NodeMCU開発ボードと純正PS4コントローラー操作をシリアルモニタに表示しました。
前回記事【PS4コントローラーとESP32 接続・操作】PS4Controllerライブラリーは by Espressif Systems バージョン1.0.6で動作(バージョン3.2.0→コンパイルエラー)Bluepad32ライブラリーはボードマネージャ【ESP32 Arduino + Bluepad32】【ESP32 Dev Module】により動作します。ただし、どちらもESP32C3・ESP32S3は動作しません。( Bluepad32 によるXboxコントローラーは動作します)



参考サイト
●ESP32-C3をXBOXコントローラーから操作する
●M5Stack / ESP32とゲームコントローラの接続いろいろ

シリアルモニタ
参考サイト【https://tsuzureya.net/esp32-c3-with-xbox-controller/】ジョイスティック部分のスケッチを変更しました。
【A】ボタンと【右スティック】を操作した時のシリアルモニタ














純正PS4コントローラー
PSボタンを押してペアリング














PS4コントローラー
【MODEL CUH-ZCT2J】
技適製品





ESP-32S 開発ボード
●ESP32 NodeMCU開発ボード2.4GHz WiFi + Bluetoothデュアルモード(技適製品)
アマゾン購入






ボードマネージャ
追加のボードマネージャー
【https://raw.githubusercontent.com/ricardoquesada/esp32-arduino-lib-builder/master/bluepad32_files/package_esp32_bluepad32_index.json】

【ツール】【ボード】【ボードマネージャ】【bluepad32】
















ボードマネージャ【ESP32 Arduino + Bluepad32】
ボード【ESP32 Dev Module】選択

プログラム Arduino IDE  【ESP32 Arduino + Bluepad32】【ESP32 Dev Module】
#include <Bluepad32.h>
ControllerPtr myControllers[BP32_MAX_GAMEPADS];

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) {
 //操作ボタン
 if (ctl->a()) Serial.printf("A\n");
 if (ctl->b()) Serial.printf("B\n");
 if (ctl->x()) Serial.printf("X\n");
 if (ctl->y()) Serial.printf("Y\n");
 if (ctl->l1()) Serial.printf("L‾\n"); //上左ボタン
 if (ctl->r1()) Serial.printf("R‾\n"); //上右ボタン
 if (ctl->l2()) Serial.printf("L_\n"); //下左ボタン
 if (ctl->r2()) Serial.printf("R_\n"); //下右ボタン

 //方向パッド
 if (ctl->dpad()& DPAD_UP) Serial.printf("UP\n");
 if (ctl->dpad()& DPAD_DOWN) Serial.printf("DOWN\n");
 if (ctl->dpad()& DPAD_LEFT) Serial.printf("LEFT\n");
 if (ctl->dpad()& DPAD_RIGHT) Serial.printf("RIGHT\n");

 //他ボタン
 if (ctl->miscButtons()& MISC_BUTTON_SYSTEM) Serial.printf("XBOX\n");
 if (ctl->miscButtons()& MISC_BUTTON_BACK) Serial.printf("BACK\n");
 if (ctl->miscButtons()& MISC_BUTTON_HOME) Serial.printf("HOME\n");

 //左右ジョイスティック
 /*
 Serial.printf("L:(%4d,%4d) R:(%4d,%4d) TRIG:(%4d,%4d)\n",
 ctl->axisX(), ctl->axisY(),
 ctl->axisRX(), ctl->axisRY(),
 ctl->brake(), ctl->throttle());
 Serial.printf("X:(%3d)\n",ctl->axisX());
 */

 int RX = ctl->axisRX();  //右ジョイスティック
 Serial.print("RX:");  
 Serial.println(RX);  //左 -512 ~ 511 右
 int RY = ctl->axisRY();
 Serial.print("RY:");  //上 -512 ~ 511 下
 Serial.println(RY);  
 int LX = ctl->axisX();  //左ジョイスティック
 Serial.print("LX:");
 Serial.println(LX);  //左 -512 ~ 511 右
 int LY = ctl->axisY();
 Serial.print("LY:");
 Serial.println(LY);  //上 -512 ~ 511 下
}

void processControllers() {
 for (auto myController : myControllers) {
  if (myController && myController->isConnected() && myController->hasData()) {
   if (myController->isGamepad()) {
    processGamepad(myController);
   }
   else {
    Serial.println("Unsupported controller");
   }
  }
 }
}

// Arduino setup function. Runs in CPU 1
void setup() {
 Serial.begin(115200);
 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]);

 // Setup the Bluepad32 callbacks
 BP32.setup(&onConnectedController, &onDisconnectedController);
 BP32.forgetBluetoothKeys();
}

// Arduino loop function. Runs in CPU 1.
void loop() {
 bool dataUpdated = BP32.update();
 if (dataUpdated) processControllers();
 delay(10);
}

0 件のコメント:

コメントを投稿

WaveGene - 多機能 高精度 テスト信号発生ソフト

 WaveGene - 多機能 高精度 テスト信号発生ソフトを使ってみました。  ●サイン波、矩形波、三角波、ノコギリ波、パルス列、パルス列(+-)、ホワイトノイズ、ピンクノイズ、M系列ノイズ(MLS) ●変調(AM、DSB、FM、PM、PWM) ●スイープ(周波数、振幅、位相)...