Electronics

Each board's authority is its KiCad redraw once that passes qualification; until then it is the frozen EasyEDA export, kept outside this repository because it embeds LCSC library records (licensing): the maintainer's private lynx-private/electronics/legacy-easyeda/pro/, verified with sha256sum -c SHA256SUMS there. Older Standard JSON exports and the 17-key wheel/20-key left designs are historical, not current boards; the 20-key left's extracted baseline is in lynx-private/electronics/baseline/F20-left/.

baseline/ holds extracted acceptance data, including source archive and board identity in each JSON's _provenance; its directories keep the legacy codes the sources were archived under (F21-left). Current modules are named in LYNXware.toml; each board lives in boards/<stem>/ as <stem>.kicad_*, and modules.md maps full names and codes to those files (naming rules). The four built boards have a KiCad redraw, placed and routed with their source's copper. Two more were drawn in KiCad, planned and not built, with no frozen source, so KiCad is their authority from the start: the left thumb module, 4 keys + joystick (left-T4J), from left-T11 and the v3 joystick thumb, and its mirror, the right thumb module, 4 keys + joystick (right-T4J), on right-T11's outline. The bottom module, mouse sensor ADNS-5050 (BM-ADNS5050) is the v3 mouse module, built and run on v3, drawn in KiCad 1:1 from its EasyEDA board, so KiCad is its authority too. The left thumb module, 11 keys (left-T11) and the right thumb module, 11 keys (right-T11) are qualified and KiCad is their authority (2026-09-25); the left finger module, 21 keys (left-F21) and the right finger module, 20 keys + scroll wheel (right-F20W) await human review. The 2026-09-25 rename changed names only, not a board's qualification. None is approved for manufacture yet (before the next order). A redraw differs from its baseline only where its deviations.toml says so.

Sources and checks

  • wiring-harness.toml owns header pin → signal → GPIO, each signal named by its function (FINGER_MATRIX_ROW_1) with its compact silkscreen alias (FI1), and the bottom slot's purchased sensor breakouts lead by lead, plus the battery sense pin on the main board, and which main-board pin each wire leaves from ([main_board]: a GPIO's own pin, a slot's rail pin, proposed until confirmed). Physical cables are still unknown; the generated pinout cannot certify an assembled wiring harness until those are measured and entered. wires.py locates both ends of every wire for the website (data.wiring-harness) and the scene's pin anchors.
  • cat/<side>-cat/ holds each hand's cat schematic, generated from those sources by write_cat_sch.py (./lx pcb cat): the main board, each fitted module's header, the sensor breakout and the battery through its power switch, as KiCad nets that ERC checks. Edit the sources, never the schematic.
  • parts.toml owns each part's symbol, footprint and source; the library notes record why and the intentional differences.
  • Before the next order holds unresolved hardware issues.
  • Tool commands cover redraw, checks and exports.
  • The old wiring diagrams and EasyEDA schematic exports moved to the private archive with the EasyEDA sources: they were historical reference, not wiring authority, and carried third-party board artwork.

Redraw qualification

Preserve the baseline pad-to-net assignments, even when vendor pin names look wrong. Naming and net aliases are expressed by boardmap.py and the per-board designators.json / nets.json: a baseline net that is a connector signal becomes its canonical name, resolved through wiring_harness.py.

For each board, compare schematic and PCB connectivity both ways against its baseline, plus pad numbering, polarity, placement, outline and holes. Run ERC, DRC with schematic parity, and the routed copper check. Record intended deviations and human review in that board's README before promoting KiCad to authority. A passing geometric script is not a replacement for the EDA tool's DRC or a fit check. A board drawn in KiCad (no baseline directory) has nothing to be compared with: it is gated like a KiCad-owned board from its first file, and its "Human review" tick gates its release.

The README's qualification table ends in a "Human review" row, and its tick (✅) is what promotes KiCad to the board's authority: the one marker, which every tool reads through authority.py instead of keeping its own list. From then on the frozen baseline is history (decision 20, 2026-09-27): ./lx pcb check --routed gates the board on ERC, DRC with schematic parity, routed connectivity and the wiring harness, Assembly and library checks, and prints its differences from the baseline as source: notes, so a board fixed in KiCad (the planned edge-pad fix) still passes. The pinout reads its header pins from the KiCad board. A board awaiting review stays on exact baseline parity.

The decision to redraw was tested on 2026-09-24: KiCad 10.0.6's CLI could not import .epro2; nightly 10.99.0.4383.gdcadf9baa3 imported the first (superseded) thumb board and dropped all PCB net assignments. Its output was also unreadable by 10.0.6. Do not treat a successful import as evidence of connectivity preservation.

Releases

A board revision is released when it was ordered. releases/<stem>/<rev>/ (r1, r2, …) holds the exact package that was sent, Gerbers, BOM and placement, and its release.toml: date, fab, order reference, the source commit and KiCad version, and each file's sha256. ./lx pcb release <board> <rev> makes it from a clean commit that passes the routed check (for a KiCad-owned board the gate above, not baseline parity), with no .kicad_dru rule lowering a DRC check and "Human review" ticked in the board's README; --from <dir> records a recovered package as it is. A release is never overwritten or regenerated: new exports are not evidence of what was manufactured. The Assembly JSON lists each module's releases, and the website's build sheets offer released revisions only.

No release exists yet: the original JLCPCB packages are not recovered (before the next order).

Connector pinout — generated

What each module header pin and each bottom-slot breakout lead carries, and where the cat firmware reads or drives it, from firmware/cat/src/bin/main.rs (verified by tools/electronics/check_wiring_harness.py).

Boards

Each cat's main board and the module boards wired to it. Pick a module to see which of its pins goes to which pin of the main board.