

Knuckles controller
An open-source, wireless column-staggered ergonomic keyboard.
- Size
- 45 × 55 mm
- Copper layers
- 2
- Thickness
- 1.6 mm
- Parts
- 47
- Nets
- 42
- Pads
- 232
- Tracks, vias
- 0, 0
- Pours
- 1
- Routed
- Not yet
- KiCad
- KiCad 8.0 (file 20240108)
- Created
- 1 Mar 2025
- Updated
- 18 Oct 2026
Overview
Knuckles controller is an open-source printed circuit board by fcoury, from the fcoury/knuckles repository on GitHub, published under the MIT licence. It is a 2-layer board of 45 × 55 mm with 47 parts on 42 nets.
It is built around the MDBT50Q-1MV2, TPS63031DSKR and BQ25186DLHR, with the USBLC6-2SC6, AO3401A and S2B-PH-SM4-TB(LF)(SN) among its other parts. Its parts include 19 resistors, 12 capacitors, 6 connectors, 4 ICs and 3 transistors. It belongs with the keyboards and input boards and the nRF52 and nRF5x boards of this library.
Main components
10MDBT50Q-1MV2
SMD-61PSMD-61P Bluetooth Modules ROHSRAYTACBluetooth ModulesTPS63031DSKR
SON-10-EP(2.5x2.5)-40℃~+125℃@(TJ) 1 1.8V~5.5V 2.4MHz 25uA 3.3V 900mA Buck-Boost Buck-Boost Built-in Fixed Yes SON-10-EP(2.5x2.5) DC-DC Converters ROHSTexas InstrumentsDC-DC ConvertersBQ25186DLHR
WSON-10-40℃~+125℃ 1 15nA 1A 2V 3.6V~18V 4.65V Charging IC I2C Lithium Battery、LiFePO4 Battery Support Support WSON-10 Battery Management ROHSTexas InstrumentsBattery ManagementUSBLC6-2SC6
SOT-23-60.35pF、0.8pF 100nA 150W@8/20us 15V 2 5V 6A@8/20us 6V ESD SOT-23-6 ESD and Surge Protection (TVS/ESD) ROHSUMWESD And Surge Protection (TVS/ESD)AO3401A
SOT-231 P-Channel 14nC@10V 30V 47mΩ@10V、60mΩ@4.5V、85mΩ@2.5V 4A 55pF 645pF 80pF 900mV SOT-23 MOSFETs ROHSAlpha & Omega SemiconductorMOSFETsS2B-PH-SM4-TB(LF)(SN)
SMD,P=2mm,卧贴-25℃~+85℃ 1 100V 1x2P 2 2A 2P 2mm 5.5mm 7.9mm 8.6mm Auxiliary Solder Pin Beige Copper alloy PA PH Surface Mount, Right Angle Tin UL94V-0 SMD,P=2mm,卧贴 Wire To Board Connector ROHSJSTWire To Board ConnectorSKRPANE010
SMD-4P,4.2x3.2mm-40℃~+90℃ 1,000,000 cycles 1.57N 16V 2.5mm 3.2mm 4.2mm J-Lead Oval Button SPST Surface Mount,Vertical Without Bracket SMD-4P,4.2x3.2mm Tactile Switches ROHSALPSALPINETactile SwitchesSM04B-SRSS-TB(LF)(SN)
SMD,P=1mm,卧贴-25℃~+85℃ 1 1A 1mm 1x4P 2.9mm 4 4.32mm 4P 50V 6mm Auxiliary Solder Pin Copper alloy PA SH Surface Mount, Right Angle Tin UL94V-0 White SMD,P=1mm,卧贴 Wire To Board Connector ROHSJSTWire To Board ConnectorSSSS811101
SMD-40℃~+85℃ 10,000 cycles 300mA 4.1mm 5V Rectangular Columnar SMD(SMT) Tab SPDT Surface Mount, Right Angle SMD Slide Switches ROHSALPSALPINESlide SwitchesTYPE-C-31-M-12
SMD-30℃~+80℃ 1 10,000 cycles 16P 20V 5A 7.35mm Female Surface Mount, Right Angle Type-C SMD USB Connectors ROHSHRO ElectronicsUSB Connectors
README
README.mdKnuckles
There are a lot of split keyboards out there, but most of the ones that piqued my interest don't have a number row, and I really like having one. I also wanted a slim ergo split that feels somewhat like a Magic Keyboard. Knuckles is my attempt at both.

