Prisma

Wireless split · 24 keys · Choc v1 · ZMK

A wireless, low-profile remake of the handwired Diamond (1333+2 per half). The layout and goals are mine; Claude, working in Claude Code, generated the PCB, the printed case and every check as code.

Left half assembled: printed base, top plate, Choc switches and keycaps
The left half: solid printed base, top plate, Choc v1 switches. KiCad ray-traced render.
Spec sheet

The board

Keys24 Choc v1 hot-swap, all 1u: 3×3, a pinky key and two thumbs per half
WiringDiodeless, one pin per key: 11 XIAO edge pins plus the NFC1 pad
ControllerOne XIAO-sized nRF52840 per half, either the Seeed XIAO nRF52840 or the NologoTech Super52840. Same board, same ZMK firmware
Power500 mAh LiPo (nominal 7 × 20 × 40 mm) on a JST PH socket, and an MSK-12C02 slide switch beside the USB-C port
PCB87.6 × 92.3 mm, 2 layers, one reversible design for both halves
CaseSolid printed base tented 6.6° (20.4 mm at the seam, 10.5 mm at the outer edge), with a 1.2 mm top plate
ExtrasMagnets to join the halves or stack them for travel, interleaving anti-slip pads, a reset button under a cone hole in the plate
AssemblySoldering iron only: no paste, no hot air
The left half seen from the front edge, tilted up towards the inner wall
From the front: the tent rises towards the seam.
The left half's PCB with switches and keycaps, seen from above at an angle
Switch side, with keycaps.

Next: Keyboard

One PCB, two halves

The reversible trick

The left half carries its parts on the back face; the right half is the same board flipped, with parts on the front. Flipped, the module's pins land mirrored: the left half's D0, D1 and D2 become VBUS, GND and 3V3. Solder jumpers route those three to their keys, and you bridge only the set on the face without the module.

The module's underside pads (battery, 12th key, reset) are reached through plated holes filled with solder from the other face, so everything stays iron-friendly. The reset pad sits under the module's GND pad on the opposite mount, so each half's reset hole has its own net and reaches only that half's button.

Underside of the left half's PCB with the Xiao, power switch, JST socket and hot-swap sockets
Parts face of the left half. The right half is this board turned over.
The bare PCB's front face, with the right half's part footprints
Bare front face: the right half's parts.
The bare PCB's back face, with the left half's part footprints
Bare back face: the left half's parts.
One board, either module

XIAO or Super52840

Both modules have the same 14 edge pins on the same nRF52840 pins, so layout, case, plate and firmware are shared. Underneath they differ. Their battery pads sit in the same two spots but swapped, so a selector on the switch face picks which hole is +: bridge +MID or +USB. The Super52840's pads were measured from photos against the 2.54 mm pin pitch.

Seeed XIAO nRF52840NologoTech Super52840
Battery +The pad nearer the middle: bridge +MIDThe pad nearer the USB end: bridge +USB
12th keyNFC1 pad (P0.09)P0.09 in a row of nine extra GPIO pads: a hole under each, on one net
ResetTest padSame place
USB-CSurface-mountLegs through its board, cleared by holes; sticks out 0.8 mm further, into the case's recess
Left half's switch face around the module: D0 to D2 jumpers, the +MID and +USB selector rows, and the boxed fill holes
Left half, switch face: D0–D2 jumpers, the +MID / +USB selector, the fill holes.
Right half's switch face, mirrored as seen when turned over
Right half, as you see it turned over.
Case

Base, plate, two ways to join

A solid base with a pocket per part, a top plate on top, and anti-slip pads that sit in different ends of each slot so they interleave when the halves are stacked.

Printed base with pockets for each part, the USB-C recess and the switch slot
Base: a pocket per part.
The top plate from above, with switch cutouts, countersunk screw holes and the reset cone
Plate: switch cutouts, countersunk screws, the reset cone.
Underside of the top plate with support pillars and screw bosses
Plate underside: pillars, bosses, solder pocket.
Both floors from below, showing where each half's anti-slip pads go
Pad positions on both floors.
Both halves joined at the seam as a unibody
Joined at the seam by magnets.
Both halves joined, seen from above, forming the diamond outline
From above: the two outlines make the diamond.
Both halves stacked floor to floor, seen at an angle
Stacked for travel, keys facing out.
Both halves stacked floor to floor, seen from the side
Stacked, from the side.

Independent tenting

Use two steel phone stands: magnetic attraction on the actual supports has been tested. The half's three stand magnets, 120° apart on a 44 mm circle around its estimated centre of gravity, pull directly on the tilting platform (not the base); no extra discs are needed. All foot positions lie at least 11.55 mm outside the centred 54 mm contact circle, so they do not create an air gap there. Keep magnets flush and faces free of glue. The 54 mm minimum leaves only 1 mm radial magnet-edge margin; prefer about 60 mm if the real platform still clears the feet and obstructions. Aluminium and nonmagnetic stainless steel are unsuitable. The estimated gravity projection stays inside the contact triangle through 35° of tilt, but slip, peel and typing-load retention still need testing.

Each keyboard half independently tented on an illustrative phone stand
Independent platforms, on stand-in stands.

Next: Cyberdeck

Cyberdeck

A dock for a phone stand

A phone on a Ugreen folding stand is the computer and the screen. The dock is one printed part that holds both halves around it. It sits over the stand's base, which stays on the desk on its own feet and carries the phone; behind the dock the base is bare, its hinge half a millimetre off the halves and the spine. Without the stand, the dock is a sturdier, more tented unibody.

It continues the halves' 45° bottom facets down to the desk, with 12° of splay and 5.70° of extra tent (about 12.3° in all). The middle is a front-opening drawer for a trackball, a trackpad or a solid placeholder, which slide out horizontally. At the back, each insert extends only its top into a 45° hood over a matching dock support, 0.4 mm clear.

Everything is held by the same 8 × 1.5 mm N52 discs. Six wing magnets mate six of each half's seven floor magnets, and three more per side pass through 0.6 mm inner skins to the insert, so every join attracts: half → dock → insert. One more disc in the drawer floor grips a module from below, and three pairs attach the dock to the Ugreen base. The rear stays free for USB and the power switch. The dock measures 199.0 × 111.3 × 29.8 mm (about 83 cm³).

Both halves on the dock, splayed and tented, with a phone on the Ugreen stand behind them
The cyberdeck: dock, both halves, trackball in the drawer, phone on its stand (stand and phone are stand-ins).
The cyberdeck seen from the front: the halves tilt down from the spine to the desk
Front: the halves slope down from the spine, the dock under them like a gem's lower half.
The cyberdeck from the side: the keyboard low on the desk, the phone on its arm behind
Side: the hinge right behind the board.
The cyberdeck from above: the halves splayed either side of the spine, the phone behind
Top: 12° of splay a side, the spine between.
Both halves on the dock without the stand: one tented, splayed unibody
Without the stand: a unibody, here with the trackpad.
Both halves on the dock with the solid placeholder in the drawer, its diamond and PRISMA in low relief
With the placeholder in the drawer.
The unibody on the dock from the side
The unibody from the side.
The dock alone: two wings with floor magnets, the drawer between them
The dock alone: wing magnets, pad recesses, drawer.
The dock on the Ugreen base seen from behind, the base's back strip left bare
From behind, on the base: bare round the hinge.
The dock from below: the pocket for the Ugreen base, and three bump-on feet under each wing
Underneath: the base's pocket and the feet.

Next: Pointing modules

Pointing

A trackball or a trackpad, in the drawer

Two ZMK pointing modules that slide into the dock's drawer or snap onto a half on the desk. They are built like a half: a tray, a lid, and the same M3 × 8 flat-head screws from the top. Tray, main board, battery, power switch and reset button are shared. The controller, a nice!nano v2 or a plain XIAO nRF52840, sits on its own small board under the main board.

