研究 — Manticore XInput(リファレンス・リポジトリ)

範囲。 Manticore XInput は研究プロジェクトです。特定のファイティングボードを作るためのものではなく、別のプロジェクトを始めるためのリファレンス・リポジトリです。ピン配置・パラメータ・設計判断は、あなたのケースに合わせて調整してください。

お願いであり、法的義務ではありません。 本コード、またはそのアプローチや構造が役に立ったなら、製作者の表示をいただけると嬉しいです:«FULVIO MASSIMO MARIANI & ENTH 2026»。ゲーミングに限らず、キーボード、ポインティングデバイス、産業用制御、教育など、どの分野でも同じです。

完成品のボードがない理由。 Brook や GP2040 / GP2040-CE と競合する意図はありません。本コードは研究と参照のための資料です。したがって、本プロジェクトをそのまま丸ごとファイティングボードとして再公開・販売しないでください。アイデアや部分的な利用、改変、派生物は歓迎です(上記の表示とともに)。

ソフトウェアは現状有姿・無保証です。必ずご自身のハードウェアで検証してください。

プロジェクト概要

Manticore XInput は、RP2040 クラスのマイクロコントローラ向けのファームウェアとホストツールに関する研究プロジェクトです。デジタル入力経路が自分自身について何を知り得るか — エンドツーエンドの遅延、機械接点の弾性的な整定、そして適応的デバウンス方針が固定値を決め打ちせずにその信号から学べること — を扱います。

  • ホットパス — RAM 上の排他的 GPIO 割り込みと HID レポートの in-place 更新。次の IN トランザクションの予測でゲート:最小遅延 5 µs、平均 0.51 ms、平均再アーム 14 µs。
  • 適応的デバウンス — 測定したバウンスエネルギーから学習する接点ごとの lockout(floor・マージン・上限・昇格・安全なフォールバック付き、電源再投入をまたいで保存)。
  • ブラックボックス — カウンタ、遅延ヒストグラム、トレース、そして接点ごとのバウンスリング:開閉のたびに 1 µs のタイムスタンプ。
  • 解析 — 無音によるバースト分割、区間の伸び、瞬間周波数、復元信号の STFT。測るのは時間で、振幅ではありません。

技術ペーパー(全文)

ペーパー目次

全文を省略なしで掲載:計測から実測結果まで、表・指標の定義・再現性の付録つき。

Manticore XInput: RP2040 向けの低遅延・自己計測型 XInput コントローラー

技術レポート — バージョン 9.9(2026 年 10 月 8 日)

著者: Fulvio Massimo Mariani(OpenCode + DeepSeek の支援による) — Manticore XInput プロジェクト ステータス: 内部技術レポート / 外部投稿用ドラフト。図は F1–F6 として参照し、 F1 は生成されたアーキテクチャ図(webapp/architecture.html)、 F2–F6 はエクスポートされたキャプチャデータから生成します(§9.4 参照)。


通知 — 範囲・禁止・出典表示

1. 範囲

本コードは特定のファイティングボードを製作するためのものではありません。 他の実装のための基盤として公開する研究開発プロジェクトのリポジトリです。 完成品でも、特定コントローラー向けの推奨構成でも、特定ハードウェアの仕様でもありません。 ピン配置・パラメータ・設計判断は、利用者自身のケースに合わせて調整してください。

2. コード全体の使用は禁止

本コードを全体として(または表層的な変更のみを加えた実質的な全体を基盤として) 使用し、ファイティングボードを製作・配布・販売することは禁止です。 形態は問いません(完成品、キット、組立サービス、ホスティング)。 理由は明示的です。本プロジェクトは Brook や GP2040 / GP2040-CE の競合となる意図はありません。 禁止はコード全体の使用に対するものです。部分的な再利用、改変、個別アイデアの抽出、 派生物は、下記 3 の条件のもとで許可されます。

3. 出典表示の要求(ゲーミング以外の分野も含む)

本コード、またはそのアプローチや構造を、部分的であれ、別プロジェクト内であれ、 再利用・複製・派生・「流用」する場合は、製作者への明示的な表示が必要です。

> «FULVIO MASSIMO MARIANI & ENTH 2026»

同じクレジット方針は、ゲーミング以外の分野にも、分野を限定せず適用されます。 例:キーボード(メカニカル、ホットスワップ、カスタム)、ポインティングデバイス、 産業用コントローラ、計測機器、教育プロジェクト。いずれの場合も、派生物の ドキュメント(README、製品ページ、論文、クレジットなど)の読みやすい位置に 表示してください。

4. 無保証

