この話の続きのようなもの。

ざっくりおさらいすると、「DDCI01ではUIAPduinoを使っており、USBの制御はソフトウェアであるためLow Speedであり、ポーリング間隔bIntervalは10ms。そのため、高速打鍵になると遅延(ジッタ)が無視できなくなる。」ということ。
では、そのジッタは実際どのくらいなのか、測ってみようというのが今回のテーマ。
構成としては、DDCI01の入力にエレキーをつないで等間隔で打鍵する。エレキーにはYACKを使う(実態はFDBM02)。この構成でWindowsでオンとオフのタイミングを計測する(オンの時間とオフの時間の長さ)。
早速結果。まずは、概ね10WPM程度(エレキーがマイコン内蔵のクロックなので速度は正確性には欠ける)。

計測結果から、短点とスペースの長さに差があることがわかるが、それはそれとして、どちらもジッタは8.5msくらい。特に短点側(青)の方がわかりやすくて、8.5msの間隔で二つの山ができている。これがbIntervalによる読込みの揺らぎなのだろう。
以下、15, 20, 25, 30, 50 WPMで同様に計測したもの。





いずれの測定結果でもジッタはだいたい8.5ms。bIntervalが10msの場合、Windowsでの実際のポーリング間隔は8msになるようだ。以下、Claudeによる解説。
実際のポーリング間隔は 8ms(約125Hz)になるのが一般的です。
決まり方
- bInterval の解釈: Low Speed / Full Speed の割り込みエンドポイントでは、bInterval は 1ms フレーム単位の値で、10 なら「10ms 以下の間隔でポーリングしてほしい」という意味です。仕様上 bInterval は最大間隔の指定であり、ホストはそれより短い間隔でポーリングしても構いません。
- ホストコントローラドライバによる丸め: Windows 11 は多くの環境で xHCI(USBXHCI.sys)を使います。スケジューラは周期を 2 のべき乗(1, 2, 4, 8, 16, 32…ms)で管理するため、LS/FS の bInterval は**「指定値以下で最大の 2 のべき乗」に切り捨て**られます。10ms なら 8ms です(xHCI のエンドポイントコンテキストでは Interval = 2^n × 125µs で表現されるため、同じ理由で 80µframe → 64µframe = 8ms になります)。EHCI/OHCI/UHCI でも周期スケジュールは 2 のべき乗なので同様です。
- 実例: Low Speed のマウスで bInterval=10 のものが 125Hz(8ms)で動作する、というのは広く知られた挙動です。bInterval=8 でも 8ms、bInterval=16 なら 16ms になります。
補足
- 途中にハブがある場合: LS デバイスをハブ経由で接続すると、ハブのトランザクショントランスレータ(TT)経由のスプリットトランザクションになり、周期は同じでもタイミングのジッタが増えます。
- HID クラスドライバ: hidusb は通常ディスクリプタの値をそのまま使うので、レジストリ等で LS デバイスの間隔を変えるのは基本的にできません。
- デバイス側の NAK: ポーリングされても、デバイスが送るデータがなければ NAK を返すので、データが上がってくるのはその 8ms 周期のタイミングです。
Microsoft の公式ドキュメントに「10ms → 8ms」と明記された箇所があるわけではなく、上記は xHCI 仕様と実測の挙動に基づく説明です。正確に確認したい場合は、USBPcap + Wireshark や USBlyzer などで IN トークンの間隔を計測すると確実です。
余談になるが、どうやら、YACKではスペースの時間がやや長めに設定されているみたい。意図的なのかそうでないのかは不明だけれど。
以前の記事に入れていた速度とジッタの関係の表を8.5msで作り直した。やはり、ジッタが10%を超えてくる15 WPMくらいがあまり違和感なく打てる限界だろうな。
| 速度 | 短点 | 短点の長さに対する8.5msの割合 |
|---|---|---|
| 10 WPM | 120 ms | 7.1% |
| 15 WPM | 80 ms | 10.6% |
| 20 WPM | 60 ms | 14.2% |
| 25 WPM | 48 ms | 17.7% |
| 30 WPM | 40 ms | 21.3% |
| 35 WPM | 34.3 ms | 24.8% |
| 40 WPM | 30 ms | 28.3% |
| 45 WPM | 26.7 ms | 31.8% |
| 50 WPM | 24 ms | 35.4% |
最後に、ジッタ計測ツールはこちら。Geminiで作った。使い方などはファイルの冒頭のコメントを参照。ZIPの中身は、Pyhtonのコードが一つだけ。


コメント