Trackball module with the grey lid raised off the blue tray and four orange screws above it
Lid, tray and four M3 × 8 screws from the top.

Three side magnets per side use every other position in the halves' six-magnet row, and one disc in the module's floor mates with the drawer floor. To remove a module, push its rear hood forwards through the dock's rear passage.

Trackball: a 34 mm ball and PMW3610 sensor, with two MX or Choc v1 hot-swap keys on one shared PCB. Populate one socket family and print the matching lid.

Choc v1 trackball case with lower switches, sharing the MX variant's PCB
Choc v1 lid: same tray and boards.

Trackpad: a 40 mm Cirque in the lid, with its supplied I²C breakout and flat cable. Four wires run from the main board to the breakout and a separate DR wire to the Cirque's underside. Space is reserved for the breakout and cable with no printed holder; check your kit's dimensions against the build guide.

Trackpad module with the grey lid raised off the blue tray
The trackpad's lid on the same tray.
The trackball module: a red ball at the front, two MX keys stacked behind it
The trackball module.
The trackball module cut open: the sensor board under the ball, the main board under the keys, the nice!nano and the battery under it
Cut open: sensor board, main board, nice!nano, battery.
The trackpad module: a round Cirque pad at the front, two Choc keys stacked behind it
The trackpad module.
The trackpad module cut open: battery, reset board and the nice!nano beneath the keys
Cut open: battery, reset board, controller.
The trackball module snapped onto the left half on the desk
Snapped onto a half on the desk.
The trackpad module snapped onto the left half on the desk
The trackpad, on a half.

USB-C, seated

The port is flush with the module's back with nothing beneath it, and the dock's 12.8 mm rear passage leads straight to it. The renders use an illustrative 12.35 × 6.5 mm plug and cable.

Trackball module with a USB-C cable seated through the rear opening
Trackball: rear USB-C.
Trackpad module with a seated USB-C cable
Trackpad: rear USB-C.
Cutaway showing the USB-C plug seated at the nice!nano
Cutaway to the receptacle.
Trackpad cutaway exposing the USB-C connection
Trackpad cutaway.
Trackball docked with its USB cable through the rear exit
Docked, cable connected first.
Trackpad docked with a USB cable through the rear passage
Trackpad docked, cable connected first.

One panel, either controller

The same breakaway panel holds three boards: main, sensor and controller. Snap them apart and file the stubs. It supports a nice!nano v2 or a plain XIAO nRF52840, with the firmware the only difference: the six signal pins are GPIOs on both. The controller stands face down on a 2.54 mm header on its own small board (two straight columns 15.24 mm apart), and eight stacking pins join that board to the main board above it. One solder jumper picks the 3.3 V pin, and two short wires carry the battery and reset.

On the panel the controller board lies a quarter turn round; in the module it sits under the main board, and each of its eight stacking holes lines up with one of the main board's. Both controllers use the same pin rows. A XIAO's rows sit 0.2 mm further from its USB-C mouth, so its mouth lies 0.2 mm inside the module's back. All images are nominal models, not a physically tested fit for every controller or clone.

The controller board with a XIAO on its header, and the main board's rear part over it, the stacking pins coming through its holes
Controller board with a XIAO, joined to the main board by the eight stacking pins. The main board is cut short to show what lies under it.
The same stack with the main board lifted 10 mm above the stacking pins' tips
Main board lifted off: each pin stands under its hole.
The two boards joined by the stacking pins with a nice!nano on the header, running on past the cut-off main board
The same stack with a nice!nano, which runs further forward on the same header.
The nice!nano stack with the main board lifted 10 mm above the stacking pins' tips
nice!nano, lifted off: same pins and holes.
The XIAO stack from low at the front corner, with coloured wires in every other main-board hole, running forward
Every other hole takes a wire. 3V red, G grey, RST white, CK yellow, IO green, CS blue and MO cyan run forward to the sensor board or trackpad; VBAT orange and R2 purple come up from the controller.
The nice!nano stack from low at the front corner, with the same coloured wires
The same wires with a nice!nano; its battery and reset wires start on its B+ and RST pins.
Plan of both boards' stacking holes measured from the routed PCB, all eight 0.000 mm apart, and a scale section across the stack
Measured on the routed board: every hole pair 0.000 mm apart.
Top view of the controller board with a XIAO on it: named pins, stacking pins and the jumper setting
XIAO wiring, trackball and trackpad.
Top view of the controller board with a nice!nano on it: named pins, stacking pins and the jumper setting
nice!nano v2 wiring, trackball and trackpad.
Seeed-published XIAO reference model on the controller board in the shared tray
XIAO reference geometry in the shared tray (no wires).
XIAO USB cutaway with a plug at the shared rear opening
XIAO USB mouth at the rear opening, from Seeed's STEP reference.
The three-board panel: main board with keys and wire pads, controller board, and sensor board
One panel for either controller and either module.
The trackball's board from the back: the MX hot-swap sockets, and the sensor's regulator, capacitors and reset button
Back face: the sockets, and the sensor's parts facing the plate.

Next: Parts

Parts

Bill of materials

Quantities are for one keyboard (both halves). The PCB is reversible, so both halves use the same board. "Spares" are worth ordering because AliExpress packs come in round numbers anyway.

# Part Qty Search AliExpress for Notes
1 PCB, fab/prisma_jlcpcb.zip 2 (order 5) (JLCPCB, not AliExpress) 2 layers, 1.6 mm, 87.6 × 92.3 mm, HASL, any colour. The cheapest tier: 5 boards is 2 keyboards plus a spare.
2 Seeed Studio XIAO nRF52840, or NologoTech Super52840 2 Seeed XIAO nRF52840 / Super52840 or MINI NRF52840 18x21 The same board takes either; set its battery selector to match (BUILD.md, step 1). XIAO: the plain one (not "Sense", not "Plus"), genuine Seeed, since the board relies on its bottom pads (BAT, GND, NFC1). Super52840: the one with B+/B- pads and a row of nine GPIO pads underneath.
3 Kailh Choc v1 switches 24 (+2) Kailh choc low profile switch Any v1 (PG1350) switch. Not v2 (MX stem) and not Choc mini.
4 Kailh Choc hot-swap sockets 24 (+4) Kailh choc hotswap socket PG1350 CPG135001S30, the low-profile socket.
5 Choc keycaps, 1u 24 MBK keycaps choc / CFX choc keycaps All 24 are 1u (17.5 × 16.5). Thumbs and pinky too.
6 LiPo battery, 500 mAh, 3.7 V 2 702040 lipo 500mah JST PH 2.0 Nominal 7 × 20 × 40 mm, for the halves only. Verify the seller's actual dimensions, lead exit and protection board; ask for the JST PH 2.0 plug and check polarity.
7 JST PH 2.0, 2-pin, SMD horizontal socket 2 (+2) JST PH 2.0 2P SMD horizontal S2B-PH-SM4-TB footprint: side entry, two signal pads and two big mounting tabs.
8 Slide switch MSK-12C02 2 (+3) MSK-12C02 SMD slide switch The 7-pad SMD one with two locating pins.
9 Reset button: SMD tact switch 5.1 × 5.1 mm, 2.0 mm tall, 4 gull-wing legs (XKB TS-1187A-B-D-B or equivalent) 2 (+3) 5.1x5.1x2.0 SMD tactile switch 4 pin On the switch face, in the nook above the thumbs: reset, or double-tap for the bootloader, with the case closed. The height matters: 2.0 mm puts the plunger 0.2 mm under the plate's top. The common 1.5 mm one (LCSC C318884) fits too, but then sits 0.7 mm down and needs a fingernail or a pen tip.
10 Disc magnets 8 × 1.5 mm, N52 26 (+4) 8x1.5mm N52 neodymium magnet Thirteen per half: four stacking positions, three circular stand contacts, six inner-wall magnets evenly spread at 17.8 mm pitch. The same part is used in every accessory.
11 M3 × 8 flat-head screws, 90° countersunk (ISO 10642 / DIN 7991) 8 M3x8 countersunk flat head screw Four per half: through the plate (the head sits flush in its countersink) and the PCB, threading into the solid base (2.5 mm pilot holes).
12 Silicone bump-ons 8 × 2 mm, self-adhesive 10 (+6) 8x2mm silicone bumpon self adhesive Five per half, in the slots under the floor (see BUILD.md). The specified height preserves stacked fit; they lie outside the centred 54 mm stand contact circle.
13 Filament ~170 g Nylon (PA) Case left + right (solid base, 65.9 cm³ each) and the two top plates (4.3 cm³ each); approximately 160 g solid nylon before print overhead.