本ソフトウェアは現状有姿で提供され、いかなる保証も伴いません。 実機で使用する場合の検証・認証および使用の結果は、利用者の責任となります。


概要

本稿では、RP2040 ベースのアーケードコントローラー向けオープンファームウェア Manticore XInput を提示します。これは通常別々に扱われる 2 つの性質、 エンドツーエンドの入力遅延と物理接点の可観測性を対象とします。入力ホット パスは RAM から実行される排他的な GPIO 割り込みで、USB HID レポートバッファを in-place でリフレッシュし、次の interrupt IN トランザクションの予測によって ゲートされます。学習されたピン単位のデバウンスロックアウト(lockout)が、各接点 で計測されたバウンスエネルギーに適応します。その周囲に、自己計測型ブラックボックス を構築しました。マイクロ秒タイムスタンプ付きのエッジカウンタ、遅延ヒストグラム、 イベントトレース、そしてバージョン 9.7 以降では、すべての機械的バウンスの個々の メイク/ブレイクの瞬間を記録する接点ごとのバウンスリングです。ホスト側の Web アプリケーションが、コンフィグモードで USB CDC 経由でデバイスを読み取り、バウンス 列を無信号区間でセグメント化し、時間領域・間隔領域・周波数領域で解析します (再構築した 2 値信号の短時間フーリエ変換、瞬時バウンス周波数、バーストごとの 整定メトリクス)。

単一のコントローラーで、999 Hz の実効ポーリングケイデンス、エッジ→レポート遅延 の最小 5 µs・平均 0.51 ms、エンドポイント再アームの平均 14 µs、in-place リフレッシュゲートが使用する間隔予測の精度 99.95 % を計測しました。2.34 M の 完了した IN 転送にわたって、ドロップしたトレースイベントは 0、失敗した in-place セルフチェックは 0 でした。バウンス計測は、粗いカウンタでは隠れてしまう接点の 挙動を示します。あるキャプチャでは、ホストが 112 イベントをセグメント化し、 そのうち 76 がチャタリングバースト、36 がクリーンな遷移でした。バーストの整定窓 は 50 µs から 480 µs にわたり、成長率(最大間隔/最小間隔)は 2.1× から 68×、 支配的なスペクトル成分は 3.9 kHz から 23.4 kHz でした。本稿では、手法、計測された コスト(264 KB の RAM のうち 94.5 KB、2 MB のフラッシュのうち 53 KB)、検証戦略 (モック化ハードウェアに対して実際のソースをコンパイルする、ARM 上でエミュレート された 9 つのテストスイートと、ホスト側 JavaScript テスト)、および限界(振幅 情報の欠如を含む — GPIO は接点がいつ開閉するかだけを報告でき、どれだけ強くかは 決して報告できません)を説明します。

キーワード: USB HID、XInput、RP2040、入力遅延、バウンス、適応型デバウンス、 組込みテレメトリ、時間–周波数解析。


1. はじめに

機械接点で作られたデジタル入力は、2 値のマスクをかぶったアナログデバイスです。 スイッチが閉じるとき、可動接点は瞬時に整定しません。相手接点に衝突して跳ね返り、 衝撃の弾性エネルギーが散逸し、接触力がばねの復元力を上回るまで振動します。接点の 電気ノードをオシロスコープで見ると、メイク/ブレイク遷移のバースト — バウンス — が観測され、通常は数十〜数百マイクロ秒続きます [1], [2]。ファームウェアはこれを デバウンス窓で隠蔽します。エッジの後、一定時間はさらなるエッジを無視します。 窓は通常保守的に選択され(2–10 ms)、その選択はユーザーには見えません — 遅延を 生むか、摩耗した接点で破綻するまでは。

アーケード/格闘ゲームコントローラーはこのトレードオフを先鋭化させます。プレイヤー は同じボタンを毎分数百回押し、入力パスは 125 MHz で動作しますが、ポリシー は いまだ開発者が選んだ定数のままです。GP2040-CE [7] のような既存のオープン ファームウェアは設定を公開しますが、接点自体については何も計測しません。

本レポートは異なるアプローチを説明します。計測器を製品の一部にするのです。 当プロジェクトは、(i) ホットパスを最小限かつ RAM 常駐に保ち、(ii) 実際に観測 されたバウンスエネルギーから接点ごとにデバウンス窓を学習し、(iii) 個々のバウンス タイムスタンプを保持するため、デバウンスを駆動するのと同じ信号を後から — ホスト 上で、オフラインで、時間領域と周波数領域で — 解析できます。

貢献:

