Settle the numpad layout: 25 keys, no encoder

Nav block across the top with an isolated inverted-T below it, operators in a
right-hand column beside 9/6/3 where a numpad puts them, and a 2u Enter plus
+ on a stepped thumb cluster spanning the three nav columns. Six by five,
~114 x 105 mm.

The volume encoder is dropped, which makes this a completely plain QMK
keyboard - no encoder, no pointing device, no consumer control. Firmware notes
and BOM updated; the numpad board is now ~$4.11 in parts.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
William Rickert
2026-09-01 08:59:04 -05:00
co-authored by Claude Opus 5
parent e555e802e1
commit 81abd43fdc
3 changed files with 75 additions and 72 deletions
+1 -2
View File
@@ -23,8 +23,7 @@ HALF-L/R,Split,D-ESD,1,ESD 5V bidirectional,PESD5V0S1BA,C2827694,SOD-323,Extende
HALF-L/R,Split,J3,1,3-pin header DNF,JST SH,-,-,Consigned,0.02,"*** DNF INSURANCE *** VCC/GND/DATA fallback if SBU proves flaky (bad cables). 3 pads cost nothing"
HALF-L/R,Split,-,-,SBU1+SBU2 TIE,-,-,-,-,0.00,"Tie A8 and B8 together on the board. SBU is CROSSED in the cable, so this makes it orientation-proof and doubles the conductor"
NUMPAD,DNF,J1/U3/R3/R4/R5,0,DO NOT POPULATE,-,-,-,-,0.00,"*** From the ALL block: numpad MCU has NO connector of its own. Its D+/D- route internally to hub downstream port 1. No connector = no ESD part and no CC resistors needed. Saves ~$0.19"
NUMPAD,Matrix,D1-D25,25,1N4148W,1N4148W,C81598,SOD-123,Basic,0.011,"25 keys: 16 numpad (no Num key) + 9 nav"
NUMPAD,Encoder,ENC1,1,EC11 detented,EC11L1525G01,C2991196,THT,Extended,1.27,"VOLUME - detented, which is what a stock EC11 already is. Occupies a 2u cell so a full-size knob fits. THT: hand-solder or JLC THT surcharge"
NUMPAD,Matrix,D1-D25,25,1N4148W,1N4148W,C81598,SOD-123,Basic,0.011,"25 keys: 14 numpad + 9 nav + 2 thumb (Enter 2u, +). No Num key"
NUMPAD,Hub,U4,1,USB2.0 4-port hub,CH334R,C4154405,QSOP-16-150mil,Extended,0.50,"Ports: 1=own MCU (internal FS) 2=left half 3=right half 4=spare"
NUMPAD,Hub,Y2,1,12MHz crystal,X322512MSB4SI,C9002,SMD3225-4P,Basic,0.101,"CH334 has built-in load caps - verify internal value vs this 20pF CL crystal; fit DNF cap pads"
NUMPAD,Hub,C12-C14,3,100nF 0402,CL05B104KO5NNNC,C1525,0402,Basic,0.006,"hub decoupling"
1 Board Section Ref Qty Value MPN LCSC Package JLC Unit USD Notes
23 HALF-L/R Split J3 1 3-pin header DNF JST SH - - Consigned 0.02 *** DNF INSURANCE *** VCC/GND/DATA fallback if SBU proves flaky (bad cables). 3 pads cost nothing
24 HALF-L/R Split - - SBU1+SBU2 TIE - - - - 0.00 Tie A8 and B8 together on the board. SBU is CROSSED in the cable, so this makes it orientation-proof and doubles the conductor
25 NUMPAD DNF J1/U3/R3/R4/R5 0 DO NOT POPULATE - - - - 0.00 *** From the ALL block: numpad MCU has NO connector of its own. Its D+/D- route internally to hub downstream port 1. No connector = no ESD part and no CC resistors needed. Saves ~$0.19
26 NUMPAD Matrix D1-D25 25 1N4148W 1N4148W C81598 SOD-123 Basic 0.011 25 keys: 16 numpad (no Num key) + 9 nav 25 keys: 14 numpad + 9 nav + 2 thumb (Enter 2u, +). No Num key
NUMPAD Encoder ENC1 1 EC11 detented EC11L1525G01 C2991196 THT Extended 1.27 VOLUME - detented, which is what a stock EC11 already is. Occupies a 2u cell so a full-size knob fits. THT: hand-solder or JLC THT surcharge
27 NUMPAD Hub U4 1 USB2.0 4-port hub CH334R C4154405 QSOP-16-150mil Extended 0.50 Ports: 1=own MCU (internal FS) 2=left half 3=right half 4=spare
28 NUMPAD Hub Y2 1 12MHz crystal X322512MSB4SI C9002 SMD3225-4P Basic 0.101 CH334 has built-in load caps - verify internal value vs this 20pF CL crystal; fit DNF cap pads
29 NUMPAD Hub C12-C14 3 100nF 0402 CL05B104KO5NNNC C1525 0402 Basic 0.006 hub decoupling
+45 -52
View File
@@ -1,59 +1,52 @@
<svg width="100%" viewBox="0 0 680 470" role="img" xmlns="http://www.w3.org/2000/svg">
<svg width="100%" viewBox="0 0 680 538" role="img" xmlns="http://www.w3.org/2000/svg">
<style>
text{font-family:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;fill:#1f2328}
.t{font-size:14px;font-weight:400}.ts{font-size:12px;font-weight:400}.th{font-size:14px;font-weight:500}
rect,circle{stroke-width:.6}
.c-teal rect,.c-teal circle{fill:#DFF3F0;stroke:#0F857B}.c-teal text{fill:#0A5750}
.c-purple rect,.c-purple circle{fill:#EDE7FA;stroke:#6D4FC4}.c-purple text{fill:#3A2775}
.c-coral rect,.c-coral circle{fill:#FCEAE4;stroke:#D8613F}.c-coral text{fill:#83321C}
.c-amber rect,.c-amber circle{fill:#FDF1DC;stroke:#C08A21}.c-amber text{fill:#6E4C08}
.c-gray rect,.c-gray circle{fill:#EFEFEF;stroke:#8A8A8A}.c-gray text{fill:#3A3A3A}
.ts{font-size:12px}.th{font-size:14px;font-weight:500}
rect{stroke-width:.6}
.c-teal rect{fill:#DFF3F0;stroke:#0F857B}.c-teal text{fill:#0A5750}
.c-purple rect{fill:#EDE7FA;stroke:#6D4FC4}.c-purple text{fill:#3A2775}
.c-coral rect{fill:#FCEAE4;stroke:#D8613F}.c-coral text{fill:#83321C}
@media (prefers-color-scheme:dark){
text{fill:#e6edf3}
.c-teal rect,.c-teal circle{fill:#0C4F49;stroke:#5FC9BF}.c-teal text{fill:#CFF0EC}
.c-purple rect,.c-purple circle{fill:#33246B;stroke:#A992EE}.c-purple text{fill:#E2D9FA}
.c-coral rect,.c-coral circle{fill:#6E2B18;stroke:#F0906F}.c-coral text{fill:#FBDDD2}
.c-amber rect,.c-amber circle{fill:#5C3F06;stroke:#E0AE4A}.c-amber text{fill:#F8E7C4}
.c-gray rect,.c-gray circle{fill:#3A3A3A;stroke:#9A9A9A}.c-gray text{fill:#E0E0E0}
.c-teal rect{fill:#0C4F49;stroke:#5FC9BF}.c-teal text{fill:#CFF0EC}
.c-purple rect{fill:#33246B;stroke:#A992EE}.c-purple text{fill:#E2D9FA}
.c-coral rect{fill:#6E2B18;stroke:#F0906F}.c-coral text{fill:#FBDDD2}
}
</style>
<title>Numpad board, settled layout</title>
<desc>Six columns by five rows. Arrows on the outer left column, page up and down beside them, the numpad on the right without a Num key, and a single volume encoder spanning two cells at the top.</desc>
<text class="th" x="18" y="24">Numpad board &#8212; settled</text>
<text class="ts" x="18" y="44">25 keys and one encoder. Arrows on the outside, no Num key, no scroll wheel.</text>
<g class="c-purple"><rect x="212" y="70" width="123" height="59" rx="4"/></g>
<g class="c-purple"><circle cx="274" cy="100" r="25"/></g>
<text class="ts" x="274" y="104" text-anchor="middle">Volume</text>
<g class="c-teal"><rect x="148" y="70" width="59" height="59" rx="4"/><text class="ts" x="178" y="104" text-anchor="middle">Del</text></g>
<g class="c-teal"><rect x="148" y="134" width="59" height="59" rx="4"/><text class="ts" x="178" y="168" text-anchor="middle">Home</text></g>
<g class="c-teal"><rect x="148" y="198" width="59" height="59" rx="4"/><text class="ts" x="178" y="232" text-anchor="middle"></text></g>
<g class="c-teal"><rect x="148" y="262" width="59" height="59" rx="4"/><text class="ts" x="178" y="296" text-anchor="middle"></text></g>
<g class="c-teal"><rect x="148" y="326" width="59" height="59" rx="4"/><text class="ts" x="178" y="360" text-anchor="middle"></text></g>
<g class="c-teal"><rect x="212" y="134" width="59" height="59" rx="4"/><text class="ts" x="242" y="168" text-anchor="middle">End</text></g>
<g class="c-teal"><rect x="212" y="198" width="59" height="59" rx="4"/><text class="ts" x="242" y="232" text-anchor="middle">PgUp</text></g>
<g class="c-teal"><rect x="212" y="262" width="59" height="59" rx="4"/><text class="ts" x="242" y="296" text-anchor="middle">PgDn</text></g>
<g class="c-teal"><rect x="212" y="326" width="59" height="59" rx="4"/><text class="ts" x="242" y="360" text-anchor="middle"></text></g>
<g class="c-coral"><rect x="276" y="134" width="59" height="59" rx="4"/><text class="ts" x="306" y="168" text-anchor="middle">7</text></g>
<g class="c-coral"><rect x="276" y="198" width="59" height="59" rx="4"/><text class="ts" x="306" y="232" text-anchor="middle">4</text></g>
<g class="c-coral"><rect x="276" y="262" width="59" height="59" rx="4"/><text class="ts" x="306" y="296" text-anchor="middle">1</text></g>
<g class="c-coral"><rect x="276" y="326" width="123" height="59" rx="4"/><text class="ts" x="338" y="360" text-anchor="middle">0</text></g>
<g class="c-coral"><rect x="340" y="70" width="59" height="59" rx="4"/><text class="ts" x="370" y="104" text-anchor="middle">/</text></g>
<g class="c-coral"><rect x="340" y="134" width="59" height="59" rx="4"/><text class="ts" x="370" y="168" text-anchor="middle">8</text></g>
<g class="c-coral"><rect x="340" y="198" width="59" height="59" rx="4"/><text class="ts" x="370" y="232" text-anchor="middle">5</text></g>
<g class="c-coral"><rect x="340" y="262" width="59" height="59" rx="4"/><text class="ts" x="370" y="296" text-anchor="middle">2</text></g>
<g class="c-coral"><rect x="404" y="70" width="59" height="59" rx="4"/><text class="ts" x="434" y="104" text-anchor="middle">*</text></g>
<g class="c-coral"><rect x="404" y="134" width="59" height="59" rx="4"/><text class="ts" x="434" y="168" text-anchor="middle">9</text></g>
<g class="c-coral"><rect x="404" y="198" width="59" height="59" rx="4"/><text class="ts" x="434" y="232" text-anchor="middle">6</text></g>
<g class="c-coral"><rect x="404" y="262" width="59" height="59" rx="4"/><text class="ts" x="434" y="296" text-anchor="middle">3</text></g>
<g class="c-coral"><rect x="404" y="326" width="59" height="59" rx="4"/><text class="ts" x="434" y="360" text-anchor="middle">.</text></g>
<g class="c-coral"><rect x="468" y="70" width="59" height="59" rx="4"/><text class="ts" x="498" y="104" text-anchor="middle">-</text></g>
<g class="c-coral"><rect x="468" y="134" width="59" height="123" rx="4"/><text class="ts" x="498" y="200" text-anchor="middle">+</text></g>
<g class="c-coral"><rect x="468" y="262" width="59" height="123" rx="4"/><text class="ts" x="498" y="328" text-anchor="middle">Ent</text></g>
<g class="c-teal"><rect x="18" y="414" width="13" height="13" rx="3"/></g>
<text class="ts" x="37" y="424">Nav · 9 keys</text>
<g class="c-coral"><rect x="223" y="414" width="13" height="13" rx="3"/></g>
<text class="ts" x="242" y="424">Numpad · 16 keys</text>
<g class="c-purple"><rect x="428" y="414" width="13" height="13" rx="3"/></g>
<text class="ts" x="447" y="424">Encoder · 2u, fits a real knob</text>
<text class="ts" x="18" y="452">Six by five units &#8212; about 114 by 95 mm on 19.05 mm spacing.</text>
<title>Numpad — no encoder, nav shifted up</title>
<desc>The volume encoder is gone. Home, End, Page Up, Page Down and Delete all move up one row, leaving a gap above the up arrow that separates the nav block from the arrow cluster.</desc>
<text class="th" x="18" y="24">Numpad &#8212; settled layout</text>
<text class="ts" x="18" y="44">25 keys, six columns by five rows. Nav block up top, isolated inverted-T, Enter and + on the thumb.</text>
<g class="c-teal"><rect x="148" y="88" width="58" height="58" rx="4"/><text class="ts" x="177" y="121" text-anchor="middle">Home</text></g>
<g class="c-teal"><rect x="212" y="88" width="58" height="58" rx="4"/><text class="ts" x="241" y="121" text-anchor="middle">End</text></g>
<g class="c-teal"><rect x="276" y="88" width="58" height="58" rx="4"/><text class="ts" x="305" y="121" text-anchor="middle">PgUp</text></g>
<g class="c-teal"><rect x="148" y="152" width="58" height="58" rx="4"/><text class="ts" x="177" y="185" text-anchor="middle">Del</text></g>
<g class="c-teal"><rect x="276" y="152" width="58" height="58" rx="4"/><text class="ts" x="305" y="185" text-anchor="middle">PgDn</text></g>
<g class="c-teal"><rect x="212" y="216" width="58" height="58" rx="4"/><text class="ts" x="241" y="249" text-anchor="middle"></text></g>
<g class="c-teal"><rect x="148" y="280" width="58" height="58" rx="4"/><text class="ts" x="177" y="313" text-anchor="middle"></text></g>
<g class="c-teal"><rect x="212" y="280" width="58" height="58" rx="4"/><text class="ts" x="241" y="313" text-anchor="middle"></text></g>
<g class="c-teal"><rect x="276" y="280" width="58" height="58" rx="4"/><text class="ts" x="305" y="313" text-anchor="middle"></text></g>
<g class="c-coral"><rect x="340" y="88" width="58" height="58" rx="4"/><text class="ts" x="369" y="121" text-anchor="middle">/</text></g>
<g class="c-coral"><rect x="404" y="88" width="58" height="58" rx="4"/><text class="ts" x="433" y="121" text-anchor="middle">*</text></g>
<g class="c-coral"><rect x="468" y="88" width="58" height="58" rx="4"/><text class="ts" x="497" y="121" text-anchor="middle">-</text></g>
<g class="c-coral"><rect x="340" y="152" width="58" height="58" rx="4"/><text class="ts" x="369" y="185" text-anchor="middle">7</text></g>
<g class="c-coral"><rect x="404" y="152" width="58" height="58" rx="4"/><text class="ts" x="433" y="185" text-anchor="middle">8</text></g>
<g class="c-coral"><rect x="468" y="152" width="58" height="58" rx="4"/><text class="ts" x="497" y="185" text-anchor="middle">9</text></g>
<g class="c-coral"><rect x="340" y="216" width="58" height="58" rx="4"/><text class="ts" x="369" y="249" text-anchor="middle">4</text></g>
<g class="c-coral"><rect x="404" y="216" width="58" height="58" rx="4"/><text class="ts" x="433" y="249" text-anchor="middle">5</text></g>
<g class="c-coral"><rect x="468" y="216" width="58" height="58" rx="4"/><text class="ts" x="497" y="249" text-anchor="middle">6</text></g>
<g class="c-coral"><rect x="340" y="280" width="58" height="58" rx="4"/><text class="ts" x="369" y="313" text-anchor="middle">1</text></g>
<g class="c-coral"><rect x="404" y="280" width="58" height="58" rx="4"/><text class="ts" x="433" y="313" text-anchor="middle">2</text></g>
<g class="c-coral"><rect x="468" y="280" width="58" height="58" rx="4"/><text class="ts" x="497" y="313" text-anchor="middle">3</text></g>
<g class="c-coral"><rect x="340" y="344" width="122" height="58" rx="4"/><text class="ts" x="401" y="377" text-anchor="middle">0</text></g>
<g class="c-coral"><rect x="468" y="344" width="58" height="58" rx="4"/><text class="ts" x="497" y="377" text-anchor="middle">.</text></g>
<g class="c-purple"><rect x="148" y="363" width="122" height="58" rx="4"/><text class="ts" x="209" y="396" text-anchor="middle">Enter</text></g>
<g class="c-purple"><rect x="276" y="373" width="58" height="58" rx="4"/><text class="ts" x="305" y="406" text-anchor="middle">+</text></g>
<g class="c-teal"><rect x="18" y="466" width="13" height="13" rx="3"/></g>
<text class="ts" x="37" y="476">Nav &#183; 9</text>
<g class="c-coral"><rect x="188" y="466" width="13" height="13" rx="3"/></g>
<text class="ts" x="207" y="476">Numpad &#183; 14</text>
<g class="c-purple"><rect x="358" y="466" width="13" height="13" rx="3"/></g>
<text class="ts" x="377" y="476">Thumb &#183; 2</text>
<text class="ts" x="18" y="506">About 114 by 105 mm. The thumb pair spans exactly the three nav columns; three cells empty around the arrows.</text>
</svg>

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

+29 -18
View File
@@ -41,16 +41,27 @@ either.
|---|---|---|---|
| `Schematics/Left` | 1 | **34** | MCU, matrix, USB-C, SBU split link |
| `Schematics/Right` | 1 | **41** | MCU, matrix, USB-C, SBU split link |
| `Schematics/Numpad` | 1 | 25 (16 numpad + 9 nav) | MCU, matrix, 1 encoder, **CH334R hub**, 3 downstream ports |
| `Schematics/Numpad` | 1 | **25** (14 numpad + 9 nav + 2 thumb) | MCU, matrix, **CH334R hub**, 3 downstream ports |
**Numpad layout is settled** — see `Documents/numpad-layout.svg`, and
`Documents/three-board-overview.svg` for all three at the same scale. Six columns by five
rows, ~114 × 95 mm. Arrows take the **outer** left column on the principle that
the most-used keys go furthest out, PgUp/PgDn sit beside them, and Del/Home/End
fill the rest of the two nav columns. **No Num key** — the firmware resolves
keypad vs number-row at press time, so the pad never needed one. The 2u that
frees up at the top holds the single volume encoder, which means a full-size
knob fits rather than two cramped ones colliding at 19.05 mm centres.
`Documents/three-board-overview.svg` for all three at the same scale. Six
columns by five rows, ~114 × 105 mm, **25 keys and no encoder**.
- **Nav block across the top**: Home/End/PgUp over Del/PgDn, with the arrows in
a standard **inverted-T** isolated below by three empty cells — the same
breathing room a 104 gives them. Del sits two rows above `←` with a gap
between, so the destructive key is never adjacent to the one you hit blind.
- **Numpad on the right**: digits in a 3×3 with `0` as a 2u, and `/ * ` in a
right-hand column beside 9/6/3, where a full-size numpad puts its operators.
- **`Enter` (2u) and `+` on a stepped thumb cluster**, spanning exactly the
three nav columns. That's what lets the digits drop from four columns to
three and keeps the board at six wide.
- **No Num key** — the firmware resolves keypad vs number-row at press time, so
the pad never needed one.
- **No encoder.** Dropped along with the scroll wheel; volume lives on a layer
or on the halves' function row. This makes the numpad a completely plain QMK
keyboard — no encoder, no pointing device, just a matrix. It is the simplest
of the three boards by a distance, and ~$4.11 in parts.
Cabling:
@@ -302,19 +313,19 @@ Plan is belt-and-braces:
Only eleven keys need this (19, 0, `.`). `KP_SLASH`/`ASTERISK`/`MINUS`/`PLUS`/
`ENTER` mean the same thing either way.
**One encoder, volume only.** The scroll wheel was dropped — no good physical
implementation. That removes more than it looks like:
**No encoder anywhere.** The scroll wheel went first, then the volume knob. That
strips a surprising amount out of the numpad's firmware:
- No `POINTING_DEVICE_ENABLE`, no `MOUSEKEY_ENABLE`, no hi-res scroll resolution
multiplier. **The numpad stops enumerating as a mouse entirely** — it's a
keyboard plus consumer control and nothing else.
- No `ENCODER_ENABLE`, no `POINTING_DEVICE_ENABLE`, no `MOUSEKEY_ENABLE`, no
hi-res scroll multiplier.
- The numpad **enumerates as a plain keyboard and nothing else** — no mouse
interface, no consumer-control interface unless media keys go on a layer.
- One fewer USB endpoint, which matters because the L103's USBFS has eight and
QMK's composite device was going to be tight against that.
- The detentless-EC11 sourcing risk is gone. A stock EC11 is detented, which is
exactly what volume wants, so `C2991196` is simply correct with nothing to
verify.
QMK's composite device was tight against that.
- The detentless-EC11 sourcing risk is gone, because there is no EC11.
Rules file is now just `ENCODER_ENABLE` + `EXTRAKEY_ENABLE`.
Volume has to live on a layer, or on the halves' function row. Decide that
rather than discover it.
---