Each half has 27 keys: a column-staggered 6×4 grid that includes the number row, plus a three-key thumb fan. It uses Kailh PG1316S low-profile switches on reversible footprints, a nice!nano controller, a JST-PH battery connector, and a power switch. The controller area also fits the HolyKeebs TPS43 touchpad module.
The first wireless PCB was ordered from JLCPCB on 2026-10-18. The exact files
are archived in manufacturing/.

ergogen/config.yaml also still defines the original wired knuckles board
(TRRS, small display). It's no longer supported. knuckles_wireless is the
board to build.
A separate integrated nRF52840 revision adds on-board USB, charging and radio circuitry in dedicated left/right layouts. Its retained routed layouts and experimental firmware are engineering prototypes; module sourcing, manufacturing review and bench validation remain release gates. The normal build continues to use the nice!nano design.
Build it
You'll need Node.js 18+ (CI uses Node 20) and Git. Footprints live in a submodule, so clone recursively:
git clone --recursive https://github.com/fcoury/knuckles.git
cd knuckles
npm install
npm run buildnpm run build runs Ergogen on ergogen/config.yaml and writes the PCBs,
plates, outlines, and bottom tray STL. npm run debug does the same with
Ergogen's debug output. npm run watch:build and npm run watch:debug rebuild
whenever the YAML or scripts change.
Key spacing
The default is 18.5 mm center to center. That's the compact layout and the one that was ordered. 19.5 mm is also available:
npm run build -- --spacing 19.5
# Keep both layouts side by side
npm run debug -- --spacing 18.5 --output build/18.5
npm run debug -- --spacing 19.5 --output build/19.5Plates, holes, the silkscreen artwork, and the bottom tray all follow the
selected spacing. Run npm run build -- --help for all options. The
gotchas cover how spacing interacts with the other scripts.
Full pipeline
The full pipeline also needs Docker. It runs KiCad 8, KiBot, and Freerouting in containers, pulling the images on first run.
./build.sh:
- Cleans previous outputs.
- Runs Ergogen to generate the unrouted board and plates.
- Exports renders and Gerbers for the plates and unrouted board with KiBot.
- Exports a DSN, autoroutes it with Freerouting, and imports the SES back into KiCad.
- Runs KiBot again on the autorouted board.
Other entry points:
./rebuild.shre-exports and autoroutes the boards already inpcbs/without running Ergogen.npm run routeautoroutes onlyknuckles_wireless. It prunes dead-end traces and tries up to three times. A route is accepted only if KiCad reports no unconnected items, no dangling tracks, and no DRC errors../watch.sh(macOS, needsfswatch) regenerates the PCB when the config changes and opens the result.
Manufacturing
Upload the KiBot ZIP from ergogen/output/gerbers/knuckles_wireless/ to
JLCPCB. Manufacturing output comes only from
pcbs/knuckles_wireless_autorouted.kicad_pcb. The KiBot configs
(kibot/default.kibot.yaml, kibot/boards.kibot.yaml) are tuned for JLCPCB.
The board uses a 0.25 mm copper-to-edge clearance for routed outlines.
Local builds and CI both route through scripts/autoroute.sh, with the same
KiCad image, Freerouting 2.1.0 JAR, rules, and optimizer settings. Freerouting
can still produce different trace geometry from run to run. That's why the
pipeline checks connectivity and DRC instead of comparing files byte for byte.
Each board that gets ordered goes in its own dated folder under
manufacturing/. Don't modify those files once they're archived.
CI
.github/workflows/build.yaml runs the full pipeline for both spacings. Each
run uploads a knuckles-18.5mm and a knuckles-19.5mm artifact containing
cases, Gerbers, images, outlines, and PCBs. npm test runs real builds of both
layouts and checks spacing selection, the generated outputs, and rejection of
invalid values.
Customizing
Everything starts in ergogen/config.yaml:
- Layout: the key matrix and thumb fan are under
points.zones.*(spacing, splay, stagger). - Switches: set
meta.footprintand pick a preset (mx,choc_v1,choc_v2, or the low-profile reversible footprints). - Wiring: column and row nets are assigned per zone. MCU pins are mapped in
the
mcufootprint section. - Touchpad: the TPS43 adapter sits on top of the nice!nano and uses its VCC, GND, SDA, and SCL pins, so the PCB doesn't need its own touchpad footprint.
- Case: edit
cases/knuckles_bottom_tray.jscadand theoutlines/_bottom_case*outlines to change walls and cutouts.
KiCad project settings in pcbs/ are generated, so edit
kicad/projects/knuckles_wireless.kicad_pro instead. The build copies it next
to the board.
The silkscreen badge and wordmark are documented in
artwork/knuckles/.
Repository layout
| Path | Contents |
|---|---|
ergogen/ | Ergogen config, footprints submodule, generated images and Gerbers |
pcbs/ | Generated KiCad boards and plates; autoroute/<board>/ holds DSN, SES, router log, and DRC report |
outlines/ | DXF/SVG outlines for the PCB, plates, and case |
cases/ | JSCAD bottom tray and generated STL; thin/ has slim case prototypes for older 18.5 mm boards |
kicad/projects/ | Canonical KiCad project settings |
kibot/ | KiBot configs and DSN/SES helper scripts |
freerouting/ | Autorouter rules and JAR |
hardware/integrated-controller/ | Opt-in integrated controller PCB and firmware prototypes, routed layouts and engineering checks |
manufacturing/ | Archived files for each ordered board |
artwork/ | Badge and wordmark sources and PCB renders |
images/ | Reference renders of the plates and controller overlay |
scripts/ | Build, autoroute, artwork, and case scripts |
Gotchas
--spacingoverridesKNUCKLES_SPACING, which overrides the config default. The YAML is never rewritten.pcbs/build-info.jsonrecords which spacing was used.- Changing spacing means you need matching plates and a matching case. Don't mix routed boards or Gerbers from different spacing builds.
./build.sh(KNUCKLES_SPACING=19.5 ./build.sh) always writes to the root output folders. Usenpm run build -- --outputif you want them kept apart../rebuild.shroutes whatever board is already inpcbs/and keeps its spacing.ergogen/output/pcbs/contains old snapshots that builds don't update.
License
MIT. See LICENSE.
Credits
Parts
47| Qty | Value | Footprint | References |
|---|---|---|---|
| 7 | 10k | Knuckles:R_0603_1608Metric | R3, R6, R7, R8, R9, R15, R16 |
| 5 | 22uF | Knuckles:C_0805_2012Metric | C2, C6, C8, C10, C11 |
| 4 | 100nF | Knuckles:C_0603_1608Metric | C1, C9, C12, C13 |
| 3 | 1M | Knuckles:R_0603_1608Metric | R13, R14, R17 |
| 2 | 100k | Knuckles:R_0603_1608Metric | R10, R11 |
| 2 | 2.2uF | Knuckles:C_0603_1608Metric | C4, C5 |
| 2 | 27R | Knuckles:R_0603_1608Metric | R18, R19 |
| 2 | 2N7002 | Knuckles:SOT-23 | Q2, Q3 |
| 2 | 4.7k | Knuckles:R_0603_1608Metric | R4, R5 |
| 2 | 5.1k | Knuckles:R_0603_1608Metric | R1, R2 |
| 1 | 0R | Knuckles:R_0603_1608Metric | R12 |
| 1 | 1.5uH SWPA3015S1R5NT | Knuckles:L_Sunlord_SWPA3015S | L1 |
| 1 | 4.7uF | Knuckles:C_0603_1608Metric | C3 |
| 1 | AO3401A | Knuckles:SOT-23 | Q1 |
| 1 | BQ25186DLHR | Knuckles:TI_WSON_DLH0010A | U2 |
| 1 | External 10k NTC pads | Knuckles:NTC_WirePads | J6 |
| 1 | MDBT50Q-1MV2 | Knuckles:Raytac_MDBT50Q | U1 |
| 1 | Matrix bring-up header | Knuckles:PinHeader_1x12_P2.54mm_Vertical | J4 |
| 1 | S2B-PH-SM4-TB(LF)(SN) | Knuckles:JST_PH_S2B-PH-SM4-TB_1x02-1MP_P2.00mm_Horizontal | J2 |
| 1 | SKRPANE010 | Knuckles:SKRPANE010 | SW2 |
| 1 | SM04B-SRSS-TB(LF)(SN) | Knuckles:JST_SH_SM04B-SRSS-TB_1x04-1MP_P1.00mm_Horizontal | J3 |
| 1 | SSSS811101 | Knuckles:SSSS811101 | SW1 |
| 1 | SWD pogo interface | Knuckles:SWD_2x3_P1.27_NoHoles | J5 |
| 1 | TPS63031DSKR | Knuckles:WSON-10-1EP_2.5x2.5mm_P0.5mm_EP1.2x2mm | U3 |
| 1 | TYPE-C-31-M-12 | Knuckles:USB_C_Receptacle_HRO_TYPE-C-31-M-12 | J1 |
| 1 | USBLC6-2SC6 | Knuckles:SOT-23-6 | U4 |
Questions
How big is the Knuckles controller PCB?
It measures 45 × 55 mm and has 2 copper layers, 1.6 mm thick.
What parts does the Knuckles controller use?
47 parts, built around the MDBT50Q-1MV2, TPS63031DSKR, BQ25186DLHR and USBLC6-2SC6. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.
Where can I download the Knuckles controller KiCad files?
From the fcoury/knuckles repository on GitHub, at the commit this page was made from: the board is hardware/integrated-controller/output/knuckles_controller.kicad_pcb and its schematic hardware/integrated-controller/output/core.kicad_sch. PCBKit opens the board in the browser, with nothing to install.
Can I use the Knuckles controller design in my own project?
Its repository publishes it under the MIT licence: you may reuse it on that licence's terms (keep the author's notice, and for a copyleft licence share your changes alike).
More from fcoury/knuckles
3- 2 layers130.3 × 107.9 mm