1. 入力 ISR が次の IN トークンの予測のもとで HID レポートバッファを in-place で リフレッシュする、RP2040 向け XInput + CDC ファームウェアアーキテクチャ(§4)。 2. 計測されたバウンススパンを lockout に変換するピン単位の適応型デバウンス ポリシー。プロモーション、上限、フォールバックを備え、入力パスを決して ブロックすることなく電源再投入をまたいで永続化されます(§5)。 3. 自己計測型ブラックボックス: 集約カウンタ、64 µs バケットの遅延ヒストグラム、 512 エントリのトレースリング、接点ごとの 128 µs スタンプ付きエッジのピン単位 リング(§6)。 4. エッジ列を定量的な接点シグネチャ — チャタリング窓、間隔の成長、瞬時バウンス 周波数、再構築したレベルの STFT — に変換するホストパイプラインと Web アプリケーション(§7、§9.4)。 5. 実験室のないプロジェクトにおける検証手法: 実際のソースをモック化ハードウェア に対して ARM エミュレーション実行し、さらに UF2 構造検証を行う(§8)。

2. 関連研究

接点物理と接点信頼性は古典的なテーマです。Holm による電気接点の扱い [1] と、 コネクタの現代トライボロジー [2] は、バウンスを接点システムの弾性動的応答として 説明しています。本稿で使用する信号処理ツールは標準的なものです [3], [4]。デジタル 設計におけるデバウンスの実践は教科書的な内容であり [5]、非定常記録のエネルギー 的なスカラー要約に対する地震学的アナロジーは Arias [6] に従います。ファームウェア 側では、GP2040-CE [7] が最も近いオープンプロジェクト(設定、SOCD、複数プロトコル) ですが、接点の挙動を計測していません。TinyUSB [8] が USB デバイススタックを提供し、 HID クラスとレポートのセマンティクスは USB HID 仕様 [9] に従います。RP2040 の デュアルコア Cortex-M0+ とその 264 KB SRAM(RAM からコードを実行できる可能性を 含む)は [10] に記述されています。

3. システム概要

対象: 19 接点のアーケードパネル(ボタン、スティック方向、トリガー)を、RP2040 (デュアル Cortex-M0+、125 MHz、264 KB SRAM、2 MB フラッシュ)の GPIO に アクティブローで配線します。2 つの USB パーソナリティを使用します:

  • XInput モード — 通常の動作モード: ベンダーインターフェース(0xff/0x5d)と

VID:PID 045e:028e、interrupt IN エンドポイント(32 バイトパケット)でホストの ポーリング間隔で配送される 20 バイトのレポート、さらにダッシュボードが使用する 4 つのベンダーコントロールリクエスト: 0x01 GET_CAPABILITIES、0x02 host action、0x03 live lock table、 0x04 black-box summary(バイナリ、リトルエンディアン、バージョン付き)。

  • コンフィグモード — 意図的なジェスチャ(ブートコンボ、L3+R3+Guide を 3 秒)

またはホストコマンドの後に CDC-ACM(045e:0c00)として再エニュメレートされ ます。シリアルポート経由のラインプロトコルが設定と診断を公開します(§6.3)。 コンフィグモードへのソフトリセットは SRAM を保持するため、ブラックボックスは それを乗り越えて存続します。

永続状態は最後の 2 つのフラッシュセクタに置かれます。設定(magic + version + CRC32)と、学習されたデバウンス/ブラックボックスのサマリで、コア 1 を退避させた flash_safe_execute 経路のみを通じて書き込まれます(§5.4)。アーキテクチャを F1 に示します(webapp/architecture.html。ドキュメントの残りと同じパイプラインで 生成)。

4. 入力ホットパス

エッジキャプチャ。 19 の入力はすべて両エッジ割り込みで設定され、USB より高い 優先度 0 の 1 つの排他 IRQ にまとめられ、そのハンドラは RAM 上に配置されます (__not_in_flash_func)。ハンドラは 1 µs タイマーを読み、§5 で学習したピンごとの lockout に照らしてエッジを分類し、受理する(状態変化)か、バウンスとして計数 します。除算は行わず、フラッシュ上のコードも呼び出しません。接点ごとのバウンス リングへのプッシュは単一プロデューサの追記です(§6.2)。

in-place レポートリフレッシュ。 メインループで HID レポートを再構築する代わり に、ISR は USB コントローラがすでに指しているバッファ(すなわちエンドポイントの DPRAM バッファ)を更新します。これにより、単一ワードの変更では「変更後にアーム する」遅延が完全に消えます。複数ワードの変更(例: 同一フレーム内のスティック + ボタン)は IN トランザクションからティアリング状態で見られてはならないため、 ゲートは観測されたポーリングケイデンスから次の完了までの時間を推定し(EMA と 最小間隔予測)、残りのマージンが 80 µs を超える場合にのみ in-place でコミット します。それ以外の場合、変更は次の再アームまで延期され、これは構造上安全です。 予測は計測セッション全体で 10 339 ヒット / 5 ミス を記録しました(§9.1)。

