Happy Mashing Keyboard Life

ゲーマーのためのQMK設定

前に書いたやつが古くて情報が更新されていない, 間違っているとまでは言えないが怪しい情報がある, そもそも読み辛かったので書き直すことにしました.

本記事で取り扱う範囲

本記事ではQMK Firmwareをゲーミング用途で使用する際に設定すべき項目と記述方法, 得られる効果, それとキーボードの入力遅延に関するいくつかの補足事項(デバウンスの仕組みやChord Splitなど)についてのみ取り扱います.

QMKやVIAの導入方法, ファームウェアの焼き方など基本的な事柄については取り扱いません. 公式のマニュアルを参照してください.

本記事の設定によって得られるもの

  • Single-key Latency: 1-2ms
  • Chord Split Delay:
    • 4K: 3-4ms
    • 8K: 7-8ms
  • ソフトウェア的対処によるチャタリングの防止

Single-key LatencyとChord Split Delayの数字はRTINGSの検証データからの推測値です(実測できるような環境はない). Chord Split DelayはPCBの出来によってもう少し遅延するかもしれません.

環境

2024-10-16時点に以下の環境でコンパイルを行っています.

  • Arch Linux 6.11.3-zen1-1-zen
  • qmk_firmware 0.26.9 (commit 85a7627641cbbc71de1a89b0346ee7d92d4fb394)
  • qmk_cli 1.1.5-2
  • gcc 14.2.1+r134+gab884fffe3fc-1

設定

設定の記述について, 以前はとっ散らかっていて色々なファイルに分散している状況でしたが, 現在は整備され keyboard.json だけで完結させられるようになっています.

Polling Rate

