USB HIDデバイスが125Hz(8ms)でしか動かない
PlatformIOでarduino-pico、いわゆるEarlephilhower版環境でRP2040-Zeroを使っていたときのことです。
パソコンにUSB接続して使うGamePadを作っていたところ、どう頑張っても125Hzでしかプログラムが動かなくなりました。
ボトルネックを調べたところJoystick.send_now();がどうも8ms処理をブロックするようだったので、対処法を調べました。
ググっても日本語の記事(というか英語の記事も)無かったので、ここに対処法を残しておきます。
USB HID のポールレートは8ms固定になっている
そもそも8msしかでないのは仕様です。
RP2040でのUSB HIDというのはソフトウェアでの処理になっていて、このポールレート(パソコンにHIDの処理を伝える間隔)が早くなれば早くなるほどRP2040のCPU負荷が高くなります。
しかし8msというのも遅すぎるので、これを1msに変えてしまいましょう。
参考までに、PHOENIXWANというコントローラーは1000Hzで入力が入るようです。
usb_hid_poll_intervalを変更する
該当環境では「usb_hid_poll_interval」という名前の変数が「弱い変数」としてグローバルに定義されています。
この弱い変数というのは、あとから定義した方が優先される変数のことで、setupやらloopやらを書いているファイル内でグローバル変数として再定義したとき、そっちの値が優先されます。
setup()などを書いたファイルと同じファイルにグローバル変数として以下の変数を定義します。
// USBのポールレートを1msに設定
int usb_hid_poll_interval = 1;
それだけでHIDのポールレートが1msになります。
従ってポールレートを1msにした状態でスケッチを書くなら、テンプレは以下の通りになります。
// USBのポールレートを1msに設定(グローバル変数として定義するだけで初期設定を上書きできる)
int usb_hid_poll_interval = 1;
void setup() {
}
void loop() {
}
全体のポールレートが変わるので、Joystickだけでなく、Keyboardなども変わると思います。
RaspberryPiPicoをつかって自作キーボードを作ってる人にも多分影響するかな?
QMK Firmwareとかmbed_picoでどうなってるかは知らないけれど・・・
だれかの役に立ちますように。。。
参考文献
Increase HID Joystick Polling Rate · Issue #1769 · earlephilhower/arduino-pico
https://github.com/earlephilhower/arduino-pico/issues/1769
Allow changing USB HID poll rate by earlephilhower · Pull Request #1771 · earlephilhower/arduino-pico · GitHub
https://github.com/earlephilhower/arduino-pico/pull/1771/commits/0d3d52ab55efdc764b03e0fd7ab8d4165598b2d6
Issueで書き足されたドキュメントはこちら:
https://github.com/earlephilhower/arduino-pico/blob/master/docs/usb.rst