再アーム。 IN 転送コールバックは最も新しい状態でエンドポイントを直ちに再アーム するため、変更はメインループの反復を待たずに次のフレームに載ります。計測された 完了→再アームの平均ギャップは 14 µs です。

5. 適応型デバウンス

信号。 受理されたすべての遷移について、ファームウェアは スパン を記録します。 受理エッジから、窓内で観測された最後のバウンスエッジまでの時間です。これは そのイベントのバウンスエネルギーに対する頑健な代理指標であり、列全体を保存する 必要がありません(§6.2 では解析のためにいずれにせよ保存しています)。

ポリシー。 サンプルは 3 遷移のブロック単位で蓄積され (MANTICORE_BLOCK_SAMPLES)、ブロックの最大値が学習値(bounce_max_us)を 決定します。得られる lockout は

lockout = clamp(bounce_max + margin, floor, cap)

であり、margin = 100 µs、floor は設定可能(既定 250 µs、100–4000 µs)、 cap = 6000 µs です。実用上重要な改良が 3 つあります:

  • プロモーション — 長いクリーンストリーク(≥24 遷移)を持つピンは、設定され

た floor を下回ることができますが、150 µs までに限られ (MANTICORE_PROMOTED_FLOOR_US)、ユーザーが明示的に選択した floor を下回る ことは決してありません。

  • 未使用ピン は、少なくとも 1 回操作されるまで保守的な 1000 µs の lockout を

維持するため、計測されていない接点が幻の押下を生じさせることはできません。

  • システムボタン(START/BACK/GUIDE)は固定 5 ms の lockout を使用し、適応から

除外されます。遅延クリティカルではなく、しばしば多目的ジェスチャに割り当てられ ているためです。

適応はコア 1 で実行されます。ハートビートが 200 ms 停止すると、コア 0 は最後の 安全な値にフォールバックするため、停止したコアが入力パスを無保護のままにすること はできません。

分類であり、フィルタリングではない。 チャタリング窓(既定 8 ms、 SET chattergap)より速いリリース→再押下のペアは、除外される代わりに 自己再開押下(dfire)として分類されます。カウンタは接点ごとに公開され、ホスト UI が使用する運用上の摩耗指標です。以前のファームウェアバージョンはこれらの イベントをフィルタリングしていたため、目に見える遅延が発生しました。計測の結果、 問題はパスではなくフィルタにあることが示されました。

永続化。 学習値、ストリーク、ブラックボックスのサマリは、バージョン付き レコード(LEARN_VERSION 2)としてエクスポートされ、アイドル窓の間のみ書き込まれ ます(受理エッジが 30 秒以上ない状態、毎分最大 1 回の書き込み、コンフィグモードへ の移行時に強制)。したがって、消去/プログラム時の約 46 ms の XIP ストールが 2 つの 入力の間に発生することはありません。手動のピン単位オーバーライド(SET pinlock) は即座に永続化されます。

6. インストルメンテーション

6.1 カウンタと分布

ブラックボックス(diag.c)は累積カウンタ(エッジ、レポート、バウンス、in-place コミット、失敗した in-place セルフチェック、ドロップしたキューエントリ、延期)に 加えて、分布を保持します。ポーリング間隔の最小/平均/最大、エッジ→レポート遅延の 最小/平均/最大(64 µs ビンの 16 バケットヒストグラム付き)、フレーム内位相 の統計、再アームギャップです。カウンタは学習状態の一部としてフラッシュに エクスポートされるため、明示的な CLR/DIAGCLR まで電源再投入をまたいで存続 します。

6.2 バウンスリング

9.8 以降、ブラックボックスはピンごとに 1 つのリングを保持します — {uint32_t time_us; uint8_t type} の 128 エントリ × 32 ピンで、未初期化 RAM セクションに 約 32 KB を占めます:

  • 受理されたすべてのエッジ(E)を記録します — バーストの開始を示します。
  • 拒否されたすべてのエッジ(B)も同じ 1 µs 分解能で記録します。

リングは入力 ISR からのみ書き込まれ(単一プロデューサ、ロックなし、除算なし — ラップはマスクです)、コンフィグモードでは GPIO 割り込みを無効にして読み出され ます。ピン単位のレイアウトを導入したのは、そうでなければ 1 つのノイズの多い接点が 共有リングを埋め尽くし、他のすべての接点を追い出しうるためです(観測: ある セッションで 3 接点から 1024/1024 エッジ)。

