Skip to the content
PCBKitNew board
2 layers45 × 55 mmKnuckles controller, the printed circuit board in 3D

Knuckles controller

fcoury/knuckles6

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

10

README

README.md

Knuckles

Knuckles echidna badge and wordmark

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.

Knuckles with case

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/.

Compact 18.5 mm wireless PCB with the Knuckles badge and wordmark

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:

sh
git clone --recursive https://github.com/fcoury/knuckles.git
cd knuckles
npm install
npm run build

npm 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:

sh
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.5

Plates, 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:

  1. Cleans previous outputs.
  2. Runs Ergogen to generate the unrouted board and plates.
  3. Exports renders and Gerbers for the plates and unrouted board with KiBot.
  4. Exports a DSN, autoroutes it with Freerouting, and imports the SES back into KiCad.
  5. Runs KiBot again on the autorouted board.

Other entry points:

  • ./rebuild.sh re-exports and autoroutes the boards already in pcbs/ without running Ergogen.
  • npm run route autoroutes only knuckles_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, needs fswatch) 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.footprint and 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 mcu footprint 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.jscad and the outlines/_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

PathContents
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

  • --spacing overrides KNUCKLES_SPACING, which overrides the config default. The YAML is never rewritten. pcbs/build-info.json records 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. Use npm run build -- --output if you want them kept apart.
  • ./rebuild.sh routes whatever board is already in pcbs/ and keeps its spacing.
  • ergogen/output/pcbs/ contains old snapshots that builds don't update.

License

MIT. See LICENSE.

Credits

  • Ergogen and its community.
  • Footprints from ceoloide (ergogen/footprints/ceoloide) and related authors.
  • Freerouting for autorouting, KiBot and PCBDraw for renders and exports.

Parts

47
QtyValueFootprintReferences
710kKnuckles:R_0603_1608MetricR3, R6, R7, R8, R9, R15, R16
522uFKnuckles:C_0805_2012MetricC2, C6, C8, C10, C11
4100nFKnuckles:C_0603_1608MetricC1, C9, C12, C13
31MKnuckles:R_0603_1608MetricR13, R14, R17
2100kKnuckles:R_0603_1608MetricR10, R11
22.2uFKnuckles:C_0603_1608MetricC4, C5
227RKnuckles:R_0603_1608MetricR18, R19
22N7002Knuckles:SOT-23Q2, Q3
24.7kKnuckles:R_0603_1608MetricR4, R5
25.1kKnuckles:R_0603_1608MetricR1, R2
10RKnuckles:R_0603_1608MetricR12
11.5uH SWPA3015S1R5NTKnuckles:L_Sunlord_SWPA3015SL1
14.7uFKnuckles:C_0603_1608MetricC3
1AO3401AKnuckles:SOT-23Q1
1BQ25186DLHRKnuckles:TI_WSON_DLH0010AU2
1External 10k NTC padsKnuckles:NTC_WirePadsJ6
1MDBT50Q-1MV2Knuckles:Raytac_MDBT50QU1
1Matrix bring-up headerKnuckles:PinHeader_1x12_P2.54mm_VerticalJ4
1S2B-PH-SM4-TB(LF)(SN)Knuckles:JST_PH_S2B-PH-SM4-TB_1x02-1MP_P2.00mm_HorizontalJ2
1SKRPANE010Knuckles:SKRPANE010SW2
1SM04B-SRSS-TB(LF)(SN)Knuckles:JST_SH_SM04B-SRSS-TB_1x04-1MP_P1.00mm_HorizontalJ3
1SSSS811101Knuckles:SSSS811101SW1
1SWD pogo interfaceKnuckles:SWD_2x3_P1.27_NoHolesJ5
1TPS63031DSKRKnuckles:WSON-10-1EP_2.5x2.5mm_P0.5mm_EP1.2x2mmU3
1TYPE-C-31-M-12Knuckles:USB_C_Receptacle_HRO_TYPE-C-31-M-12J1
1USBLC6-2SC6Knuckles:SOT-23-6U4

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 mmKnuckles, the printed circuit board in 3D

    Knuckles

    fcoury/knuckles

    An open-source, wireless column-staggered ergonomic keyboard.

    152 parts6MIT
  • 2 layers130.3 × 107.9 mmKnuckles wireless autorouted, the printed circuit board in 3D

    Knuckles wireless autorouted

    fcoury/knuckles

    An open-source, wireless column-staggered ergonomic keyboard.

    121 parts6MIT
  • 4 layers137.3 × 113.5 mmKnuckles integrated right, the printed circuit board in 3D

    Knuckles integrated right

    fcoury/knuckles

    An open-source, wireless column-staggered ergonomic keyboard.

    106 parts6MIT

Similar boards

  • 2 layers35 × 100 mmWalkieTalkie, the printed circuit board in 3D

    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 mmTrinketcore, the printed circuit board in 3D

    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 mmOwl mainboard, the printed circuit board in 3D

    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 mmVW MTC1, the printed circuit board in 3D

    VW MTC1

    Sajeevanveeriah/Ataxia-Monitor

    Real-Time Ataxia Monitor

    154 partsUnlicense
  • 4 layers78 × 78 mmTiltBox Voice A, the printed circuit board in 3D

    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 mmPmd tracker, the printed circuit board in 3D

    Pmd tracker

    ollielarkins/pmd-tracker

    Wearable rugby performance tracker: nRF52840 + Zephyr firmware, React Native companion app

    31 parts
  • 2 layers344.7 × 123.1 mmAthena, the printed circuit board in 3D

    Athena

    BenjaminJAnderson/Orthodox

    557 parts1