- 2 layers130.3 × 107.9 mm

Knuckles wireless autorouted
fcoury/knuckles
An open-source, wireless column-staggered ergonomic keyboard.
121 parts6MIT - 4 layers137.3 × 113.5 mm

Knuckles integrated right
fcoury/knuckles
An open-source, wireless column-staggered ergonomic keyboard.
106 parts6MIT
Similar boards
- 2 layers35 × 100 mm

WalkieTalkie
GuzziFlipFlops/ESP32-Walkie-Talkie
An open source ESPNOW based walkie talkie with a 600 meter tested distance, with an OLED and multiple buttons to interact with
66 parts7MIT - 4 layers40 × 60 mm

Trinketcore
alph4345/test
TrinketCore puts everything a small rechargeable gadget needs on one 40 × 60 mm board, ready to order assembled from PCBWay:
113 parts - 4 layers61.8 × 79.8 mm

Owl mainboard
danieltyukov/owltunes
Owl-shaped Spotify remote for your desk and pocket: ESP32-S3 firmware, LVGL UI, KiCad PCB, 3D-printed enclosure, and owl v0 on the Waveshare AMOLED kit
107 partsMIT - 4 layers90 × 60 mm

- 4 layers78 × 78 mm

TiltBox Voice A
Tom-Michiels/TiltBox
A handheld retro game console with tilt controls, featuring 9 games on an 8x8 LED matrix. Designed at maakleerplek
165 parts - 4 layers45 × 30 mm

Pmd tracker
ollielarkins/pmd-tracker
Wearable rugby performance tracker: nRF52840 + Zephyr firmware, React Native companion app
31 parts - 2 layers344.7 × 123.1 mm

- 2 layers344.7 × 123.1 mm