Cyberdeck dock (optional): case/dock.stl (about 83 cm³, 95 g of Nylon), for a Ugreen folding phone stand with an 85 × 105 × 4 mm base, or on its own as a tented unibody. Print it flat side down, with supports inside the pocket (its roof spans 85 mm). It takes 31 common 8 × 1.5 mm discs: 12 under the halves (six per half), 12 in the drawer walls (six per side), 6 for the three base-magnet pairs and one in the drawer floor. The side magnets face all six seam magnets outside; positions 2, 4 and 6 also face the insert through a 0.6 mm inner skin. Load them from outside, flush, then glue in place. A magnet chain must attract throughout: half → dock → insert. Three base discs go in the dock and three are glued on the aluminium Ugreen base, paired with opposite poles facing. Add 6 more 8 × 2 mm bump-ons, three under each wing.

Independent tenting (optional): two stands with steel tilting phone platforms. The owner confirmed magnetic attraction on the actual supports. No extra discs: the existing case magnets meet the steel directly. Use the mirrored SVGs in case/ for alignment only. Minimum centred clear flat contact circle 54 mm; prefer about 60 mm if it clears the feet and obstructions. Attraction alone does not qualify retention at a typing angle.

Drawer placeholder: case/insert.stl (71.6 cm³, solid, with PRISMA in low relief), for when neither module is in the drawer: 6 common discs, three a side.

Magnet total: both halves 26 + dock and base 31 + placeholder 6 + both pointing modules 14 = 77 discs, before spares. The three discs glued to the dock stand's aluminium base are unchanged; these are separate from the independent steel platforms.

Drawer modules (optional). Either slides into the dock's drawer from the front, or snaps onto either half's inner wall on the desk. Everything below is per module, and most of it is the same part you already buy for the halves.

Every module Qty Search for Notes
Printed tray, case/module_tray.stl 1 The same print for every module
Printed lid 1 trackball/case/lid.stl (MX), trackball/case/lid_choc.stl (Choc v1) or trackpad/case/lid.stl
PCB, trackball/fab/trackball_jlcpcb.zip 1 (order 5) (JLCPCB) 2 layers, 1.6 mm, 53.7 × 99.5 mm. One breakaway panel of three boards (main, sensor, controller), for both pointing modules and either controller: nice!nano v2 or plain XIAO nRF52840. JLCPCB may count this as three designs and add a fee: enter Different Design = 3 and confirm on the quote
M3 × 8 flat-head screws 6 same as item 11 Four through the lid unchanged; finish the two sensor-board screws to ≤7.6 mm overall, deburr, then verify seating, engagement and ≥0.3 mm tip clearance before installing electronics/battery (BUILD.md)
Disc magnets 8 × 1.5 mm, N52 7 same as item 10 Three a side, one in the floor
Silicone bump-ons 8 × 2 mm 3 same as item 12
Slide switch MSK-12C02 1 same as item 8 On the main board, lever out of the back wall
Reset button TS-1187A 1 same as item 9 On the sensor board, facing down
nice!nano v2 or clone 1 nice!nano v2 / SuperMini nRF52840 Face down on the controller board's header, USB-C flush with the back. Only a genuine nice!nano v2's pin rows have been checked: compare a clone's against the wiring diagram before soldering
Alternative to nice!nano: plain XIAO nRF52840 or Super52840 1 same as item 2 Same panel and header; set its jumper and use its own firmware. Its USB-C mouth sits 0.2 mm inside the back. Real fit and operation remain unverified; Super52840 support is experimental
Compatible 2.54 mm-pitch pin header 11 pins 2.54 mm round pin header 0.6mm Two 5-pin lengths and a loose pin, under the controller. Plastic 2.54 mm thick. Measure actual pins and controller holes: standard 0.64 mm square pins interfere with the Ø0.75 mm Seeed reference holes; round Ø0.6 mm is a candidate, not a hardware qualification. Never force pins
Extra-long 2.54 mm pin header, 15 mm 8 pins 2.54 mm header 15 mm long Stacking pins between the controller board and main board: two 3-pin lengths and two single pins. Check where the plastic sits: short end at least 2.35 mm, long end at least 6.7 mm
LiPo battery 752025, 250 mAh 1 752025 lipo 250mah 7.5 × 20 × 25 mm, not the halves' larger cell. Over 20.5 mm wide, it fouls the controller board's arms
30 AWG stranded wire 80 to 100 mm per wire 30 AWG silicone wire About 25 mm for the two wires from the controller
Trackball Qty Search for Notes
PixArt PMW3610DM-SUDU + LM18-LSI lens 1 + 1 PMW3610 (eBay, Tindie: Randware) / LM18-LSI Through-hole sensor in the sensor board's cut-out, on its back face; the lens clips on from the front, looking up
TLV74318PDBVR, SOT-23-5 1 TLV74318PDBVR The sensor's 1.8 V
0805 capacitors: 10 µF, 3.3 µF, 1 µF ×2, 100 nF ×3, 10 nF ×2; 0805 resistor 10 kΩ 9 + 1 0805 capacitor kit Values as siderakb's PMW3610 board (CERN-OHL-P), which this circuit follows
MX switches + Kailh MX sockets + 1u DSA caps, or Choc v1 switches + Choc sockets + caps 2 each Kailh MX hotswap socket / item 4 Populate only one socket family. Choc v2 is not supported
34 mm trackball, 3 mm Si3N4 balls 1 + 3 34mm trackball / 3mm ceramic ball Si3N4 The ceramic balls glue into the cup's three pockets
Trackpad Qty Search for Notes
Cirque TM040040-2023-302 or I²C-configured kit 1 Cirque 40mm I2C flat overlay Use the supplied I²C breakout and flat cable; on SPI-labelled kits remove R1 for I²C, keeping R7/R8 for 3.3 V
Supplied I²C breakout with pull-ups + 12-pin FFC 1 + 1 supplied with the kit Reserved maximum breakout envelope 24 × 18 × 4.5 mm; confirm actual size and FFC contact orientation. Four MCU wires to breakout, separate DR wire directly to Cirque underside
Choc v1 switches, sockets and keycaps 2 + 2 + 2 same as items 3, 4, 5 Compact caps only: 17.5 × 16.5 mm, rotated with the switches (17.5 mm front-to-back here). Centred nominal pad gap 0.585 mm, potentially 0.285 mm after radial seat play; verify actual placement/travel/wobble.

Consumables: thin solder (0.5–0.6 mm), flux, a little kapton tape, thin double-sided tape (0.25 mm at most) for the controller board's seats, CA glue or epoxy for the magnets, removable adhesive dots for the trackpad, thin card for the sensor's shims, and a 2.5 mm insulating spacer/tape stack for the I²C breakout (no printed holder).

Soldering, assembly and printing: see BUILD.md.

Next: Build guide