現在, QMKは標準でPolling Rate 1,000 Hzとなっているため, 設定は不要です(#15352).

ただし, 工場出荷時の状態で古いQMKが焼かれている場合はPolling Rate 125 Hzで動作している可能性があります. その場合は必ず最新のQMKを焼き直すようにしてください.

N-Key Rollover

NKROを有効化するには keyboard.json に以下のように記述します.

"features": {
    "bootmagic": true,
    "mousekey": true,
    "extrakey": true,
    "nkro": true,
    "rgb_matrix": false
},
"usb": {
    "pid": "0x1321",
    "device_version": "2.1.0",
    "force_nkro": true
},

"nkro": true はNKROを使えるようにします.

"force_nkro": true は接続時にNKROを有効化します. NKROを使える状態であっても, これを書かないと接続時に有効にはなりません(Legacy BIOSのための措置と思います).

Debounce

QMK標準のデバウンスアルゴリズムは sym_defer_g となっていますが, sym_eager_pk を使用するように直してください.

keyboard.json に以下のように記述します.

"build": {
    "debounce_type": "sym_eager_pk"
},
"debounce": 25

補足: 何故 sym_eager_pk を使うべきなのか

(前提としてContact bounce / contact chatter | QMK Firmwareを読んでください)

  • Eager vs Defer

    • Eager
      • 信号を検出した時点でレポートするため, 遅延が生じない.
      • 信号を検出した時点でレポートしてしまうため, ノイズ耐性がない.
      • デバウンス時間を大きくできるため, 滅多なことではチャタリングを生じさせない(ソフトウェア的に対処できる).
    • Defer
      • デバウンス時間分信号が安定するのを確認してからレポートを行うため, 遅延が生じ, また遅延に一貫性がない.
      • デバウンス遅延がありデバウンス時間を大きくできないため, 酷使されたスイッチではチャタリングを起こす.
  • Global Timer vs Per-Row Timer vs Per-Key Timer

    • Global Timer
      • 他キーの影響を受けて遅延が生じる.
      • リソースの消費量は最も小さい(のでこれを採用した sym_defer_g が標準となっている).
    • Per-Row Timer
      • 行内の他キーの影響を受けて遅延が生じる.
      • マトリクスが90度回転している(行が実質列である)などといった場合は弊害が少ない.
      • 比較的リソースの消費量が小さい.
    • Per-Key Timer
      • 各キーが独立して処理されるため余計な遅延を生じることがない.
      • リソースの消費量は最も大きい.

纏めると sym_eager_pk は, 性能は高いものの, ノイズ耐性がなく, リソースの消費量が大きい, ということになるが,

  • 普通のキーボード基板のインピーダンスと一般の御家庭における使用では外来的なノイズを気にする必要はない(はず)(逸般の御家庭では駄目かも)(そんなところでゲームするな).
  • 普通のキーボード基板で sym_eager_pk を使ったところでリソースが足りないということはまずない.

というわけで sym_eager_pk 以外の, 入力遅延で劣るアルゴリズムを選択する理由はないです.

補足: デバウンスアルゴリズムとスキャンレートについて

性能の低いPCBで sym_eager_pk のような処理負荷の高いアルゴリズムを使用すると問題が生じるという懸念があります.

が, 実際のところ, (設計が酷くなければ)ATmega32U4のような廉価なMCUであっても, sym_eager_pk を使用しても安定してScan Rate 2,000 Hz程度は出ているようでした. これは60%での数値で(60%しか持ってない), マトリクスの多いTKLなどでは多少落ちるかとは思いますが, 多分1,500 Hzくらいは出ると思う(適当)ので特に気にしなくていいと思います.

気になる場合は自分でデバッグして確認してください. もしScan Rate 500 Hzとかそんな数値が出ていたら窓から放り投げて新しいキーボードを組みましょう.

補足: デバウンス時間の設定について

  • 現実的, 人間の反応速度の限界的に20~25msくらいに設定しておけば大丈夫なはず.
  • 音ゲーをやっていて不安, 神経質な人はもう少し小さくしていいかもしれない.
  • 30ms以上はリリースや連打に悪影響が出る(かもしれない)からやめておいた方がいいと思う.

私は一応小さめに, 15msに設定しています. RTINGSの検証によるとメカニカルスイッチがボトムアウトしている状態からリリースされるまでに大体4~8ms必要(スイッチにより当然差がある)で, 現実的に人間が打鍵する際にはどれだけ最速で離鍵しようとしても10msは必要となる, という理屈でこの値にしています.

実際, 「自分が底打ちさせてから最速で離鍵するようにして何msでリリースが発生するか」を(ガバガバ)検証したところ, 超絶上振れを引いて16msが最速という測定結果になったので, まあこんなもんでいいんじゃないかなと思います.

その他遅延を生じる機能の無効化

  • 当然ながら, Tap/Holdなど「入力待ち」を要する機能は使えません.
  • OLEDの更新は結構な遅延を生じ, ゲーミング的にカスらしいです. でもOLEDの実装されているキーボードを持ってないから実際のところどれくらい影響があるのかはわかんないです.
  • RGBを有効にしていると僅かにスキャンレートが低下するなどして僅かに遅延が生じるかもしれません(未検証). 使うことないから調べてないです.

設定例

自分が使用しているPCBでの設定例(diff)を申し訳程度に貼っておきます.

DZ60RGB-WKL V2.1

diff --git a/keyboards/dztech/dz60rgb_wkl/v2_1/keyboard.json b/keyboards/dztech/dz60rgb_wkl/v2_1/keyboard.json
index 968488e544..7f9bde8bc0 100644
--- a/keyboards/dztech/dz60rgb_wkl/v2_1/keyboard.json
+++ b/keyboards/dztech/dz60rgb_wkl/v2_1/keyboard.json
@@ -1,7 +1,8 @@
 {
     "usb": {
         "pid": "0x1321",
-        "device_version": "2.1.0"
+        "device_version": "2.1.0",
+        "force_nkro": true
     },
     "rgb_matrix": {
         "animations": {
@@ -48,10 +49,13 @@
         "mousekey": true,
         "extrakey": true,
         "nkro": true,
-        "rgb_matrix": true
+        "rgb_matrix": false,
+        "console": false,
+        "command": false
     },
     "build": {
-        "lto": true
+        "lto": true,
+        "debounce_type": "sym_eager_pk"
     },
-    "debounce": 3
+    "debounce": 15
 }

FM-60S

diff --git a/keyboards/geonworks/frogmini/fms/keyboard.json b/keyboards/geonworks/frogmini/fms/keyboard.json
index c34765288b..d95ed3a765 100644
--- a/keyboards/geonworks/frogmini/fms/keyboard.json
+++ b/keyboards/geonworks/frogmini/fms/keyboard.json
@@ -6,8 +6,13 @@
     "usb": {
         "vid": "0x6777",
         "pid": "0x2D33",
-        "device_version": "0.0.1"
+        "device_version": "0.0.1",
+        "force_nkro": true
     },
+    "build": {
+        "debounce_type":
+    },
+    "debounce": 15,
     "features": {
         "backlight": true,
         "bootmagic": true,

Zed60

diff --git a/keyboards/mechlovin/zed60/keyboard.json b/keyboards/mechlovin/zed60/keyboard.json
index 39a8ae7ea7..5f8bbb0b6c 100644
--- a/keyboards/mechlovin/zed60/keyboard.json
+++ b/keyboards/mechlovin/zed60/keyboard.json
@@ -6,15 +6,20 @@
     "usb": {
         "vid": "0x4D4C",
         "pid": "0x0602",
-        "device_version": "0.0.1"
+        "device_version": "0.0.1",
+        "force_nkro": true
     },
+    "build": {
+        "debounce_type": "sym_eager_pk"
+    },
+    "debounce": 15,
     "features": {
         "bootmagic": true,
-        "command": true,
-        "console": true,
+        "command": false,
+        "console": false,
         "extrakey": true,
         "mousekey": true,
-        "nkro": false,
+        "nkro": true,
         "rgblight": true
     },
     "matrix_pins": {

トラブルシューティング

容量超過でコンパイルに失敗する

以下の記事を参考に不要な機能を無効化してください.

補足: Chord Split Delayについて

キーの状態変化をレポート毎に1つずつしか送信できない実装をChord Splitと呼びます. Polling Rate 1,000 HzかつChord Splitである場合, 8キーを完全に同時押しした場合は最初に送信されるキーと最後に送信されるキーとで理論上7msの遅延が生じることになります.

現状, QMKはChord Splitです(市販の大抵のゲーミングキーボードはそうではありません). 詳細は以下を参照してください.

Chord Splitであることは同時押しで必ず遅延が生じることになり, 主に音ゲー用途で悪影響があることが懸念されますが, 実際どうでしょうか.

結論を述べると, RTINGSの検証を見るに,

  • QMK(を使用しているPCB)のChord Split Delayの実測値は仕様をほぼそのまま反映している.
    • ほぼ理論値, 1キーにつき1msである.
    • ただし, PCBの出来に左右されるところがあるのか若干遅いものもある.
  • 仕様上Chord Splitでないことと実際に生じるChord Split Delayは大して関係がない.
  • 市販の高性能を謳うゲーミングキーボードと仕様上Chord SplitであるQMKとで, 実測値には有意差がなかった.

ということになっているっぽいので, まあ特に気にしなくていいと思います.

以前纏めた表

以前書いた記事にあったRTINGSのデータを纏めた表をそのまま貼っておきます(2023-12時点のものです). 8K Chord Split Delayで昇順になっています.

KeyboardPolling Rate (Hz)Single-key Latency (Wired, ms)Single-key Latency (PCB Estimated, ms)4k Chord Split Delay (ms)8k Chord Split Delay (ms)Notes
8BitDo Retro Mechanical Keyboard1,0008.16.51.24.9
Keychron K3 (Version 2)1,00016.415.62.05.2光学スイッチ
Corsair K70 MAX8,0004.4N/A4.56.8磁気スイッチ, ラピッドトリガー
Keychron C1 Pro/C2 Pro (QMK)1,0009.47.72.97.2STM32L432KB (80MHz)/STM32F402RC (84MHz)
Razer Huntsman V3 Pro [Mini, TKL]1,0003.4N/A2.37.4光学スイッチ, ラピッドトリガー
Razer BlackWidow1,0004.93.13.67.5
ErgoDox EZ (QMK)1,0002.90.92.97.5ATmega32U4 (16MHz), sym_eager_pr (※), debounce time 30ms
Microsoft Bluetooth KeyboardN/AN/A20.71.27.7
Razer Huntsman1,0004.53.74.97.9光学スイッチ
Razer BlackWidow Elite1,0005.03.44.68.1
Mountain Everest Max1,00010.28.25.98.4
EVGA Z204,0002.21.45.58.6光学スイッチ
SteelSeries Apex Pro1,0004.1N/A5.98.7磁気スイッチ, ラピッドトリガー
Corsair K65 PRO MINI8,0000.80.05.18.7
ZSA Moonlander (QMK)1,00011.29.43.08.9STM32F303 (72MHz)
Corsair K70 PRO MINI WIRELESS8,0001.20.04.79.0
ASUS ROG Strix Flare II Animate8,0002.20.25.39.0
Razer BlackWidow V3 Pro1,0004.02.25.69.0
Corsair K70 RGB MK.21,0007.96.05.99.1
ROCCAT Vulkan II Mini Air1,0006.95.65.49.3
GLORIOUS GMMK1,00019.717.44.39.5
Razer Huntsman V28,0000.90.05.99.6光学スイッチ
Logitech G7151,0004.52.76.69.7
SteelSeries Apex 91,0003.02.06.89.7光学スイッチ
Keychron Q Pro Series [Q1 Pro, Q2 Pro, etc.] (QMK)1,0009.06.74.29.7STM32L432 (80MHz)
Razer BlackWidow V4 Pro8,0001.70.06.19.7
Razer BlackWidow V4 75%8,0001.60.04.59.8
Wooting two HE1,0001.9N/A5.99.8磁気スイッチ, ラピッドトリガー
IQUNIX F971,00015.713.85.39.9
Ducky Shine 71,00010.4N/A5.19.9
Wooting 60HE1,0001.8N/A4.710.0磁気スイッチ, ラピッドトリガー

※ ErgoDox EZはマトリクスが90度回転している(rowが実質columnである)ため, sym_eager_pr であっても弊害が少ないことに注意.