# キーボードマトリックスの仕組み

<!---
  original document: 0.13.15:docs/how_a_matrix_works.md
  git diff 0.13.15 HEAD -- docs/how_a_matrix_works.md | cat
-->

キーボードスイッチのマトリックスは行と列に配置されます。マトリックス回路がなければ、各スイッチはコントローラに直接配線する必要があります。

回路が行と列に配置されている場合、キーが押されると、列ワイヤが行ワイヤと接触し、回路が完成します。キーボードコントローラはこの閉回路を検知し、キー押下として登録します。

マイクロコントローラはファームウェアを介してセットアップされ、論理1を一度に1つずつ列に送信し、行から一度に全てを読み取ります - このプロセスはマトリックススキャンと呼ばれます。マトリックスはデフォルトでは電流の通過を許可しないたくさんの開いたスイッチです - ファームウェアはキーが押されていないものとしてこれを読み取ります。1つのキーを押すとすぐに、キースイッチが接続されている列から来ていた論理1がスイッチを通過して対応する行に渡されます - 以下の 2x2 の例を確認してください:

        Column 0 being scanned     Column 1 being scanned
                  x                                   x
                 col0     col1              col0     col1
                  |        |                 |        |
        row0 ---(key0)---(key1)    row0 ---(key0)---(key1)
                  |        |                 |        |
        row1 ---(key2)---(key3)    row1 ---(key2)---(key3)

`x` は関連付けられた列と行の値が1であるか、HIGH であることを表します。ここでは、キーが押されていないことが分かります。そのため `x` を取得する行はありません。1つのキースイッチの二つの接点はそのスイッチのある行と列にそれぞれ接続されていることに注意してください。

`key0` を押すと、`col0` は `row0` に接続されるため、ファームウェアがその行に対して受け取る値は `0b01` です (ここで `0b` はこれがビット値であることを意味します。つまり次の数字は全てビット(0または1)であり、その列のキーを表します)。この表記を使用して、キースイッチが押されたことを示し、列と行が接続されていることを示します:

        Column 0 being scanned     Column 1 being scanned
                  x                                   x
                 col0     col1              col0     col1
                  |        |                 |        |
      x row0 ---(-+-0)---(key1)    row0 ---(-+-0)---(key1)
                  |        |                 |        |
        row1 ---(key2)---(key3)    row1 ---(key2)---(key3)

`row0` には `x` があるため、値が1であることがわかります。全体として、`key0` が押された時にファームウェアが受信するデータは、

    col0: 0b01
    col1: 0b00
            │└row0
            └row1

一度に複数のキーを押し始めると問題が発生します。マトリックスをもう一度見ると、かなり明白になっているはずです:

        Column 0 being scanned     Column 1 being scanned
                  x                                   x
                 col0     col1              col0     col1
                  |        |                 |        |
      x row0 ---(-+-0)---(-+-1)  x row0 ---(-+-0)---(-+-1)
                  |        |                 |        |
      x row1 ---(key2)---(-+-3)  x row1 ---(key2)---(-+-3)

      Remember that this ^ is still connected to row1

これから取得されるデータは以下の通りです:

    col0: 0b11
    col1: 0b11
            │└row0
            └row1

4つ全てではなく、3つのキーしか押されていないため、これは正確ではありません。この挙動はゴーストと呼ばれ、このような奇妙なシナリオでのみ発生しますが、より大きなキーボードではより一般的です。これを回避する方法は、キースイッチの後に、行に接続する前にダイオードを配置することです。ダイオードは、電流が一方向にのみ流れるようにします。これにより、前の例で他の列と行がアクティブにならないようにします。ダイオードマトリックスをこのように表します;

        Column 0 being scanned     Column 1 being scanned
                    x                                   x
                  col0      col1              col0     col1
                    │        │                 |        │
                 (key0)   (key1)            (key0)   (key1)
                  ! │      ! │               ! |      ! │
        row0 ─────┴────────┘ │     row0 ─────┴────────┘ │
                    │        │                 |        │
                 (key2)   (key3)            (key2)   (key3)
                  !        !                 !        !
        row1 ─────┴────────┘       row1 ─────┴────────┘

実際の用途では、ダイオードの黒い線が行に面するように、キースイッチから離れるように配置されます - この場合の `!` はダイオードで、隙間は黒い線を表します。これを覚える良い方法は、以下のシンボルを考えることです: `>|`

次に、3つのキーを押して、ゴーストシナリオとなるものを実施します:

        Column 0 being scanned     Column 1 being scanned
                    x                                   x
                  col0      col1              col0     col1
                    │        │                 │        │
                 (┌─┤0)   (┌─┤1)            (┌─┤0)   (┌─┤1)
                  ! │      ! │               ! │      ! │
      x row0 ─────┴────────┘ │   x row0 ─────┴────────┘ │
                    │        │                 │        │
                 (key2)   (┌─┘3)            (key2)   (┌─┘3)
                  !        !                 !        !
        row1 ─────┴────────┘     x row1 ─────┴────────┘

全てが期待通りに動きます！これにより、以下のデータが取得されます:

    col0: 0b01
    col1: 0b11
            │└row0
            └row1

ファームウェアはこの正しいデータを使って、何をすべきかを、最終的には OS に送信する必要のある信号を検出できます。

参考文献:
- [Wikipedia の記事](https://en.wikipedia.org/wiki/Keyboard_matrix_circuit)
- [Deskthority の記事](https://deskthority.net/wiki/Keyboard_matrix)
- [Dave Dribin による Keyboard Matrix Help (2000)](https://www.dribin.org/dave/keyboard/one_html/)
- [PCBheaven による How Key Matrices Works](https://pcbheaven.com/wikipages/How_Key_Matrices_Works/) (アニメーションの例)
- [キーボードの仕組み - QMK ドキュメント](ja/how_keyboards_work.md)
