
Main panel
google/mozc-devices
Circuit diagrams and firmware source code for Gboard DIY keyboards

KSP MacroPad repo for the HackClub stardance project
KSP MacroPad is an open-source printed circuit board by MintyTheCoder, from the MintyTheCoder/KSP-MacroPad repository on GitHub. It is a 2-layer board of 100 × 100 mm with 71 parts on 61 nets, routed with 712 tracks and 43 vias.
It is built around the SK6812MINI-E. Its parts include 36 diodes, 17 switches, 9 resistors, 1 capacitor and 1 IC. It belongs with the keyboards and input boards of this library.
A custom macropad built for Kerbal Space Program, made for Hack Club's Stardance Challenge.
16 macro keys and 2 rotary encoders on a custom PCB, driven by a Seeed XIAO RP2040. The keys don't send keystrokes. They trigger full flight procedures (launch, gravity turn, circularize, rendezvous, suicide burn, an interplanetary autopilot) that a companion KSP mod runs inside the game. The mod talks to the pad over USB serial, and sends state back for per-key RGB LEDs, underglow, and a 128x32 OLED.
The key matrix is read through a resistor ladder on 4 ADC pins instead of 8 GPIO pins, which is what makes everything fit on the XIAO's 11 pins.

![]() | ![]() |
![]() | ![]() |
A normal 4x4 matrix needs 8 pins, and after the encoders, OLED and LEDs there were only 4 left. So each pin carries two lines:
The firmware drives one column pin high at a time and reads both row pins. A pressed key puts one of four voltages on its row pin depending on which resistors are in its path:
| Column path | Row path | Row pin voltage |
|---|---|---|
| 10k | 16k | 0.70 to 0.82 V |
| direct | 16k | 0.98 to 1.13 V |
| 10k | direct | 1.28 to 1.45 V |
| direct | direct | 2.62 to 2.85 V |
Those ranges cover 1% resistors across the full 1N4148 diode drop range, and every band has at least 0.15 V of margin to the next, so all 16 keys decode reliably.


