StampFlyをDualSenseで操作するやつ

M5Stack社から発売された、StampFlyを購入しました。が、それを操作するAtom JoyStickが品切れで買えませんでした。

そこで、その代用としてPlayStation5のコントローラである「DualSense」を使えないかしら、というお話です。

最終的に、こんな感じになっています。
(※音量注意)

ただし今回のやり方は、本家のコントローラであるAtom JoyStickに比べ、次のようなデメリットがあります。

【デメリット】
1. 遅延増
 もともと、Atom JoyStickにはメインマイコンとしてAtomS3が搭載されており
  (JoyStick等の入力まとめ用)STM32F030 -[I2C]-> AtomS3 -[ESP NOW]-> StampFly
 といった流れの通信となっています。

 一方、今回の接続方法は
  DualSense -[Bluetooth]-> M5Stamp Pico -[I2C]-> AtomS3 -[ESP NOW]-> StampFly
 となっており、前半のステップ分、遅延が増えます。

2. 分解能が低い
 DualSenseから取得できるアナログスティックの分解能は8bitです。
 Atom JoyStick内では12bitで処理しているため、それと比べると低いです。

3. 充電機能がない
 Atom JoyStickには、使用するバッテリーを充電する機能がついています。

もちろん、DualSenseのほうがボタンが多いなどのメリットもありますが、基本的にはAtom JoyStickの購入をお勧めします。

HW接続

まずは、M5Stamp PicoとAtomS3を入手します。

私の場合、M5シリーズをスイッチサイエンスさんで購入することが多いです。
(M5Stamp Picoはこちら、AtomS3はこちら)

また、M5Stamp Picoの注意点として、USB-シリアル変換器が搭載されていません。
このため、ファームを書き込むには別途、「ファーム焼き機」が必要です。
(ファーム焼き機とのセットはこちら)

入手できましたら、M5Stamp PicoとAtomS3を次のように接続します。

[AtomS3] [M5Stamp Pico] function
G39 G22 SCL(for I2C)
G38 G25 SDA(for I2C)
5v 5v Power
GND GND Power

ちょうど、M5Stamp Picoの後ろのピンと、AtomS3を直結する感じです。

また、電源はAtomS3にモバイルバッテリーなどを接続することで確保します。
上記で接続した5vピン経由で、M5Stamp Picoにも電圧が供給されます。

それと、SDAとSCLは4.7kΩくらいで3.3vにプルアップしたほうが良いかもしれません。
(本家のAtom JoyStickはしている。回路図はこちらの右下のほう。今回はM5Stamp Picoの内部プルアップに期待して端折りました。波形は確認してません…)

ソースコード

M5Stamp Pico

まずは、M5Stamp Pico側のコードについて。

DualSenseと通信するライブラリとして、以下を使わせて頂きました。
https://github.com/rodneybakiskan/ps5-esp32

このライブラリは、DualSenseと「Bluetooth Classic」による通信を行います。

ここで注意なのが、AtomS3を含む最近のESP32シリーズはこのBluetooth Classicに非対応です。
一方、M5Stamp Picoはこれに対応しているため、DualSenseとAtomS3の間にかませる構成としました。

【補足】各ESP32シリーズのBluetooth Classic対応状況は、@tnkmasayukiさんの
ツイートがとても分かりやすいです。

さて、このライブラリを用いた
「DualSenseと通信 ⇒ ボタンやスティック情報を取得 ⇒ I2CでAtomS3へ送信」
の実装はこんな感じに。

ここで、使用する際の注意点を2点ほど。

【注意点】
・9行目のとおり、DualSenseのMACアドレスを設定しておく必要あり。
 このアドレスが不明な場合は、試しに一度パソコン等とDualSenseをBluetoothペアリング
 することで、プロパティでMACアドレスを知ることが可能。

・最初の一回だけ、DualSenseとM5StampPico間でBluetoothペアリング操作をする必要あり。
 DualSenseのほうをペアリングモードに入れれば、M5Stamp Picoが勝手に認識してくれる。

AtomS3

次に、AtomS3側のコードについて。

元々は、AtomS3側のコードをいじらず(=Atom JoyStick用ファームを焼くだけで)実現したかったのですが、どうもうまくいかず…。
(前述の通り、元々AtomS3はSTM32F030とI2C通信しているので、それをM5Stamp Picoに置き換えるだけでいけるかしら、と思ったのですが、うまくいかず断念…。)

なので、若干AtomS3側のI2C通信周りのコードをいじっています。

実際に触らせて頂いた元のコードはこちらです。

【変更内容と懺悔】
I2Cについて、データを16byte一括して受信する形に変更しました。

また、データ内容が固定であるため、Wire1.requestFrom()前の読み出しレジスタアドレス指定処理を端折りました。(合わせて、前述のM5Stamp Pico側のonRequest()処理も実行していません)

こうしないと、通信データ内容がずれる謎の現象に悩まされ…。M5Stamp Pico側のDualSense処理が重いから?原因不明…。とても行儀の悪い乗り切り方ですみません…。

(変更箇所に watako modified のコメントを入れています)

補足: ビルド環境について

超スーパーざっくりですが、以下の感じです。

M5Stamp Pico

開発環境: ArduinoIDE(2.3.2)
ボードマネージャ: Arduino core for the ESP32(v3.0.4)
マイコンの種類: ESP32 PICO-D4を選択

AtomS3

開発環境: vscode + PlatformIO
 (導入方法はこちらの記事がわかりやすかったです。ありがとうございます!)
StampFlyControllerプロジェクトのインポート:
 githubから取得したディレクトリ群にて、PlatformIOのPick a folderで以下に相当する場所を指定。
 https://github.com/m5stack/Atom-JoyStick/tree/main/examples/StampFlyController
 (platformio.ini が存在するディレクトリ)

おわりに

もう少しスマートに行けるかとおもいきや、なんだか泥沼にはまって無理やり乗り切った感じです…。
少しでもご参考になれば幸いです。

そして、せっかくコントローラを作ったのに、StampFlyのバッテリー切れで遊べませんでしたとさ。
(充電できないからね。ちゃんちゃん)