6.3 ホストプロトコル

GET | SET | SAVE | STATS | LOCKS | TRACE | BOUNCE | CLR | DIAGCLR | RESET | REBOOT | BOOT、改行終端で、RAM バッファからストリーミングされます(ダンプは CDC FIFO よりはるかに大きい)。BOUNCE は次を出力します:

BOUNCE pins=<contacts with data> ev=<emitted event lines> rec=<recorded events>
E <time_us> <pin>      accepted edge
B <time_us> <pin>      rejected edge (one bounce)
...
OK

ピンごとにまとめられ、各ピン内では古い順で、データを持つピン間で共有される 1024 イベント行の総予算付きです — したがって、おしゃべりな接点が他の接点を隠すことは できません。ヘッダは生成されたイベントと記録されたイベントを区別し、これに より切り詰められたダンプがホストから見えるようになります。

7. ホストツール

シングルページの Web アプリケーション(Chrome/Edge、WebSerial、ビルドステップ なし、サードパーティコードなし)がコンフィグモードに接続し、接続時にすべてを自動 的に読み込みます。設定、ブラックボックス、バウンス列、ファームウェアマニフェスト です。表示内容は次のとおりです:

  • ブラックボックス(遅延ヒストグラム、ピンごとのカウンタ、dfire 比率を含む劣化

テーブル)。

  • 適応型 lockout テーブルとバー。
  • バウンスビューア: 接点ごとの最新キャプチャ、エッジの瞬間から再構築した

ステップ波形、連続するバウンスエッジ間の間隔バー、スペクトルパネル(§9.4)。

  • エクスポート/インポート付きの IndexedDB 履歴。
  • ファームウェアアップデータ: BOOT → manifest.json に固定された size と

sha256 に対してイメージを検査した後、File System Access API 経由で UF2 を RPI-RP2 ボリュームに書き込みます(§11)。

統計処理はホスト側で行います。デバイスには提供できる振幅がないためです。ページは 1 µs でリサンプリングして 2 値レベルを再構築し、無信号区間でバーストに分割し (既定ギャップ 5 ms、調整可能)、付録 B のメトリクスを計算します。

8. 検証

実験室がないため、正しさは ARM エミュレータ(Unicorn 2.1.4)上で実際の ファームウェアソースをモック化ハードウェアに対して実行することで担保されます。 9 つのスイート(firmware_test、dpram_test、settings_test、diag_test、 config_test、ui_test、descriptors_test、lcd_test、telemetry_test)が、 入力 ISR、in-place ゲート、永続化、ダンププロトコル、USB ディスクリプタ、 ディスプレイをカバーします。ホストパイプラインには独自の依存関係のない Node テストがあります(セグメンテーション、FFT、STFT、窓処理、退化入力)。 verify_uf2.py スクリプトは生成されたイメージを再読み込みし、UF2 構造、 バージョン識別文字列、リセットベクタ、およびリンクされた BIN との一致を検査する ため、リリースされた成果物がテスト済みツリーと無言で異なることはありません。

計測機能はファームウェアを監査可能にもします。9.8 に対する外部マルチエージェント レビュー(ファームウェア、ホストコード、ドキュメント、更新経路を対象とした 4 名の 独立レビュア)は、1 件のブロッキング欠陥(ブラウザタブをフリーズさせうる無制限の スペクトログラム。240 フレームと 200 k サンプルの上限を追加)と、いくつかの 正しさの問題(2 つのバーストを統合しかねない 32 ビットタイマーのラップ、以降の すべてのコマンドを無言で無効化しかねないラッチされたビジーフラグ、マニフェストに ダイジェストがない場合でもイメージを書き込みうる更新経路)を発見し、すべて 9.9 で 回帰テスト付きで修正されました。

9. 結果

9.1 入力パス(単一コントローラー、1 セッション)
項目値
実効ポーリングケイデンス999 Hz(平均間隔 1.00 ms)
エッジ→レポート遅延、最小5 µs
エッジ→レポート遅延、平均0.51 ms
エッジ→レポート遅延、最大45.88 ms(ホストストール 1 件、§10 参照)
フレーム内位相、平均29 µs
完了→再アーム、平均14 µs
間隔予測10 339 ヒット / 5 ミス(99.95 %)
ドロップしたトレースエントリ0
失敗した in-place セルフチェック0
受理エッジ / 完了した IN 転送21 910 / 2 341 553
拒否エッジ(バウンス)734 968(受理エッジあたり 33.5)
9.2 コスト
リソース9.9
フラッシュイメージ(BIN)2 MB のうち 53 904 B(2.6 %)
.text / .rodata(XIP、フラッシュ常駐)43 248 / 2 652 B
.data(RAM)7 716 B
.bss(RAM、20 KB のダンプバッファを含む)37 804 B
未初期化 RAM(ブラックボックス + バウンスリング)38 696 B
ヒープ + 2 本の 4 KB スタック10 240 B
RAM 合計94 456 B ≈ 264 KiB のうち 92 KiB(35 %)