Build guide

Soldering and assembly

The module, battery and battery socket all end up inside the case, under the PCB. Only the USB-C port and the power-switch lever show, through openings in the outer wall: a recess the size of a cable's plug in front of the port, and a slot open to the top for the lever. Push the lever with a fingernail. The module's LED and its own reset button face the case floor, so flash and test it before closing the case. A second reset button on the switch face, wired to the module's reset pad, works with the case closed: it sits in a cone in the plate, above the thumbs.

Everything is soldered with an iron: no paste, no hot air. Build one half at a time. Both halves use the same PCB, turned over for the right half.

The module is a Seeed XIAO nRF52840 or a NologoTech Super52840. The board takes either: a battery selector, set in step 1, matches it to your module. The other steps are the same for both.

Tools

  • Temperature-controlled iron with a small chisel tip (1.6–2 mm) for the module, sockets and JST tabs, and a fine conical tip for the power switch.
  • Leaded solder: about 330 °C.
  • Lead-free: about 360 °C.
  • Thin solder (0.5–0.6 mm), a flux pen, fine tweezers, kapton tape, isopropyl alcohol and a brush.
  • A multimeter with a continuity beep.
  • Optional: a magnifier or phone camera to inspect the small pads.

The two faces

Each board has a parts face and a switch face. The silkscreen tells you which is which:

Half Parts face (silkscreen) Switch face
Left LEFT: parts on this face the other one
Right RIGHT: parts on this face the other one
  • Parts face: the module, power switch, JST socket and the 12 hot-swap sockets. It faces the case floor.
  • Switch face: the key switches clip in here, the reset button is soldered here, and you bridge the jumpers and fill the module's holes from this side.

The module always lies flat on the parts face, with its pad side against the PCB and its components (USB-C, shield, reset button) pointing away from it, towards the case floor.

Before you start

  • Flash and test the module first. Plug it into USB and double-tap reset: a USB drive appears. Copy the firmware onto it:
Half With a dongle Without a dongle
Left prisma_peripheral_left-zmk.uf2 prisma_central_left-zmk.uf2
Right prisma_peripheral_right-zmk.uf2 prisma_peripheral_right-zmk.uf2

A dead module is much easier to swap now than after soldering.

  • Battery size and polarity. The halves use nominal 7 × 20 × 40 mm, 500 mAh cells; the trackball and trackpad keep 752025, 250 mAh cells. Verify actual dimensions and lead clearance before assembly. Silkscreen + marks pin 1 of the JST socket. Cells ship with either polarity: check the plug with the multimeter. If reversed, swap the two crimps in the disconnected plug housing (lift each tab with a needle), keeping the contacts insulated from each other.
  • Magnet polarity. Every left-half magnet goes in with the same pole facing out, and every right-half magnet with the other pole. That makes both the stack and the side-by-side join attract. Mark one face of each magnet stack before you start.

1. Bridge the D0–D2 jumpers and the battery selector (switch face)

On the switch face, inside the module's outline, there are three small pad pairs labelled D0, D1, D2, on the face without the module. Flux them and bridge each pair with a small blob of solder.

Next to them is the battery selector: two rows of two pad pairs, labelled +MID and +USB. The two modules have their battery pads in the same spots, swapped, and the row you bridge decides which battery hole is +:

