PS5のアクセスコントローラー(Access Controller) を借りたので、RPi Zero 2W で試してみる。

ちなみに、PS5 はもっていない。GTA6が出たら買う予定。

RPi Zero2 W setup

アプリでおまかせ。

RPi Zero2 用のno desktop (RASPBERRY PI OS LITE(64BIT))を 32GBのmicro SDカードに書き込んで、boot。

SSH server をあげて、Mac のTerminalから作業する。

BLE Pairing

アクセスコントローラー

PSロゴ と、PROFILE ボタンを同時押しすると、チカチカとブルーの光が面滅して、ペアリングモードになる。

RPi Zero2 W

  • Bluetooth 関連のsoftware をinstall
bash
sudo apt install -y bluetooth pi-bluetooth bluez bluez-tools
  • BLEを初期化
bash
sudo systemctl restart bluetooth
  • ペアリング

(アクセスコントローラーが点滅しているのを確認)

bash
 sudo bluetoothctl
 [bluetooth]# agent on
 [bluetooth]# default-agent
 [bluetooth]# scan on
 [CHG] Controller XX:5F:01:4A:AB:XX Discovering: yes
 ...
 [NEW] Device YY:18:49:A5:83:YY Access Controller
 ...

このController XX:5F:01:4A:AB:XX は、RPI Zero2 W本体のBLE。 YY:18:49:A5:83:YY が Access Controller 。紛らわしい。。。

connect する。

bash
[bluetooth]# pair YY:18:49:A5:83:YY
[bluetooth]# trust  Y:18:49:A5:83:YY
[bluetooth]# connect YY:18:49:A5:83:YY

確認&command quit

bash
[bluetooth]# devices Paired
Device YY:18:49:A5:83:YY Access Controller
[bluetooth]# quit

再接続

bluetoothctl をrestartしたり、RPi Zero2 Wをreboot したあとは、一度、 `remove YY:18:49:A5:83:YY` として、ペアリングをやり直した方が早い。

動作確認

python のevdev install

単純なpip installでは、最近のRPi OSでは `システム壊すんじゃない` ポリシーのおかげで、install できない。 rootにいれるのなら、debian package にする。

bash
sudo apt-get install -y python3-evdev

sample の実行

以下のsample プログラムで、ボタンやXYZセンサの入力をチェックする。

ps_access_controller_check.py · Gistpython
import evdev
from evdev import categorize, ecodes
import sys

def main():
    # 利用可能なデバイスを一覧表示
    devices = [evdev.InputDevice(path) for path in evdev.list_devices()]
    if not devices:
        print("利用可能なデバイスが見つかりません。")
        sys.exit(1)

    print("利用可能なデバイス:")
    for i, device in enumerate(devices):
        print(f"{i}: {device.path}, {device.name}, {device.phys}")

    # ユーザーにデバイスを選択させる
    device_index = int(input("使用するデバイスの番号を入力してください: "))
    device = devices[device_index]

    print(f"選択されたデバイス: {device.path}, {device.name}, {device.phys}")
    print("デバイスの機能:")
    for code, type_list in device.capabilities(verbose=True).items():
        print("-"*80)
        print(f"  {code}:")
        for t in type_list:
            if isinstance(t, tuple):
                print(f"    {t[0]}, {t[1]}")
            else:
                print(f"    {t}")

    print("-"*80)
    print(f"デバイス {device.name} からの入力を監視しています...")

    alreays = []
    try:
        for event in device.read_loop():
            if event.type == ecodes.EV_KEY:
                key_event = categorize(event)
                if key_event.keystate == key_event.key_up:
                    print(f"ボタン {key_event.keycode} が押されました")
            elif event.type == ecodes.EV_ABS:
                absevent = categorize(event)
                if ecodes.ABS[absevent.event.code] in alreays:
                    continue
                alreays.append(ecodes.ABS[absevent.event.code])
                print(f"軸 {ecodes.ABS[absevent.event.code]} の値: {absevent.event.value}")

    except IOError as e:
        print(f"デバイスからの読み取り中にエラーが発生しました: {e}")
    except KeyboardInterrupt:
        print("プログラムが中断されました")
    finally:
        device.close()

if __name__ == "__main__":
    main()

実行結果

bash
$ python sample.py
利用可能なデバイス:
0: /dev/input/event0, vc4-hdmi, vc4-hdmi/input0
1: /dev/input/event1, vc4-hdmi HDMI Jack, ALSA
2: /dev/input/event2, Access Controller, YY:5f:01:4a:ab:YY
使用するデバイスの番号を入力してください: 2
選択されたデバイス: /dev/input/event2, Access Controller, YY:5f:01:4a:ab:YY
デバイスの機能:
--------------------------------------------------------------------------------
  ('EV_SYN', 0):
    SYN_REPORT, 0
    SYN_CONFIG, 1
    SYN_DROPPED, 3
    ?, 4
--------------------------------------------------------------------------------
  ('EV_KEY', 1):
    ['BTN_A', 'BTN_GAMEPAD', 'BTN_SOUTH'], 304
    ['BTN_B', 'BTN_EAST'], 305
    BTN_C, 306
    ['BTN_NORTH', 'BTN_X'], 307
    ['BTN_WEST', 'BTN_Y'], 308
    BTN_Z, 309
    BTN_TL, 310
    BTN_TR, 311
    BTN_TL2, 312
    BTN_TR2, 313
    BTN_SELECT, 314
    BTN_START, 315
    BTN_MODE, 316
    BTN_THUMBL, 317
--------------------------------------------------------------------------------
  ('EV_ABS', 3):
    ('ABS_X', 0), val 135, min 0, max 255, fuzz 0, flat 15, res 0
    ('ABS_Y', 1), val 132, min 0, max 255, fuzz 0, flat 15, res 0
    ('ABS_Z', 2), val 128, min 0, max 255, fuzz 0, flat 15, res 0
    ('ABS_RX', 3), val 0, min 0, max 255, fuzz 0, flat 15, res 0
    ('ABS_RY', 4), val 0, min 0, max 255, fuzz 0, flat 15, res 0
    ('ABS_RZ', 5), val 128, min 0, max 255, fuzz 0, flat 15, res 0
    ('ABS_HAT0X', 16), val 0, min -1, max 1, fuzz 0, flat 0, res 0
    ('ABS_HAT0Y', 17), val 0, min -1, max 1, fuzz 0, flat 0, res 0
--------------------------------------------------------------------------------
  ('EV_MSC', 4):
    MSC_SCAN, 4
--------------------------------------------------------------------------------
デバイス Access Controller からの入力を監視しています...
軸 ABS_Y の値: 132
ボタン ['BTN_A', 'BTN_GAMEPAD', 'BTN_SOUTH'] が押されました
ボタン BTN_THUMBL が押されました

おまけ

このままevdevを使っても、アクセスコントローラーのボタンの設定を変えることはできない。PS5本体がなければ、どのボタンにイベントを設定するかはdefaultのまま。

ほかにソフトがないか探したら、Bleakというパッケージがあったが、アクセスコントローラを検知できず。。

モジュール構造図をClaude.ai に出してもらって、諦めた。

evdev とbleakの関係

evdev とkernel