ホットパスは測定可能なコストを追加しません。バウンス記録は RAM 常駐コードにおける 拒否エッジあたりのインデックスインクリメント 1 回と 2 回のストアです。

9.3 バウンスケーススタディ(単一デバイス、1 回のキャプチャ)

19 接点パネルからの 1 回の BOUNCE ダンプは、リングに 1097 エッジを記録し、 電源投入以降に操作された 11 接点をカバーしました。1024 行の予算では 843 エッジ 行が出力され、ホストはそれらから 76 のチャタリングバーストと 36 のクリーンな 遷移をセグメント化しました。3 つの接点が範囲を示します(P1、K2、K3 はパネルの 面ボタンとトリガー位置のラベルです):

接点エッジチャタリング窓成長率(最大/最小間隔)支配的20 kHz 超のエネルギー
P1 (X)350 µs×2.123.4 kHz68 %
K2 (B)17250 µs×3.83.9 kHz45 %
K3 (RT)18480 µs×683.9 kHz31 %

対応する間隔系列(F2–F4)は予想される機械的シグネチャを示します。接点が整定する につれて間隔は単調に増加し(K3: 瞬時バウンス周波数が 0.48 ms にわたって 71.4 kHz から 1.0 kHz に低下)、一方 P1 は 3 遷移で終了します — 同じ種類のイベントであり ながら、エネルギーは 2 桁小さいものです。1 つの接点をクリッキーからリニアスイッチ に交換すると、シグネチャが質的に変化しました。これは、クリック機構が閉時に接点 リーフを励振するという仮説と整合します(§10.3)。

9.4 解析パイプラインのパラメータ

リサンプリング 1 µs(1 MHz)、Hann 窓、256 点 FFT(0.256 ms 窓、64 µs ホップ)、 周波数分解能 3.91 kHz。ホストの処理量を制限するため、フレームは 240、サンプルは 200 k に上限設定。約 100 kHz を超えるものは接点の内容ではなく ISR ジッターと して報告します。バーストごとのメトリクスは付録 B で定義されています。Web アプリケーションは生のエッジストリーム(JSON)とバーストごとのメトリクス(CSV) をエクスポートできるため、これらの数値はいずれも再計算可能です。

10. 考察

10.1 適応ポリシーがもたらすもの

バウンスデータは、固定窓が誤った道具である理由を説明します。同じコントローラー の 3 つの接点間で、整定窓は 1 桁異なりました(50 µs 対 480 µs)。1 ms の固定 lockout は 3 つすべてを保護しますが、最もクリーンな接点に約 1 ms の遅延を追加 します。100 µs の窓では K3 のバウンスが漏れます。ピンごとに学習し floor で クランプすることで、応答性の高い接点は応答性を保ち、ノイズの多い接点は安全に 保たれます。

10.2 遅延最大値が意味すること(そして意味しないこと)

latency max = 45.88 ms は 21 910 サンプル中の単一の外れ値です。このメトリクスは 受理エッジ → その後に完了した最初の IN 転送 と定義されるため、必然的にホストの ポーリング挙動を含みます。45 ms という値は、ホストが約 45 ms の間エンドポイントの サービスを停止したこと(スケジューリング、ポート電源管理、バス競合)を意味し、 ファームウェアが 45 ms かかったことを意味しません。根拠はその数値の近傍にあります。 再アーム 14 µs、最小遅延 5 µs、平均 0.51 ms です。したがって、ヒストグラムを 正直な見方、最大値をホスト環境の指標として扱います。

10.3 クリックはバウンスに影響するか

クリッキースイッチでは、クリックは作動点でスナップする別のリーフによって生成され ます。これは接点リーフと機械的に結合され、接点が閉じるまさにその瞬間に発火します。 同じ位置でクリッキースイッチをリニアに交換したときに観測された変化(異なるバース ト形状、異なる整定窓)は、クリックがバウンス列に寄与するという仮説を支持します。 クリーンな実験には、再現可能なアクチュエータ(サーボ/ウェイト)、両バリアントで 同一のスイッチモデル、接点あたり ≥5 回の作動にわたる中央値の比較が必要です。この 実験は今後の課題です。

