<spanclass="line"><span> row1 ---(key2)---(key3) row1 ---(key2)---(key3)</span></span></code></pre></div><p>The <code>x</code> represents that the column/row associated has a value of 1, or is HIGH. Here, we see that no keys are being pressed, so no rows get an <code>x</code>. For one keyswitch, keep in mind that one side of the contacts is connected to its row, and the other, its column.</p><p>When we press <code>key0</code>, <code>col0</code> gets connected to <code>row0</code>, so the values that the firmware receives for that row is <code>0b01</code> (the <code>0b</code> here means that this is a bit value, meaning all of the following digits are bits - 0 or 1 - and represent the keys in that column). We'll use this notation to show when a keyswitch has been pressed, to show that the column and row are being connected:</p><divclass="language- vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang"></span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><span> Column 0 being scanned Column 1 being scanned</span></span>
<spanclass="line"><span> x row0 ---(-+-0)---(key1) row0 ---(-+-0)---(key1)</span></span>
<spanclass="line"><span> | | | |</span></span>
<spanclass="line"><span> row1 ---(key2)---(key3) row1 ---(key2)---(key3)</span></span></code></pre></div><p>We can now see that <code>row0</code> has an <code>x</code>, so has the value of 1. As a whole, the data the firmware receives when <code>key0</code> is pressed is:</p><divclass="language- vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang"></span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><span>col0: 0b01</span></span>
<spanclass="line"><span>col1: 0b00</span></span>
<spanclass="line"><span> │└row0</span></span>
<spanclass="line"><span> └row1</span></span></code></pre></div><p>A problem arises when you start pressing more than one key at a time. Looking at our matrix again, it should become pretty obvious:</p><divclass="language- vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang"></span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><span> Column 0 being scanned Column 1 being scanned</span></span>
<spanclass="line"><span> x row0 ---(-+-0)---(-+-1) x row0 ---(-+-0)---(-+-1)</span></span>
<spanclass="line"><span> | | | |</span></span>
<spanclass="line"><span> x row1 ---(key2)---(-+-3) x row1 ---(key2)---(-+-3)</span></span>
<spanclass="line"><span></span></span>
<spanclass="line"><span> Remember that this ^ is still connected to row1</span></span></code></pre></div><p>The data we get from that is:</p><divclass="language- vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang"></span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><span>col0: 0b11</span></span>
<spanclass="line"><span>col1: 0b11</span></span>
<spanclass="line"><span> │└row0</span></span>
<spanclass="line"><span> └row1</span></span></code></pre></div><p>Which isn't accurate, since we only have 3 keys pressed down, not all 4. This behavior is called ghosting, and only happens in odd scenarios like this, but can be much more common on a bigger keyboard. The way we can get around this is by placing a diode after the keyswitch, but before it connects to its row. A diode only allows current to pass through one way, which will protect our other columns/rows from being activated in the previous example. We'll represent a dioded matrix like this;</p><divclass="language- vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang"></span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><span> Column 0 being scanned Column 1 being scanned</span></span>
<spanclass="line"><span> row1 ─────┴────────┘ row1 ─────┴────────┘</span></span></code></pre></div><p>In practical applications, the black line of the diode will be placed facing the row, and away from the keyswitch - the <code>!</code> in this case is the diode, where the gap represents the black line. A good way to remember this is to think of this symbol: <code>>|</code></p><p>Now when we press the three keys, invoking what would be a ghosting scenario:</p><divclass="language- vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang"></span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><span> Column 0 being scanned Column 1 being scanned</span></span>
<spanclass="line"><span> row1 ─────┴────────┘ x row1 ─────┴────────┘</span></span></code></pre></div><p>Things act as they should! Which will get us the following data:</p><divclass="language- vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang"></span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><span>col0: 0b01</span></span>
<spanclass="line"><span>col1: 0b11</span></span>
<spanclass="line"><span> │└row0</span></span>
<spanclass="line"><span> └row1</span></span></code></pre></div><p>The firmware can then use this correct data to detect what it should do, and eventually, what signals it needs to send to the OS.</p><p>Further reading:</p><ul><li><ahref="https://en.wikipedia.org/wiki/Keyboard_matrix_circuit"target="_blank"rel="noreferrer">Wikipedia article</a></li><li><ahref="https://deskthority.net/wiki/Keyboard_matrix"target="_blank"rel="noreferrer">Deskthority article</a></li><li><ahref="https://www.dribin.org/dave/keyboard/one_html/"target="_blank"rel="noreferrer">Keyboard Matrix Help by Dave Dribin (2000)</a></li><li><ahref="https://pcbheaven.com/wikipages/How_Key_Matrices_Works/"target="_blank"rel="noreferrer">How Key Matrices Works by PCBheaven</a> (animated examples)</li><li><ahref="./how_keyboards_work">How keyboards work - QMK documentation</a></li></ul></div></div></main><footerclass="VPDocFooter"data-v-39a288b8data-v-09de1c0f><!--[--><!--]--><!----><navclass="prev-next"data-v-09de1c0f><divclass="pager"data-v-09de1c0f><aclass="VPLink link pager-link prev"href="/how_keyboards_work"data-v-09de1c0f><!--[--><spanclass="desc"data-v-09de1c0f>Previous page</span><spanclass="title"data-v-09de1c0f>How Keyboards Work</span><!--]--></a></div><divclass="pager"data-v-09de1c0f><aclass="VPLink link pager-link next"href="/understanding_qmk"data-v-09de1c0f><!--[--><spanclass="desc"data-v-09de1c0f>Next page</span><spanclass="title"data-v-09de1c0f>Understanding QMK</span><!--]--></a></div></nav></footer><!--[--><!--]--></div></div></div><!--[--><!--]--></div></div><!----><!--[--><!--]--></div></div>