The case is fully parametric in CAD/ksp_macropad_case.scad, and it was checked for interference against the real board's STEP model.
| ID | Macro | ID | Macro |
|---|---|---|---|
0x00 | Launch sequence | 0x08 | Docking prep |
0x01 | Auto gravity turn | 0x09 | Landing prep |
0x02 | Circularize | 0x0A | Suicide burn arm (hold 1 s) |
0x03 | Time warp to next event | 0x0B | Precision input toggle (encoder mode 2) |
0x04 | Intercept | 0x0C | Transmit science |
0x05 | Orbit sync | 0x0D | Resource monitor |
0x06 | Rendezvous prep | 0x0E | Auxiliary toggle (encoder mode 3) |
0x07 | Deorbit burn | 0x0F | Autopilot |
Macros that fly the vessel queue up: press CIRCULARIZE while AUTO GRAVITY TURN is still flying and it starts as soon as the turn finishes. The OLED shows the active macro and what's queued next.
| Mode | Left encoder | Right encoder |
|---|---|---|
| 1: Normal | Throttle | Time warp |
| 2: Precision | Target throttle % | Target heading |
| 3: Auxiliary | Camera zoom | RCS thrust limit % |
The mod (mod/KSPMacropad) is a C# plugin for KSP 1.12. It:
To install it, build the project in Visual Studio (.NET Framework 4.8) and copy KSPMacropad.dll into GameData/KSPMacropad/Plugins/. Optional settings go in KSPMacropad.cfg next to the DLL:
port = COM5
allow_with_mechjeb = trueThe firmware turns on a second USB CDC data port (in boot.py) alongside the REPL console.
Pad to mod (6 bytes): [0x44, type, id, data_hi, data_lo, 0x77]
type 0x01: key press, id = key IDtype 0x02: encoder turn, id = (mode << 4) | encoder (1 = left, 2 = right), data = signed 16-bit detent stepstype 0x03: hello, sent every second so the mod can find the right porttype 0x04: resync, asks the mod to resend every LED state after a lost connectionMod to pad (5 bytes): [0x77, id, state, data, 0x44]
0x00 to 0x0F: key LED state0x10 to 0x13: underglow state0x14: heartbeat (the pad shows NO CONN after 3 s without one)0x15: live throttle %0x16: live warp rate, as data x 10^(state & 0x0F), with bit 7 of state set for physics warp0x17 to 0x19: active macro, next queued macro, queue lengthLED state values are defined in led_states.py (firmware) and LEDStates.cs (mod), and the two have to stay in sync.
CIRCUITPY/lib/:
neopixeladafruit_display_textadafruit_displayio_ssd1306boot.py, code.py and led_states.py from Firmware/ to the root of CIRCUITPY.boot.py can turn on the USB data port.| Qty | Part | Reference | Notes |
|---|---|---|---|
| 1 | Seeed XIAO RP2040 | U1 | |
| 16 | MX switches | SW1 to SW16 | |
| 16 | DSA 1U keycaps | ||
| 16 | 1N4148 diodes, through-hole | D1 to D16 | |
| 20 | SK6812 MINI-E RGB LEDs | LED1 to LED20 | reverse mount |
| 2 | EC11 rotary encoders, 20 mm shaft | ENCDR_LEFT1, ENCDR_RIGHT1 | |
| 1 | 0.91" 128x32 SSD1306 OLED, I2C | S1 | pinout GND, VCC, SCL, SDA |
| 1 | 100 µF electrolytic capacitor | C1 | LED supply |
| 2 | 10k resistor, 1% | R2, R4 | matrix columns |
| 2 | 16k resistor, 1% | R5, R7 | matrix rows |
| 4 | 10k resistor | R9 to R12 | ADC pulldowns |
| 1 | 300 Ω resistor | R13 | LED data line |
| 3 | M3 x 16 mm screws | PCB to case | |
| 3 | M3 x 5 x 4 mm heat-set inserts | ||
| 6 | 4 x 1 mm disc magnets | plate retention, glued in pairs | |
| 1 | PCB | production/gerbers.zip | |
| 1 | Case bottom, 3D printed | production/case_bottom.stl | |
| 1 | Top plate, 3D printed | production/case_top_plate.stl |
| Qty | Value | Footprint | References |
|---|---|---|---|
| 20 | SK6812MINI-E | made-for-macro:SK6812MINI-E_fixed | LED1, LED2, LED3, LED4, LED5, LED10, LED11, LED12, LED13, LED14, LED15, LED16, LED17, LED18, LED19, LED20 +4 |
| 16 | D | Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal | D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, D16 |
| 16 | SW_Push | ai03-2725 MX_V2 main MX_Solderable:MX-Solderable-1U | SW1, SW2, SW3, SW4, SW5, SW6, SW7, SW8, SW9, SW10, SW11, SW12, SW13, SW14, SW15, SW16 |
| 6 | 10k | Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal | R2, R4, R9, R10, R11, R12 |
| 3 | MountingHole_3.2mm_M3 | MountingHole:MountingHole_3.2mm_M3 | SCRW1, SCRW2, SCRW3 |
| 2 | 16k | Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal | R5, R7 |
| 2 | NetTie_2 | NetTie:NetTie-2_SMD_Pad0.5mm | NT1, NT2 |
| 2 | RotaryEncoder_Switch | Rotary_Encoder_hp:RotaryEncoder_Alps_EC11E-Switch_Vertical_H20mm | ENCDR_LEFT1, ENCDR_RIGHT1 |
| 1 | 100 | Capacitor_THT:CP_Radial_D6.3mm_P2.50mm | C1 |
| 1 | 300 | Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_Horizontal | R13 |
| 1 | MOUDLE-SEEEDUINO-XIAO | Seeed-Studio-XIAO-series:XIAO-Generic-Hybrid-14P-2.54-21X17.8MM | U1 |
| 1 | ~ | made-for-macro:SSD1306-0.91-OLED-4pin-128x32 | S1 |
It measures 100 × 100 mm and has 2 copper layers, 1.6 mm thick.
71 parts, built around the SK6812MINI-E. 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.
From the MintyTheCoder/KSP-MacroPad repository on GitHub, at the commit this page was made from: the board is design/KSPMacroPad/KSPMacroPad.kicad_pcb and its schematic PCB/KSPMacroPad.kicad_sch. PCBKit opens the board in the browser, with nothing to install.
Its repository states no licence, so its author keeps all rights: ask MintyTheCoder before reusing the design.

google/mozc-devices
Circuit diagrams and firmware source code for Gboard DIY keyboards

Bastardkb/Dilemma
The Dilemma is a vertical stagger low-profile keyboard with mods.

Pwnsat/FlatSat
Flatsat v1.0 is a hardware based platform for aerospace cybersecurity research

adamws/kicad-kbplacer
KiCad plugin for automatic keyboard's key placement and routing

imchipwood/dumbpad
Simple 4x4 numpad with rotary encoder. Powered by QMK via ATmega32u4 Pro Micro

makerforgetech/modular-biped
An open source framework for creating a bipedal modular companion robot.