10.4 機械的バウンスと閾値ノイズの区別

デジタルエッジがアナログ信号(コンパレータまたは ADC 閾値)に由来する接点は、 閾値付近で電気的再トリガーを生じることがあります。2 つの現象は形状で区別でき ます。機械的バウンスは単調に増加する間隔と再現可能な形状を示し、閾値ノイズは 増加のない不規則な間隔と確率的な発生を示します。ビューアが接点ごとに 5 つの バーストを保存するため、追加のインストルメンテーションなしでその比較が可能です。

11. 限界と今後の課題

  • 振幅なし。 GPIO は接点がいつ開閉するかは報告しますが、どれだけ強く、

どれだけ変位したかは決して報告しません。振幅 — 接点抵抗の過渡、力、変位 — には追加ハードウェア(接点の分圧器に接続した ADC、または外部の加速度計/ レーザー振動計)が必要です。当プロジェクトは代理指標(間隔の成長、スペクトル 内容)を意図的に代理指標として報告します。

  • 帯域上限。 エッジタイムスタンプには約 1 µs の量子化とサブ µs の ISR

ジッターが含まれ、約 100 kHz を超える内容は接点の挙動ではなく計測ノイズです。 ビューアはすべてのスペクトルにこの旨を表示します。

  • 単一デバイスのデータ。 計測された表は 1 つのコントローラーと少数のセッション

に基づきます。手法(およびエクスポート経路)はデバイス、スイッチ、操作スタイル をまたいだ再現のために設計されていますが、ここでの数値はケーススタディであり、 母集団ではありません。

  • 操作のばらつき。 指による操作は、アクチュエータを固定しない限り接点間の差を

支配するばらつきを持ち込みます。推奨手順は接点あたり ≥5 バーストと中央値の比較 です。

  • 更新の信頼。 アップデータは manifest.json から取得した size と sha256

に対してイメージを検証し、未検証のイメージを拒否し、パスを検証しますが、 ダイジェストはイメージと同じファイル内を移動します。HTTPS とホスティングの 完全性のみが信頼の根拠です。署名付きマニフェストは今後の課題です。

  • 計画中の機能。 ゲームごとのプロファイル付きボタンリマッピング、オプションの

turbo、アナログ(Hall/ADC)入力バリアントがロードマップにあります。最後の ものは、この計測器が見ることのできない振幅を得る自然な方法です。

12. 結論

入力ホットパスに予算を費やすマイクロコントローラでも、計測器であり続ける余力が あります。Manticore XInput はエッジ→レポート経路を最小 5 µs・再アーム 14 µs に 保ちながら、すべてのエッジをマイクロ秒タイムスタンプ付きで記録し、計測したバウンス エネルギーから接点ごとに lockout を学習し、ホストが定量的な整定シグネチャに変換 する生のバウンス列をエクスポートします。デバウンス窓を選択するのと同じデータが、 エンジニアリング上の問い — この接点はどれほど弾性的か、どのように減衰するか、その クリックは信号に現れているか — にも答えます。機械にオシロスコープを接続すること なく。

参考文献

1. R. Holm, Electric Contacts: Theory and Application, 4th ed. Springer, 1967. 2. M. Braunovic, V. V. Konchits, N. K. Myshkin, Electrical Contacts: Fundamentals, Applications and Technology. CRC Press, 2007. 3. F. J. Harris, "On the use of windows for harmonic analysis with the discrete Fourier transform," Proceedings of the IEEE, vol. 66, no. 1, pp. 51–83, 1978. 4. A. V. Oppenheim, R. W. Schafer, Discrete-Time Signal Processing, 3rd ed. Pearson, 2010. 5. P. Horowitz, W. Hill, The Art of Electronics, 3rd ed. Cambridge University Press, 2015 (switch debouncing and Schmitt-trigger practice). 6. C. P. Arias, "A measure of earthquake intensity," in Seismic Design for Nuclear Power Plants. MIT Press, 1970 (intensity summaries of a non-stationary record). 7. GP2040-CE — open-source firmware for RP2040-based game controllers, https://github.com/OpenStickCommunity/GP2040-CE 8. TinyUSB — an open-source cross-platform USB stack for embedded systems, https://github.com/hathach/tinyusb 9. USB Implementers Forum, Device Class Definition for Human Interface Devices (HID), version 1.11, 2001. 10. Raspberry Pi Ltd, RP2040 Datasheet: A microcontroller by Raspberry Pi, 2021.

引用注: この一覧は、プロジェクトが確実に名指しできる文献に意図的に限定して います。外部投稿の前に拡張と検証を行ってください。

