ゲーム機のコントローラでマイコンを制御してみたいと思い立ち色々と調べたところ、割と簡単にesp32でPS3のコントローラの値を取得できることがわかったので今回はその備忘録になります。
また今回の開発環境はWindowsのみになるので注意してください。
では、始めます。
0:esp32とPS3コントローラの準備
今回esp32のマイコンとしてAtom Liteを使用しました(※他のesp32系のボードでは本記事のソースコードがそのままでは動かない可能性もあるので注意してください)。
また前提としてArduino IDEとesp32、Atomを扱える状態にまでしておく必要があります。
Atom Matrixの方ですが、過去に環境構築してサンプルを動かした記事があるのでそちらを参照してください。
PS3コントローラ(Bluetooth対応)とPS3コントローラと接続するUSBケーブルを準備します。
Bluetooth対応PS3コントローラは中古ショップなどで2000円しないぐらいで購入できると思います。
PS3はモバイルバッテリーなどからは充電できないようで、PCなどのUSBポートから充電するようにしてください。
1:本体のMACアドレスを取得する
まずはesp32とPS3をペアリングしなければBluetoothでの通信はできないので、esp32のMACアドレスを確認します。
以下のプログラムをAtom Liteに書き込みます。
・M5Atom_macadrs.ino
#include "M5Atom.h"
void setup() {
Serial.begin(115200);
Serial.println("-----------------------------");
uint8_t btmac[6];
esp_read_mac(btmac, ESP_MAC_BT);
Serial.printf("[Bluetooth] Mac Address = %02X:%02X:%02X:%02X:%02X:%02X\r\n", btmac[0], btmac[1], btmac[2], btmac[3], btmac[4], btmac[5]);
}
void loop() {
}
このスケッチを書き込んでからシリアルモニタを開いてAtom Liteのリセットボタンを押下すると、以下のようにMACアドレスが表示されるのでその値をメモ/コピーしておきます。
2:PS3コントローラにペアリングしたいMACアドレスを書き込む
PS3のコントローラのペアリングは、コントローラ側に予めペアリング先のMACアドレスを設定しておく必要があります。
まずは、PC側の書き込みツールをインストールします。
次のページを開きます。
赤枠部分をクリックします。
ダウンロード先を選択してクリックします。ここではUKを選択しました。
クリックするとダウンロードページが開き、数秒待つと自動的にexeファイルがダウンロードされます。
ダウンロードしたインストーラを起動し「Next」をクリックします。
ダウンロード先を指定して「Next」をクリックします。デフォルトのままで問題ないかと思います。
スタートメニューのショートカットもデフォルトのままで「Next」をクリックします。
設定確認の画面になるので「Install」をクリックしてインストールを開始します。
インストールが完了したら「Finish」をクリックします。
これで書き込むツールのインストールは完了です。
インストール後、PCとPS3コントローラをUSBケーブルで接続します。
その状態でWindowsの検索欄に「sixaxis」と入力して出てきた「SixaxisPairTool」を選択してツールを起動させます。
初回起動時には以下のようにドライバのインストールが始まる場合があるので、しばらく待ちます。
ドライバのインストール後、以下のような画面になるので「Change Master」と書かれている方に1で確認したMACアドレスを入力し「Update」ボタンをクリックします。
すると「Current Master」と「Change Master」の値が同じになります。
これでPS3コントローラへのMACアドレスの書き込みは完了になります。
3:Arduino IDEにPS3コントローラのライブラリをインストールする
次にArduino IDEにPS3コントローラのライブラリをインストールします。
以下のGithubページにアクセスします。
ページ右上にある「Code」をクリックし、出てきた中にある「Download ZIP」をクリックしてzipファイルをダウンロードします。
Arduino IDEを開いてメニューの「スケッチ」→「ライブラリをインクルード」→「ZIP形式のライブラリをインストール」を選択します。
先ほどダウンロードしたzipファイルを指定して「開く」をクリックします。
これでPS3コントローラをArduinoで扱えるようになりました。
4:Bluetoothのサンプル
準備ができたので、実際にBluetoothの通信ができるかを確認します。
Atom Liteに以下のスケッチを書き込みます。
※「Ps3.begin("xx:xx:xx:xx:xx:xx");」のところは各自のMACアドレスに適宜変更してください
・M5Atom_ps3con_test.ino
#include "M5Atom.h"
#include <Ps3Controller.h>
const int LED_BRIGHTNESS = 100;
uint8_t b_lx = 0, b_ly = 0, b_rx = 0, b_ry = 0;
void setup() {
M5.begin(true, false, true);
Ps3.begin("xx:xx:xx:xx:xx:xx");
Serial.begin(115200);
showMsgLed("Pairing Ready...", 255, 0, 0);
while (!Ps3.isConnected()){
delay(1000);
}
showMsgLed("Pairing OK", 0, 0, 255);
}
void loop() {
M5.update();
if (Ps3.data.button.start) { showMsgLed("start", 0xF0, 0xF8, 0xFF); }
if (Ps3.data.button.select){ showMsgLed("select", 0x99, 0x66, 0xCC); }
if (Ps3.data.button.l1) { showMsgLed("button L1", 0xFA, 0xEB, 0xD7); }
if (Ps3.data.button.l2) { showMsgLed("button L2", 0xFF, 0x7F, 0x50); }
if (Ps3.data.button.l3) { showMsgLed("analog L3 push", 0x64, 0x95, 0xED); }
if (Ps3.data.button.r1) { showMsgLed("button R1", 0x00, 0xFF, 0xFF); }
if (Ps3.data.button.r2) { showMsgLed("button R2", 0xFF, 0xF8, 0xDC); }
if (Ps3.data.button.r3) { showMsgLed("analog R3 push", 0x00, 0x00, 0x8B); }
if (Ps3.data.button.up) { showMsgLed("up", 0x7F, 0xFF, 0xD4); }
if (Ps3.data.button.right){ showMsgLed("right", 0xF0, 0xFF, 0xFF); }
if (Ps3.data.button.down) { showMsgLed("down", 0xF5, 0xF5, 0xDC); }
if (Ps3.data.button.left) { showMsgLed("left", 0xFF, 0xE4, 0xC4); }
if (Ps3.data.button.cross) { showMsgLed("cross", 0x8A, 0x2B, 0xE2); }
if (Ps3.data.button.square) { showMsgLed("square", 0xA5, 0x2A, 0x2A); }
if (Ps3.data.button.triangle){ showMsgLed("triangle", 0xDE, 0xB8, 0x87); }
if (Ps3.data.button.circle) { showMsgLed("circle", 0x5F, 0x9E, 0xA0); }
delay(100);
}
void showMsgLed(String s, uint8_t r, uint8_t g, uint8_t b) {
M5.dis.setBrightness(LED_BRIGHTNESS);
M5.dis.drawpix(0, getDispColor(r, g, b));
Serial.println(s);
}
CRGB getDispColor(uint8_t r, uint8_t g, uint8_t b) {
return (CRGB)((r << 16) | (g << 8) | b);
}
void showAnalog() {
uint8_t lx, ly, rx, ry;
lx = Ps3.data.analog.stick.lx;
ly = Ps3.data.analog.stick.ly;
rx = Ps3.data.analog.stick.rx;
ry = Ps3.data.analog.stick.ry;
if ((b_lx != lx) || (b_ly != ly) || (b_rx != rx) || (b_ry != ry)) {
Serial.print("LX=");
Serial.print(lx);
Serial.print(", LY=");
Serial.print(ly);
Serial.print(", RX=");
Serial.print(rx);
Serial.print(", RY=");
Serial.println(ry);
b_lx = lx;
b_ly = ly;
b_rx = rx;
b_ry = ry;
}
}
void showAccelerometer() {
Serial.print("SX=");
Serial.print(Ps3.data.sensor.accelerometer.x);
Serial.print(", SY=");
Serial.print(Ps3.data.sensor.accelerometer.y);
Serial.print(", SZ=");
Serial.println(Ps3.data.sensor.accelerometer.z);
}
上記スケッチをAtom Liteに書き込んだ後、Atom LiteのLEDが赤色に光ります。その状態でPS3の「PSボタン」を押してペアリングが成功するとAtom LiteのLEDが青色に変化します。
その状態でPS3コントローラの各ボタンを押すとLEDの色が変化します(中には光の強度の関係で似たような色に見えるものもあります)。
ちなみにArduino IDEのシリアルモニタを開いた状態で行うと、以下のようにどのボタンを押したかがわかるようにしています。
またvoid loop( )関数でコメントアウトしているshowAnalog( )、showAccelerometer( )のコメントアウトを外すと、アナログスティックの値とコントローラの加速度の値もシリアルモニタに表示できます。
以上がAtom LiteでPS3コントローラの値を取得する方法になります。
参考資料にあるページ様のソースコードを参考にしつつやりましたが、割と簡単にPS3コントローラとのBluetooth通信ができることがわかってよかったです。
今回はAtom LiteとPS3コントローラでやりましたが、ライブラリ的にはesp32となっているため、他のesp32系のマイコンボードでも同じように通信できると思います(未確認)。
また検証していませんが、以下のようにPS4コントローラ用ライブラリを公開している方もいるので、PS4コントローラでも同じようなことができるようです。
ゲーム機のコントローラをesp32で扱えるということは、簡単なラジコンみたいなものも作れそうなので楽しみが広がりますね。
・参考資料