A custom split ergonomic keyboard. Layout designed with Ergogen; cases are either Ergogen JSCAD (v1) or OpenSCAD (v2 onward).
- Handwired (no custom PCBs); v2 will also support hotswap sockets.
- 3D-printed cases and bottom covers (PETG / PLA, 100% infill).
- M3 heat-set inserts in the case; M3 button-head screws to attach the bottom cover.
├── variants/
│ ├── v1/ # Q11-inspired 94-key split (handwired, RP2040 + QMK)
│ │ ├── config.yaml # Ergogen layout + case
│ │ ├── test_block.yaml # Tolerance test print (single switch + 2u stab)
│ │ ├── firmware/qmk/ # QMK source: config.h, rules.mk,
│ │ │ # keyboard.<mcu>.json, keyboard.<mcu>.<proto>.json
│ │ └── docs/ # Committed previews + per-mcu wiring/
│ └── v2/ # Wireless (nRF52840 + ZMK), hotswap, OLEDs (WIP)
│ ├── layout.yaml # Ergogen layout (points only; no case)
│ ├── case/ # case_*.scad sources (→ output case_stls/)
│ ├── pcb_plate/ # pcb_plate_*.scad sources
│ ├── test/ # test_*.scad tolerance prints
│ ├── expansion_modules/ # pointing-module SCAD sources
│ └── firmware/
│ ├── qmk/ # placeholder keyboard.pi_pico.json (wiring diagram only)
│ └── zmk/ # ZMK skeleton (in progress)
├── footprints/ # Custom ergogen footprints
├── scripts/
│ ├── build.sh # Single entry point for every build artifact
│ ├── _matrix.js # Per-variant matrix mapping (used by gen-layout / wiring)
│ ├── export-points.js # Ergogen → points.json/scad (used by v2 OpenSCAD)
│ ├── gen-layout.js # LAYOUT macro + keymap.c + via.json
│ ├── visualize.js # Layout SVG preview
│ └── wiring.js # Wiring diagram SVG
├── output/ # ALL generated artifacts (gitignored).
│ ├── v1/ # STLs, JSCAD cases, points.json, wiring SVG, etc.
│ ├── v2/ # per variant.
│ └── keycaps/ # 3D-printable keycap STLs.
├── KeyV2/ # 3D keycap generator (cloned on demand) — gitignored
├── qmk_firmware/ # Local QMK checkout — gitignored, ~600MB
└── keycaps/ # Keycap source SCAD (output goes to /output/keycaps/)
Each variant folder is self-contained — to build v1 from scratch, you
only need variants/v1/ plus scripts/.
| Variant | Description | Status |
|---|---|---|
| v1 | Q11-inspired 94-key split, Pi Pico per half, QMK + TRRS interconnect | ✅ Built |
| v2 | Wireless (nRF52840 + ZMK), hotswap MX sockets, dual 1.3" OLEDs, LiPo per half | 🚧 WIP |
Tolerance test prints (./scripts/build.sh --test --variant <v>) live
inside each variant: e.g. variants/v1/test_block.yaml for v1's
single-switch + 2u stab block, or variants/v2/test_*.scad for v2's
hotswap/dock test prints.
Everything goes through scripts/build.sh. Run with --help for the full surface:
./scripts/build.sh --help# Build EVERYTHING for every variant (cases, PCB plates, firmware
# UF2s, wiring SVG, previews, test prints, keycaps, prototype freebees)
./scripts/build.sh --all
# Or scope to one variant
./scripts/build.sh --all --variant v2
# Wipe output/ before / instead of building
./scripts/build.sh --clean # just clean
./scripts/build.sh --clean --all # clean then full build
# Pick individual artifacts
./scripts/build.sh --preview --variant v1 # layout SVG
./scripts/build.sh --case --variant v2 # case STLs
./scripts/build.sh --pcb --variant v2 # PCB plate STLs
./scripts/build.sh --test --variant v2 # tolerance test prints
./scripts/build.sh --layout --variant v1 # LAYOUT macro + keymap.c
./scripts/build.sh --wiring --variant v1 # handwiring diagram SVG
./scripts/build.sh --firmware --variant v1 # compile UF2 (default + vial)
./scripts/build.sh --firmware --variant v1 --keymap default # one keymap
./scripts/build.sh --firmware --variant v1 --keymap via
# Run case + layout + wiring + preview in one shot
./scripts/build.sh --all --variant v1
# 3D-printable spacebar keycap STLs (no variant; auto-clones KeyV2)
./scripts/build.sh --keycapsIf you've hand-wired a prototype with non-canonical column→pin
assignments, define the override in
variants/<v>/firmware/keyboard.<prototype>.json and pass --prototype N
to build.sh. The --layout, --wiring, and --firmware flows respect it:
./scripts/build.sh --layout --variant v1 --prototype 1
./scripts/build.sh --wiring --variant v1 --prototype 1
./scripts/build.sh --firmware --variant v1 --prototype 1 --keymap viaThe prototype's wiring SVG lands at
output/v1/wiring_diagrams/pi_pico.prototype_1.svg. The firmware compiles into a
separate keyboard tree (lucero_v1_prototype_1) so it doesn't clobber
your canonical lucero_v1 build.
The first time you run a particular build, you may need to install:
| Tool | Used for | Install |
|---|---|---|
node/npm |
ergogen, layout/wiring scripts | brew install node |
openscad |
v2 case, keycap STLs | brew install openscad |
qmk |
firmware compilation | brew install qmk/qmk/qmk |
scripts/build.sh will tell you exactly which tool is missing if it
can't find one.
The matrix layout (each key's (row, col)) lives in
scripts/_matrix.js — that's the source of truth. Several files
are auto-generated from it on every --layout run:
variants/<v>/firmware/keyboard.json(thelayouts.LAYOUT.layoutblock)variants/<v>/firmware/keymaps/{default,via}/keymap.cvariants/<v>/firmware/lucero_<v>.hvariants/<v>/firmware/via.json
Hand-edits to those files will be silently overwritten by the next
build.sh --layout. To catch this before it bites:
# One-time setup per clone — point git at the in-tree hooks dir.
git config core.hooksPath .githooksThe pre-commit hook runs build.sh --layout --variant <v> --check
on every commit that touches a layout-input or layout-output file.
If the on-disk artifacts don't match what _matrix.js would
generate, the commit is blocked until you regenerate.
You can run the same check ad-hoc:
./scripts/build.sh --layout --variant v1 --checkAfter running --firmware, the .uf2 lands in
output/<v>/firmware/. To flash:
- Hold the on-board RST/BOOT button while plugging the Pi Pico into USB. It mounts as a USB drive named RPI-RP2.
- Drag the
.uf2onto the drive.
After the first flash, QMK's QK_BOOT keycode (default Fn + Esc)
re-enters bootloader mode without unplugging.
- Copy an existing variant or start fresh:
cp -r variants/v1 variants/v3
- Update
variants/v3/firmware/keyboard.json(keyboard_name,pid). - Build:
./scripts/build.sh --all --variant v3 ./scripts/build.sh --firmware --variant v3 --keymap default