付録 A — コンフィグモードのコマンド

GET                  settings dump (debounce, socd, forget, chattergap, ...)
SET debounce <us>    per-pin floor, 100..4000 (wire unit µs)
SET socd <mode>      neutral | last | first | up
SET forget <s>       seconds without bounces before forgetting the learned lockout
SET pinlock <gp> <us>  manual override (persisted immediately, 0 = automatic)
SET chattergap <ms>  malfunction chatter window (1..50)
SAVE                 persist settings
STATS | LOCKS | TRACE | BOUNCE   streamed dumps, terminated by OK
CLR | DIAGCLR        reset black box (and adaptive state for CLR)
RESET | REBOOT | BOOT  restore defaults / reboot / ROM UF2 bootloader

付録 B — バウンスメトリクス

受理エッジが t0、バウンスエッジが t1 … tn のバースト(拒否エッジ n 個、 合計 n+1 エッジ)について、間隔を dk = tk − t0 とすると:

  • チャタリング窓 = max(dk) — 受理エッジから最後のバウンスまで。
  • エッジ数 = n + 1。
  • 間隔の最小 / 中央値 / 最大 — {dk} の順序統計量。
  • 成長率 = 最大間隔 / 最小間隔(≥1。大きい = 接点が密に始まり緩んだ、すなわち

整定振動)。

  • 瞬時周波数 = 1/(2·dk) — 1 周期あたり 1 組のメイク/ブレイク。
  • 支配的 / 重心 / 高周波シェア — 1 µs でリサンプリングしたレベルの Hann 窓

FFT から(シェア = 20 kHz 超のエネルギー割合)。

  • 受理エッジで始まるか — バーストの最初のイベントが受理された遷移であったか

どうか(そうでなければ、リングから落ちたバーストの尾です)。

付録 C — 再現性

Firmware 9.9   standard UF2  sha256 58f019f7b85d11d70517526b8c110b44c043f6e312f256d38f797787de7f54fa
               timing   UF2  sha256 2ecc3048231a3589be3077b283b7e36fe7c4f06daecf8b73606cb4be05898969
Build          cmake -S . -B build-9.9 -G Ninja -DPICO_SDK_PATH=<pico-sdk-1.5.1> \
                     -DPICO_BOARD=pico -DCMAKE_BUILD_TYPE=Release && ninja -C build-9.9
Tests          python3 tests/run_tests.py <firmware_test|dpram_test|settings_test|diag_test|
               config_test|ui_test|descriptors_test|lcd_test|telemetry_test>
               node tests/bounce_js_test.mjs
Artifact       python3 tests/verify_uf2.py build-9.9/manticore_xinput.uf2 build-9.9/manticore_xinput.bin
Capture        play → config mode (L3+R3+Guide 3 s) → web app → Refresh bounce → Export captures
               (JSON raw edges + CSV per-burst metrics)
Analysis       same parameters as §9.4 (1 µs resampling, Hann, 256-pt FFT, 64 µs hop,
               gap 5 ms default, 240-frame / 200 k-sample caps)

本ドキュメントは docs/paper-manticore-xinput.md(英語版)の日本語訳です。

アーキテクチャ

構成図はこのページの最下部にズーム可能なビューアで掲載しています(Ctrl+ホイールまたはピンチ、ドラッグで移動、ダブルクリックで 1:1 / 2x)。ベクター版は architecture.svg からも取得できます。

ドキュメントとダウンロード

  • 技術ペーパー: italiano · English · 日本語(全文は下にも掲載)
  • ソースパッケージ 9.9: manticore-xinput-9.9-src.zip(1.122931 MB、sha256 b27d9663f76d21b9f6575c4319037e9ddd6eb93c1fe3ac71e676fb1a61d1528d)
  • リファレンス Web アプリ(WebSerial、Chrome/Edge): ソースパッケージ内の webapp/index.html(Chrome/Edge で開く)

検証方法

9 本の ARM エミュレーテッドテストが実ソースを模擬ハードウェア上で実行し、依存なしの Node テストがホスト側パイプラインを、検証スクリプトがリリースした UF2 をリンク済みバイナリとバージョン同一性に対して検査します。9.8 に対する外部マルチエージェント監査で 1 件の阻害的欠陥と複数の修正が得られ、すべて 9.9 に回帰テスト付きで反映されています。

閲覧

Schema dell'architettura

Manticore XInput system architecture
SVG

Ctrl+rotella o pinch per lo zoom, trascina per spostare, doppio click per 1:1 / 2x. Il pulsante SVG apre il file originale.