Module Bridge both pairs in row
Seeed XIAO nRF52840 +MID (its + pad is the one nearer the module's middle)
Super52840 +USB (its B+ pad is the one nearer the USB end)

Bridge one row only. Both rows short the battery; the wrong row connects it backwards. Both halves get the same row.

Left half, switch face Right half, switch face (mirrored, as you see it)

Left: the left half's switch face. Right: the right half's switch face. Bridge the three D0–D2 pairs and one selector row, and later fill the three boxed hole groups (step 2).

Leave the jumpers on the other face open: they're on the parts face, under where the module will sit.

Check: each bridged pair beeps on the multimeter, and the unbridged selector row doesn't.

2. Solder the module (parts face)

  1. Pre-tin the module's underside pads that the boxed holes reach: the two battery pads (VBAT and GND on the XIAO, B+ and B- on the Super52840), the P0.09 pad (NFC1 on the XIAO, 009 on the Super52840) and RST. Flux each one and touch it with a lightly tinned iron, leaving a thin, flat coat. Wick off any bump: a blob lifts the module off its edge pads. In step 4 the solder fed into each hole then only has to melt into the coat that's already there.
  2. Flux the 14 edge pads. Lay the module flat over its outline with the USB-C end towards the board edge. The pads are pulled out past the module, so you can reach them from the side.
  3. Tack two opposite corners: put solder on the iron, touch it to the board pad and the castellation together, and let it flow. Check the module is flat and every castellation sits over its pad. Reheat a corner to adjust it.
  4. Solder the other 12 edge pads the same way: iron on the board pad, solder fed into the castellation. Each joint should be a small concave fillet up the half-hole.
  5. Turn the board over (switch face up). Fill the boxed holes: the pair inside one box (the battery), both holes in the second box (P0.09: one under each module's pad, so fill both), and the round hole in the small square box near the USB end (RST, the module's reset pad). Hold the iron on the ring for 2–3 s and feed solder into the hole until it fills and stops sinking. This alone does not prove a good joint: check continuity to accessible points on the module and inspect for shorts before applying power. Fill only the boxed holes. The unboxed ones belong to the other half. Most sit under bare module areas; the unboxed reset hole sits under the module's GND test pad, and only wires to the other half's (empty) button pads, so it does no harm either way.
  6. Clean off the flux.

The battery holes and one P0.09 hole are smaller than the rest (0.6 mm, as large as the pads above them allow): flux them well, use thin solder (0.5 mm), and hold the iron on the ring until the solder sinks into the hole before you feed more.

Check:

  • Before any battery goes in: the power switch's middle pad (VBAT; the switch is fitted in step 3) must not beep to the module's GND castellation. A beep may indicate the wrong selector row, both rows bridged, or another short: find and fix it first.
  • The battery hole the selector made + beeps to the power switch's middle pin.
  • The RST hole does not beep to GND (the module's reset is pulled up inside the module: a beep means a solder bridge, and the half would sit in reset).
  • No two adjacent castellations beep to each other.

3. Power switch, MSK-12C02 (parts face)

It goes next to the module's USB-C, with the lever pointing out over the board edge and its two locating pegs in the small holes.

  1. Tin one of the four corner (shield) pads. Place the switch with tweezers and reheat that pad to tack it.
  2. Solder the other three shield pads.
  3. Solder the three signal pads with the fine tip and very little solder. A bridge between the middle pin and its near neighbour does no harm (both are VBAT). A bridge from the middle pin to the far one bypasses the switch: wick it away.

4. JST battery socket (parts face)

Its opening faces the battery's spot under the inner keys. Tack one signal pin, check it sits flat, and solder the other pin. Then solder the two large mounting tabs: they need more heat and more solder, because they take the force of plugging the battery in.

5. Hot-swap sockets (parts face)

Twelve, one per key. Each socket fits its outline only one way round.

  1. Tin one pad lightly, place the socket, and hold it flat with tweezers while you reheat the pad until the socket's metal tab sinks into the solder.
  2. Solder the second tab. Use enough solder to make a fillet, but keep it out of the socket's opening.

6. Reset button, TS-1187A (switch face)

It goes on the switch face, in the gap above the thumb keys, inside its outline labelled RST. The part is square and symmetric: any of the four ways round works.

  1. Tin one corner pad, hold the button flat and centred with tweezers, and reheat the pad to tack it.
  2. Solder the other three legs: a small fillet on each, iron on the pad and against the leg. Keep the solder off the body: the button is 2.0 mm tall and the plate's pocket over it leaves only 0.3 mm above the collar.

Check: the RST hole (step 2.4) beeps to the two legs on the RST side of the button (the side with the label), and beeps to GND only while you press the button.

7. Test (before the case)

  1. Plug in USB. With the firmware flashed and your computer paired or connected, short each socket's two contacts with tweezers. Every key should register.
  2. Plug in the battery, unplug USB and toggle the power switch: the half should stay connected.
  3. Press the reset button once: the half reboots (it disconnects and reconnects). Reconnect USB, then press it twice quickly: a USB drive appears (the bootloader), as with the module's own button.
Symptom Look at
One key dead That socket's two joints
Pinky, ring-bottom or middle-home dead Its D0–D2 jumper (step 1)
Index-top dead (both halves) The NFC1 / P0.09 hole (step 2.4)
Works on USB, not on battery The battery holes, the selector row (step 1), the power-switch joints, battery polarity
Reset button does nothing The RST hole (step 2.4) and the button's legs (step 6)
Half never starts, or keeps rebooting RST bridged to GND: the RST hole or the button's legs
Nothing works The module's castellations, or the firmware file

8. Case and plate

The base is solid up to the PCB's underside, with a pocket for every part. The PCB rests on plastic everywhere, which makes the half stiff and quiet. The top plate covers the whole board: the switches clip into it, and a shallow pocket in its underside clears the solder around the module.

  1. Fit 13 common 8 × 1.5 mm N52 discs per half (polarity!): seven underneath and six along the seam. Dry-fit first, without forcing the plastic, then apply a little suitable adhesive. Keep adhesive off the mating faces.
  2. Lay the battery in its bay and plug it into the JST socket. The plug and the slack of its leads sit in the bay, between the battery and the socket.
  3. Lower the PCB, parts face down, into the base. Each part drops into its pocket, the switch lever slides down its slot, and the USB-C port lines up with its recess. Nothing should need force: every pocket has 0.6 mm of clearance, and the PCB 0.5 mm to the outer walls.
  4. Lay the plate on top, its pillars and screw bosses resting on the PCB, and fit the four M3 × 8 flat-head screws through the plate and PCB. They cut their own thread in the Nylon: turn them in slowly, and stop when the heads sit flush in their countersinks.
  5. Clip the switches through the plate into the sockets, then fit the keycaps. The reset button now sits under a cone in the plate, between the index finger's bottom key and the thumbs. Its plunger is 0.2 mm under the plate's top, so keycaps and palms don't reach it.
  6. Anti-slip pads. Each floor has five slots, each long enough for two pads. Stick one 8 × 2 mm bump-on into one end of every slot and leave the other end empty: when the halves are stacked back to back, the other half's pad drops into that empty end, so the floors and magnets still meet.

The rule is the same on both halves: turn the half over and go clockwise round the floor. In every slot, the pad goes in the end you reach second. Then each half's five pads sit in the ends the other half leaves empty.

Both floors from below: the pads in black

Clean the slots with isopropyl alcohol first and press each pad down firmly against the slot's roof, centred in its round end. Stack the halves to check: they should close flat, with no rocking.

Optional stands and drawer retention

  • Use the same 8 × 1.5 mm N52 discs everywhere. The dock takes six wing magnets and six side magnets per half, three base pairs (three of those discs are glued to the Ugreen base) and one upward-facing disc in the drawer floor: 31 discs total. No underside contact sits near the drawer retention magnet: at least 1 mm of plastic separates their pockets, even with each 0.2 mm off. Leave the rear free for USB and the cable.
  • Each drawer insert takes three evenly spaced side magnets per side (seam positions 2, 4 and 6). The halves and dock have six per side at 17.8 mm pitch; the inserts use every other position. Check the full half → dock → insert polarity chain before gluing.
  • Each pointing module also takes one disc in its floor, on the centreline, directly above the drawer's. Glue both flush or slightly recessed, opposite poles facing. They grip the module from below, whatever the side magnets manage through the walls.
  • The nominal magnet pockets are Ø8.3 mm for 8 mm discs; never force a magnet in.
  • To take a module out, hold the dock and push the tip of the rear hood forwards with a finger through the dock's rear passage, then pull the module out of the front. Unplug USB first.
  • The USB-C port is nominally flush with the module's back, with nothing under it. Feed a plug through the dock's 12.8 mm rear passage. A 12.35 × 6.5 mm overmold is the nominal modelled envelope, not a guaranteed fit for every plug or printed dock; check the real plug, cable and passage.
  • The rear hood and the dock meet at a 45° slope with 0.4 mm clearance.
  • For independent tenting, use the tested steel tilting phone platforms. Do not glue extra discs onto them: the half's existing three stand magnets attract the steel directly. The SVG templates in case/ are 1:1 alignment guides; print at 100% and check the 54 mm boundary with a ruler.
  • The minimum centred contact circle is 54 mm (44 mm magnet-centre circle). All foot positions lie at least 11.55 mm outside its edge, so the feet do not space the magnets off this steel patch. Prefer about 60 mm for more edge margin, checking the actual shape against feet, rubber and lips. Keep magnet faces flush and clean; any recess, coating or adhesive can reduce grip. Use 2.0 mm bump-ons for stacked fit. Start flat, support the half while increasing the tilt, and test slip, peel, typing loads and stand stability before relying on it. The confirmed attraction is not a retention qualification.

Pointing modules

Both modules are built the same way as a half: a tray, a lid, and the same M3 × 8 flat-head screws going in from the top. The tray is one print, shared by all of them. Only the lid changes: trackball/case/lid.stl (MX), trackball/case/lid_choc.stl (Choc v1) or trackpad/case/lid.stl.

The raised lid has upper facets on its front and both sides, starting at the halves' top-surface height. Below that height the front keeps the drawer's matching profile for horizontal removal.

The parts, lid raised Closed

The same main board holds the two keys and the power switch on both modules. A battery and the controller, on its own small board, sit under it. The same sensor board holds the reset button at the front; on the trackpad it carries nothing else. Everything is hand-soldered with an iron: no paste or hot air. The trackpad retains its supplied I²C breakout and flat cable, plus a separate DR wire.

One panel, either controller: order trackball/fab/trackball_jlcpcb.zip for a nice!nano v2 or a plain Seeed XIAO nRF52840, for either pointing module. The panel has three boards: the main board, the sensor board and the controller board.

The controller stands face down on the controller board on an ordinary 2.54 mm pin header, its pins in two straight columns 15.24 mm apart. Eight stacking pins then join the controller board to the main board above it, beside the controller. The six signal pins land on GPIOs on both controllers, so they need only the right firmware. One solder jumper chooses the 3.3 V pin. Two wires of about 25 mm, the same on both controllers, carry the battery and reset.

The main board does not lift out afterwards: removing it means desoldering the eight stacking pins. Solder and test everything beneath it first.

USB always plugs directly into the chosen MCU's onboard USB-C receptacle. There is no external USB connector, extension or soldered USB wiring.

Boards

  1. Snap the panel. The main board and sensor board are joined by one long bridge with a row of holes at each end, and the controller board hangs off the sensor board's side, a quarter turn round, on a short tab with a row of holes at each end of its own. The tab meets it in its USB notch. Snap the controller board's tab first, then the bridge: hold a board in one hand and the bridge in the other (pliers help) and bend at the row of holes until it snaps. File off the stubs.
  2. Main board. Solder the MSK-12C02 power switch on the front face (the side marked MCU BOARD BELOW), with its lever over the rear edge. Solder one family of hot-swap sockets on the back face: Kailh MX for the MX lid, Choc for the Choc lid and the trackpad. Never both.
  3. Sensor board, trackball. Solder the regulator, capacitors, resistor and TS-1187A reset button on the back face, the PMW3610 in its cut-out, and clip on the lens.
  4. Sensor board, trackpad. Solder only the TS-1187A reset button, on the back face.

  5. Controller board.

  6. Set the jumper, on the underside, the face without MCU FACE DOWN. Bridge the middle 3V pad to X for a XIAO or N for a nice!nano. Never bridge all three: on a nice!nano that ties reset to the 3.3 V rail.
    • Fit a compatible header. Measure the actual controller's holes and the pins before soldering. The Seeed reference has Ø0.75 mm holes: a common 0.64 mm square pin has a 0.905 mm diagonal and does not fit that model. Do not force it or enlarge plated controller holes. A 2.54 mm-pitch header with round Ø0.6 mm pins is a candidate, not a confirmed fit; verify pin diameter, actual hole tolerance, plastic height (2.54 mm) and solder engagement. The reference came from Seeed's Sense resources, so confirm the selected plain XIAO or clone separately. Cut two compatible 5-pin lengths. Set the short ends down through rows 3 to 7 of each column from the top face, so the plastic sits on the top face and the long ends stand up, then solder them from underneath. Pull one compatible loose pin from a spare length and solder it into the left column's row 2, the single hole behind the strip, at the USB end, at the same height: the tray's magnet boss leaves no room for plastic there. Trim the tails underneath to about 1 mm.
  7. Flash the controller first, while its reset is in reach, then fit it face down, its USB-C over the notch. Rest it on the plastic, level, and solder the pins on its back. Trim them to 0.6 mm at most above the controller: the sockets are close above it. Power it from USB and check that it connects: its keys and sensor are not joined until the stacking pins are soldered. Solder its two wires now, about 25 mm each: battery and reset, from the table under Wiring. They will not reach the main board yet.
  8. Fit the stacking pins last, keeping them square. Use 15 mm extra-long header with a short end of at least 2.35 mm and a long end of at least 6.7 mm: two 3-pin lengths for the columns beside the controller, and one pin each for the two outer holes. Sand the cut ends of the plastic flush, so they sit square. Their plastic belongs near the main board's underside, not this board. Fit the short ends up into the main board's eight stacking holes. On the left, three in a line: K2, the outer hole of the joined CS pair, and K1, with GND set further out ahead of them. On the right, the outer holes of the joined CK, IO and MO pairs in a line, and the outer hole of the joined 3V pair set further out ahead of them. The stacking GND is not the pad marked G, which takes a wire. Then stand the main board over this board on a 6.75 mm spacer (6.6 to 6.9 mm works), with the long ends down through this board's holes. Solder them to this board only, from underneath. Lift the main board off, and trim the tails underneath to about 1 mm.

How the stacking pins meet the main board, in the module: on the panel the controller board lies a quarter turn round, but each of its eight stacking holes sits exactly under one of the main board's. The diagram is measured from the routed board.

The main board lifted off the stacking pins Assembled, seen from above
Plain XIAO nRF52840
nice!nano v2

Every other hole in the main board takes a wire. Wires: 3V red, G grey, RST white, CK yellow, IO green, CS blue, MO cyan, run forward to the sensor board or trackpad; VBAT orange and R2 purple come up from the controller.

Plain XIAO nRF52840 nice!nano v2

Stacking holes of both boards, measured from the routed PCB, and a section across the stack

For the trackball sensor board, use these values at the PCB references: C1 3.3 µF; C2, C3 and C4 100 nF; C5 and C7 10 nF; C6 10 µF; C8 and C9 1 µF; R1 10 kΩ. Match the regulator and PMW3610 pin 1 to the footprint markings and check the manufacturer drawings before soldering. Solder with an iron, inspect the joints under magnification and check adjacent pins for shorts. Keep the lens clean and do not touch its optical surfaces.

Some sensor-board silkscreen labels overlap. Do not identify wires by silkscreen alone: in the KiCad panel, inspect pad references SJ1 through SJ7, whose nets are respectively S_VCC, S_GND, S_RST, S_SCLK, S_SDIO, S_NCS, S_MOTION. Meter each pad to its intended component or reset button before soldering.

Wiring

Use flexible 30 AWG stranded wire. The main board's pads have short labels: 3V is VCC, G is GND, CK SCLK, IO SDIO, CS NCS and MO MOTION. Solder both of these to the main board before it goes in, and keep it beside the tray on its wires while you fit the parts below it. Run the CK, IO, MO and CS wires inboard of the stacking pins' plastic: that is the only way out of those holes, and a wire left outboard gets trapped. The main board's labels are small: down its right edge, rear to front, the pads are R2, RST, VBAT, CK, IO, MO and 3V, and on its left G and CS, with K2, K1 and GND marking stacking holes.

From To
Battery + / − Main board + / - pads (the switch is on the board)
Sensor board VCC, GND, RST Main board 3V, G, RST

Two wires of about 25 mm run from the controller to the main board, the same on both controllers. Check that length against your own route before cutting. They go on the controller first, and into the main board last, from above:

Controller To main board VBAT To main board R2 Jumper
nice!nano v2 B+ RST, on its pin 3V to N
Plain XIAO nRF52840 BAT+ pad on its back Reset pad on its back 3V to X

Do not connect VBAT to 3V3/VCC, and leave a XIAO's 5V pin empty. The header's row 1 does not reach the board at all, so the battery cannot land on that pin by accident. The same D-number means different GPIOs on these controllers: follow the names in the diagrams and confirm the actual module's markings before soldering.

Plain XIAO nRF52840 nice!nano v2

Each signal takes the same controller pin on both modules. The stacking pins carry them, along with G, 3V, K1 and K2:

Pad nice!nano v2 pin Plain XIAO pin
CK D2 (P0.17) D4 (P0.04)
IO D3 (P0.20) D5 (P0.05)
CS D20 (P0.29) D8 (P1.13)
MO D4 (P0.22) D6 (P1.11)
K1 D19 (P0.02) D7 (P1.12)
K2 D21 (P0.31) D9 (P1.14)

On the trackball, also wire the sensor board's SCLK, SDIO, NCS and MOTION to the main board's CK, IO, CS and MO pads, which sit beside their stacking pins.

Verify the clone's pin labels and USB location against a genuine nice!nano v2 before wiring; clones can differ. The power switch is between the cell positive and B+, not between the controller and its regulated VCC. Insulate the battery leads while wiring, check polarity and continuity with the battery disconnected, and confirm there is no short between supply and ground before connecting it.

Use prisma_trackball for nice!nano or prisma_trackball_xiao for XIAO. The XIAO shield turns off I²C1 and the serial port, so that the sensor can use D4 and D5 and the other signals D6 and D7.

On the trackpad, retain the supplied I²C breakout PCB and its 12-pin flat cable. Solder four flexible wires from the breakout's VDD/VCC, GND, SDA and SCL pads to the main board's 3V, G, IO and CK pads. Solder one additional wire directly from the Cirque's underside DR/data-ready test pad to the MO pad; this does not replace the flat cable. Confirm DR by continuity to connector J1 pin 4 before soldering. Use the breakout's two pull-ups to 3.3 V, not 5 V; verify their population and the kit's pad order with its schematic/meter rather than wire colours. Cable orientation matters: check the supplied FFC contact orientation and the breakout's pin reversal before applying power.

Configure the Cirque for I²C: order a TM040040-2023-302 flat-overlay I²C version, or verify the kit's SPI-labelled board has R1 removed. If R1 is still fitted, remove it with a short iron touch and wick away any bridge; protect the nearby FFC connector. Keep R7 and R8 fitted for this 3.3 V design—do not apply the 5 V conversion. See the adapter guide and the Cirque data sheet. Leave the common sensor PCB's trackball components and CK/IO/CS/MO connections unpopulated; wire only its reset and ground (its unpopulated VCC connection is optional).

The firmware uses Zephyr's Pinnacle driver and assumes a directly wired, active-high DR signal. Test startup, motion, primary tap, sleep and wake on the actual pad; interrupt startup and driver calibration have not been physically verified. The PMW3610 trackball firmware likewise compiles but the shared SDIO line and bus turnaround have not been electrically tested.

Trackpad signal nice!nano v2 pin Plain XIAO pin
SCL (breakout), on pad CK D2 (P0.17) D4 (P0.04)
SDA (breakout), on pad IO D3 (P0.20) D5 (P0.05)
DR (Cirque underside), on pad MO D4 (P0.22) D6 (P1.11)
K1 D19 (P0.02) D7 (P1.12)
K2 D21 (P0.31) D9 (P1.14)
Breakout GND, on pad G GND GND
Breakout VDD/VCC, on pad 3V VCC (3.3 V) 3V3

Use prisma_trackpad for nice!nano or prisma_trackpad_xiao for XIAO. Both use I²C at 100 kHz and address 0x2A. Never connect breakout VDD/VCC to raw battery voltage or USB 5 V. Both I²C firmware variants compile; physical communications, tap, sleep and wake still need testing.

On the plain XIAO nRF52840, the VBAT and R2 wires start on the two small pads on its back. Keep them flat across its back, not crossing, and off towards the rear of the sockets above it. The battery's negative needs no wire to the XIAO: the - pad is ground on the main board, and ground reaches the XIAO through the stacking pins and header. Use Seeed's front and back pinout to identify the pads on the actual board. Insulate each joint and check polarity and shorts with the cell and USB disconnected.

Super52840: battery-pad locations differ and reset, charger and regulator details depend on the actual revision; compatibility remains experimental until verified against that board's schematic and measurements. Do not assume the Seeed battery, reset or charging pinout applies. The XIAO firmware variants compile but have not been tested on hardware.

Into the tray

Work in this order, power off, with the magnets already glued in. Before putting the battery in, perform the sensor screw depth check in step 2. The picture shows the first three steps done.

Battery, sensor board and nice!nano in the tray

  1. Battery. Lower it straight into its cradle. Its 7.5 mm thickness has room to spare, but measure a protected pack first, including tape, tabs and leads. Never force it.
  2. Sensor board. Prepare its two M3 × 8 flat-head screws outside the assembly, before installing electronics or the battery: shorten/file their tips to 7.6 mm maximum finished overall length, deburr and remove all swarf. These are the only screws to shorten. The straight Ø3.4 mm PCB holes are not countersunk: the model's head descends 0.22 mm before seating. An unmodified 8 mm screw bottoms 0.22 mm past the pilot end without a shim; a 0.4 mm shim leaves only 0.18 mm nominal tip clearance. Finished 7.6 mm screws with that shim leave 0.58 mm nominal clearance (0.38 mm with a further 0.2 mm axial uncertainty). Measure the actual head seating, screw length, PCB, posts and shim: retain at least 0.3 mm tip-to-pilot-bottom clearance and sufficient thread engagement. If needed, select a shorter compatible screw or finish it further; never use tightening force to obtain clearance. Trackball: determine the actual unshimmed distance H from the top of the board on the posts to the ball surface on the optical axis with the lid, bearings and ball seated. Measure X from the board top to the lens reference plane specified by the PMW3610 data sheet. Place one equal-thickness shim under each post, each of thickness H − X − 2.4 mm, and verify the assembled reference-plane-to-ball gap is 2.2–2.6 mm. The nominal model gives H = 4.8 mm, but actual dimensions may differ. If the calculated thickness is negative, shimming cannot correct it: do not force the assembly. Do not change optical shims merely to make a screw fit; recheck/shorten the screw for the measured optical stack. Trackpad: no optical gap to set, but put the same 0.4 mm washer under each post because the posts print 0.4 mm low. Fit the board parts face down only after checking screw depth. Actual fastener tolerances and assembled engagement still require physical verification.
  3. Controller on its board. Hold the stack with the front tilted up, about 18°, and lower it in about 3 mm forward of its place. Move it back so the USB end goes in first: a nice!nano's board edges go into the two pockets in the back wall. Lower the front until the board's ears rest on their seats, with the ribs ahead of its arms and the small posts behind its rear corners. These stops take a plug's push and pull, with about 0.4 mm of play on a nice!nano and 0.65 mm on a XIAO. A thin double-sided tape (0.25 mm at most) on the seats keeps the board down. Check that the USB-C mouth lines up with the opening, and test a real plug before going on. A XIAO's mouth sits 0.2 mm inside the back. The cell's end is 0.4 mm ahead of the board, so make sure no battery tape or wire is caught there.
  4. Main board. Before lowering it, meter the stack: 3V and ground must not beep together, and each stacking pin must beep to its header pin. Then lower the board flat, feeding the eight stacking pins through those eight holes, and the controller's two wires up through VBAT and R2. The pins' plastic stops about 0.25 mm short of its underside. The two side posts come up through its large holes and it rests on their shoulders and on the ledge at the back wall. The power lever goes down its slot. Solder the eight pins and the two wires from above. Each pin's pad is joined to a wire pad, so its joint may melt that wire's: keep them brief, and keep the joints concave. Trim the pins to 0.6 mm at most: the Choc and trackpad lids sit 1 mm over them, and the lid's lip passes close to the two rear pins, so dry-fit the lid. Now test everything together, before the lid: the battery, the power switch, both keys, the sensor or trackpad, and reset.

Main board in the tray

  1. Trackpad only. Confirm the actual pad has a clear support ring and fit it in the lid on removable adhesive dots. Reserve the packing space above the mostly empty sensor/reset board for the supplied breakout: 24 × 18 × 4.5 mm maximum overall, including connector, resistors and solder joints, on a 2.5 mm insulating spacer above the sensor PCB so it clears the screw heads. No printed holder is required. Insulate the breakout's underside and prevent it from moving into screw heads or bare conductors. Keep the original flat cable in its reserved 7 mm-wide bend corridor above the breakout, with slack to lift the lid; route the separate DR lead beside it, and the four breakout wires to the main board's pads. These are explicit clearance envelopes, not measurements of your kit: check its board size, cable length, bend radius and joint height before assembly. Do not sharply fold the FFC or trap it under the lid. Check the complete wired closure before securing the lid.
  2. Trackball only. Glue the three ceramic balls into the lid's cup.
  3. Lid. Rear first: tilt the lid, push its two rear hooks into the slots in the back wall, then lower the front. It locates on the tray's rim.
  4. Four M3 × 8 screws into the lid's countersinks, as on a half: they go into the tray's four posts. Turn them in slowly, and stop when the heads sit flush.
  5. Clip the switches through the lid into the sockets, fit the keycaps, and drop the ball in. On the trackpad, use 17.5 × 16.5 mm compact Choc caps. Conventional twin-stem caps rotate with the switch, putting 17.5 mm front-to-back here; do not assume they can turn independently. The centred nominal pad gap is 0.585 mm; an 18 mm square envelope has only 0.335 mm. The seat's 0.3 mm radial play can reduce those gaps to 0.285/0.035 mm before other tolerances. Centre and secure the pad with the actual adhesive, then verify full key travel and wobble without contact. Stop if tolerances cannot preserve clearance; nominal tests do not guarantee fit. Use the current tray and lid together: the front screw pair moved 1.5 mm outwards to retain a 2.087 mm screw-to-pad-seat web. Tighten only to flush, never to force a distorted lid flat.

Stick three 8 × 2 mm bump-ons into the floor's recesses.

Power and reset

Same switch and same button in the same place on both modules.

The power slider, above the USB-C port Reset, from below

The power switch disconnects the battery from both controller and charger: charging requires the switch on. USB can power the controller even with the switch off, so unplug USB, switch off and unsolder the battery's + lead before working on wiring: the module has no battery connector. Use a protected single-cell Li-ion/LiPo pack rated for the controller's charging voltage and current; the main PCB supplies neither a charger nor battery protection. Verify the exact controller's charger, startup/bootloader current settings, battery rating and charge termination under USB load before charging. On a genuine XIAO the selectable charging current is approximately 50 or 100 mA; do not assume a Super52840 uses the same circuit or setting. See Seeed's charging documentation. To reset, take the module out of the dock and press a blunt pin, at most 2 mm across, straight into the hole in the floor: once to reset, twice quickly for the bootloader, if supported by the controller's installed bootloader.

Opening a module

Take it out of the dock, unplug USB, switch it off, and take off the keycaps and ball. Undo the four lid screws and tilt the lid up from the front. The main board stays: it is soldered to the eight stacking pins, so desolder them to take it out. On the trackpad the lid remains attached by the supplied flat cable and the separate DR wire; support it without pulling either, and release the FFC latch if the available slack is insufficient.

Resetting a closed half

Press straight down into the cone above the thumbs with a fingertip (the pad, not the nail, is enough: the cone is 4.2 mm across at the top and the plunger 2.0 mm wide).

  • Once: the half reboots.
  • Twice quickly: the bootloader. With USB plugged in, a USB drive appears: copy a .uf2 onto it to flash new firmware, as in "Before you start".

Printing

Switch mounts: see SWITCH_MOUNT_RESEARCH.md for the manufacturer drawings and qualification limits. All Choc v1 retaining plates use 1.2 mm thickness, a 2.2 mm PCB-to-plate-top stack and 14.0 mm CAD apertures. The MX lid uses 1.5 mm thickness, a 5.0 mm stack and 14.2 mm CAD apertures. The opening allowances are provisional FDM compensation, not manufacturer tolerances. Measure finished openings and verify both switch clips engage before installing electronics.

  • Base: floor-down; intended without supports, subject to bridge inspection in your slicer. The USB recess spans approximately 14.6 mm and pad-slot roofs span 8.6 mm. Inspect bridge direction, anchoring and sag with the intended dry-Nylon profile; add accessible removable support if necessary. For a quiet, solid base, use 4–5 walls and 40–100% infill (gyroid, or solid). More infill means less hollow sound and more weight.
  • Plate: top face down: the STL is already oriented that way, with the pillars and screw bosses pointing up. The reset button's cone narrows upwards at 45° from the bed (4.2 mm to 2.8 mm over the first 0.7 mm) and needs no support. Print it solid, at 0.2 mm layers. The switch cutouts are 14.0 mm (13.8 mm + 0.1 mm per side); if your switches are loose or tight, change cut_tol in design.py and regenerate.
  • Module tray: floor down; the rear hood's underside is designed at 45°. Inspect the 12.8 mm USB bridge and resulting sag clearance to the real plug/controller before assuming support-free printing. Use 4 walls: the screw posts and the 0.9 mm magnet backings carry the load.
  • Module lids: top face down; the trackball's cup grows out of the lid as it prints. The intended orientation is support-free.
  • Review all module overhangs, particularly the rear hooks, cup and pad ledge, in the actual slicer; support-free printing has not been physically verified. Add removable support if the chosen material and slicer require it, keeping mating surfaces accessible for cleanup.
  • Dock: flat side down, with supports inside the stand-base pocket: its roof is at Z = 4.3 mm and has about 5,900 mm² of downward-facing horizontal area. Inspect support-interface material, gap, density, access and removal in the actual slicer. Supports must be removable without damaging the pocket roof, magnet skins or fit surfaces. Measure the cleaned pocket against the actual base; it is not a support-free bridge.
  • Fit: nominal allowances include 0.35 mm round a module in the drawer, 0.3 mm round a half on the dock, 0.25 mm round a lid in its tray and 0.15 mm radially round a magnet. These are not guarantees against cumulative print error, warping or elephant foot. Calibrate shrinkage and elephant-foot compensation, and use the same filament and settings for mating parts. Check fits before installing electronics; careful local cleanup may be needed, and a successful first print is not guaranteed.
  • Nylon: dry the filament before printing. It's tough enough to take the self-tapping threads without cracking, and its softness damps key noise.
  • Release gate: follow PRINT_READINESS.md. Inspect continuous toolpaths through every 0.6–0.9 mm magnet backing/skin, not just the outer mesh. A hypothetical 0.5% error over the 199 mm dock is about 1 mm, greater than the local fit allowances. Measure differential shrinkage and warping of mating parts with the chosen material/profile before a complete build; ±0.2 mm translation tests do not cover either. Never scale just one mating part blindly: that also moves magnets and screw centres. If calibration cannot meet the fit budget, stop and revise/regenerate the geometry.

Next: How it is made

Toolchain

Everything is a script

Python + shapely

One design.json places everything from the key layout: XIAO, battery, connector, screws, magnets. The tent angle is the smallest one the parts under the PCB fit beneath.

KiCad 9 Python API

Runs headless in the official container. Footprints are written as text and checked against KiCad's library, Seeed's OPL library and kiswitch; the board is then built by script.

Freerouting 2.2

Autoroutes the board; pours and stitching vias go on afterwards.

kicad-cli

Design-rule check, JLCPCB Gerbers and drill files, and every render on this page.

manifold3d

Builds the base and plate as solids and intersects every part with them. Anything that isn't 0 mm³ fails.

Top view of the left half's placement: sockets, Xiao, battery, JST socket, magnets, screws, reset button and pad slots
The placement design.json describes, left half from above: sockets red, XIAO blue, battery yellow, floor magnets purple, anti-slip pads black, screws dark grey.
How a language model does it

No CAD window, just a loop

A model can't drag parts around in a GUI, so the design lives in code and every judgement is a number or a picture it can inspect.

  1. GeneratePlacement, footprints, board, solids, all from scripts.
  2. CheckDRC with zero errors, and the fit check at 0 mm³.
  3. LookRender the board and case, then read the images.
  4. Fix upstreamChange the generator, never the output by hand.
  5. RegenerateRerun the whole chain from design.py.
Checks

What gets checked

Every part that could collide is modelled, and the fit check fails on anything above 0 mm³. Some checks cover how the keyboard is assembled and used, not only where parts sit:

A USB-C cable seats fully

A recess the size of the largest Type-C overmold (12.35 × 6.5 mm) reaches the port, and the PCB edge is notched in front of it. The check plugs in a cable of that size.

The PCB drops straight in

The power switch's lever reaches past the PCB edge, so it slides down a slot open to the top, wider outwards so a fingernail reaches the lever. The check sweeps the lever along the drop-in path.

Room for tolerances

0.5 mm around the PCB and plate covers JLCPCB's ±0.2 mm outline tolerance plus print shrinkage.

One magnet throughout

Thirteen 8 × 1.5 mm N52 discs per half: six along the seam and seven underneath, three of them stand contacts. Each pocket keeps 0.5 mm of plastic all round, measured against the printed base. The 500 mAh battery raises the PCB and case by 1.8 mm without changing the PCB outline or wiring.

$ python check_fit.py
sockets vs base                       0.000 mm3
xiao vs base                          0.000 mm3
battery vs sockets                    0.000 mm3
plate vs base                         0.000 mm3
usb plug vs base                      0.000 mm3
usb plug vs pcb                       0.000 mm3
switch lever (dropping in) vs base    0.000 mm3
reset button body vs plate            0.000 mm3
seam magnet 1 (+0.5 all round) vs voids    0.000 mm3
magnets (+0.5) vs each other          0.000 mm3
stacked: left pads vs right pads      0.000 mm3
balance, unibody      nearest key  2.79 mm inside (2.0 needed): ok
ALL CLEAR

Excerpt of the output.