Skip to the content
4 layers64 × 80 mmIris brainstem, the printed circuit board in 3D

Iris brainstem

HeyPCB/iris-brainstem

Iris Brainstem: power and servo hub of the Iris robot head. 9 V USB-C PD in, 6 V / 5 A servo rail in stitched copper zones (measured), 5 V rail, half-duplex servo bus with ten ports, speaker amp. 4-layer KiCad 10 board, DRC-clean, fab-ready.

Size
64 × 80 mm
Copper layers
4
Thickness
1.6 mm
Parts
97
Nets
59
Pads
310
Tracks, vias
770, 208
Pours
55
Routed
Yes
KiCad
KiCad 10.0 (file 20260206)
Created
3 Oct 2026
Updated
3 Oct 2026

Overview

Iris brainstem is an open-source printed circuit board by HeyPCB, from the HeyPCB/iris-brainstem repository on GitHub, published under the CERN-OHL-S-2.0 licence. It is a 4-layer board of 64 × 80 mm with 97 parts on 59 nets, routed with 770 tracks and 208 vias.

It is built around the SN74LVC1G125DBVR-TP, SN74LVC1G126DBVR-TP and CH224K, with the INA226AIDGSR, MAX98357AETE+T and TPS56339DDC among its other parts. Its parts include 28 capacitors, 22 resistors, 15 connectors, 9 ICs and 6 diodes. It belongs with the robots and motor control and audio and music boards of this library.

Main components

12

README

README.md

Iris Brainstem

The power and servo hub in the base of Iris: 9 V USB-C PD in, a 6 V / 5 A servo rail laid in stitched copper zones, a 5 V rail, the half-duplex servo bus with ten ports, a speaker amp and a USB-C data port.

Part of Iris, the human-eyed robot head, HeyPCB's open robot boards. Designed end to end with the HeyPCB method on KiCad 10 (headless pipeline, Freerouting 2.4.1); every number below is measured on the files in this repository. Mentions of ./run.sh, docs/rules/, blocks/ or parts/ refer to the heypcb-kicad SDK that produced them.

Iris Brainstem, raytraced in KiCad

LayersOutlinePartsNetsConnections routedViasERC errorsDRC errors / unconnected / parity
464 x 80 mm, shaped9748230 -> 0 open20800 / 0 / 0

Not fabricated, assembled or powered.

KiCad projectkicad/
Gerbers (unzipped and zipped), BOM, CPL, STEP, schematic PDFfab/
Mechanism CAD, fit check and system docsIris, the human-eyed robot head
Renderstop, bottom
Design process, every step as KiCad rendered itmedia/design-process.mp4

Iris Brainstem design process, sped up

Iris Brainstem is board B2 of Iris, a robot head with human-like eyes. It sits flat in the base of the head and is the head's power, USB and servo hub. It takes 9 V from a USB-C PD charger, makes a 6.0 V / 5 A rail for the ten eye, lid and brow servos and a 5 V rail for the head controller (B1 Cortex), measures the input with an INA226, drives the servos' half-duplex serial bus and the speaker, and passes a second USB-C port's data up to B1. It was designed with the HeyPCB method on KiCad 10 (10.0.6), by heypcb-kicad's headless pipeline with Freerouting 2.4.1, from the brief in board.json and section 4.2 of the Iris design spec v0.1 (not published; its binding interconnect and mounting contracts are in the Iris system docs).

This board has not been fabricated, assembled or powered, and no firmware for it has been written. Everything below is what KiCad, the pipeline and the copper scripts measured on the design files. Nothing here has been tested on hardware or in the head.

Role in Iris

Iris has four boards (spec 4): B1 Cortex (ESP32-S3, camera, on the eye cradle), B2 Brainstem (this board, in the head's base), B3 Iris ring (two LED rings) and B4 Brow (forehead sensors). B2 is where power enters the head and where every servo plugs in:

  • USB-C J1 PWR brings 9 V. Everything in the head is powered from here.
  • USB-C J2 DATA carries a PC's USB to B1's native USB, and its VBUS powers the logic on its own (servos stay off).
  • H1 (JST SH-10) and H2 (JST SH-7) are the two harnesses to B1: 5V_SYS, USB, the servo bus and SERVO_EN on H1; I2C, the INA226's alert and I2S audio on H2 (spec 5).
  • J10-J19 are the servo ports, J7 the speaker.

Features

  • USB-C PD sink, 9 V, no firmware. WCH CH224K (U1) with CFG1, CFG2 and CFG3 tied straight to GND, which requests 9 V. There is no configuration resistor to go missing: on the CH224K a missing resistor on CFG1 would request 20 V. VDD through 1 kOhm with 1 uF, VBUS sense through 10 kOhm (WCH's reference schematic). A red PD OK LED (D6) hangs on the CH224K's PG output (open drain, active low).
  • Input protection and measurement. SMAJ15A TVS (D1), 5 A Littelfuse NANO2 fuse (F1, 0451005.MRL), 10 mOhm 1206 shunt (R1) read by an INA226 at 0x40 (U2, ALERT on H2 pin 4), and 470 uF on VIN (C3).
  • 6V0_SERVO, 5 A. TPS565208 buck (U3) to 5.93 V (68 k / 10 k on a 0.760 V reference), 3.3 uH FXL0630, 3 x 22 uF at the regulator and 470 uF at each servo bank (C1, C2). Off by default: EN is SERVO_EN from B1 through 1 kOhm with a 100 kOhm pull-down.
  • 5V2 and 5V_SYS. TPS56339 buck (U4) to 5.21 V (54.9 k / 10 k on 0.802 V), 5.6 uH FXL0630, then an SS34 (D2) onto 5V_SYS. J2's VBUS joins 5V_SYS through a second SS34 (D3). Neither VBUS is ever driven by the board. 5V_SYS goes to B1 on H1 pins 1-2 and to the amplifier.
  • 3V3_B2. AP2112K-3.3 (U6) from 5V_SYS for the INA226, the bus buffers and their pull-ups.
  • Servo bus. The Waveshare / Feetech auto-direction half-duplex driver: 74LVC1G126 (U7), 74LVC1G125 (U8) and an MMBT3906 (Q1), 10 k pull-ups on BUS_TX, BUS_RX and BUS_DATA, an ESD5Z5.0 on BUS_DATA at each bank (D4, D5). TX is never echoed back to RX.
  • Ten servo ports (J10-J19), HC-5264-3A vertical (Molex 5264 type), pin 1 BUS_DATA, pin 2 6V0_SERVO, pin 3 GND, in two banks of five down the left and right edges. D V G is printed at every port and each port is labelled with its servo ID.
  • Speaker amplifier. MAX98357A (U9) on B1's I2S, mono (L+R)/2 (1 MOhm on SD_MODE), 9 dB gain, from 5V_SYS through a ferrite, to a JST SH-2 (J7). Bridge-tied output: neither wire is ground.
  • USB data port. J2 with 5.1 kOhm on CC1 and CC2 (a plain sink) and a USBLC6-2SC6 (U5) on D+ / D- before H1.
  • Test pads (1.5 mm, not fitted parts): VIN, 6V0, 5V2, 5V_SYS, 3V3_B2, BUS_DATA, SERVO_EN and GND (TP1-TP8).
  • Board: 64.0 x 80.0 mm, corner fillet 3.0 mm, 1.6 mm, 4 copper layers: F.Cu signal and power zones, In1 a solid GND plane, In2 signal with a 6V0_SERVO pour, B.Cu mostly a power layer (6V0_SERVO, VIN and 5V_SYS zones, with keep-outs that hold signal tracks off them; 101.5 mm of track runs on B.Cu elsewhere). Every part is on the top side. Four non-plated 2.2 mm holes for M2 screws.

Block diagram

mermaid
flowchart LR
  J1["J1 USB-C PWR"] -->|"VBUS_PD 9 V"| D1["D1 SMAJ15A"]
  J1 -->|"CC, D+/D-"| U1["U1 CH224K<br/>CFG = 9 V"]
  U1 -->|PG| LED["D6 PD OK"]
  J1 -->|VBUS_PD| F1["F1 5 A"] --> R1["R1 10 mOhm"]
  R1 -->|VIN| C3["C3 470 uF"]
  R1 -.->|Kelvin| U2["U2 INA226 0x40"]
  R1 -->|VIN| U3["U3 TPS565208<br/>6V0 5 A"]
  R1 -->|VIN| U4["U4 TPS56339<br/>5V2 3 A"]
  U3 -->|6V0_SERVO| PORTS["J10-J19 servo ports<br/>C1, C2 470 uF"]
  U4 -->|5V2| D2["D2 SS34"] --> SYS(("5V_SYS"))
  J2["J2 USB-C DATA"] -->|VBUS_DATA| D3["D3 SS34"] --> SYS
  J2 -->|"D+/D-"| U5["U5 USBLC6"] --> H1["J5 H1 SH-10 to B1"]
  SYS --> H1
  SYS --> U6["U6 AP2112K 3V3_B2"]
  SYS --> U9["U9 MAX98357A"] --> J7["J7 SPK"]
  H1 -->|"BUS_TX / BUS_RX"| BUS["U7, U8, Q1<br/>half-duplex driver"] -->|BUS_DATA| PORTS
  H1 -->|SERVO_EN| U3
  H2["J6 H2 SH-7 to B1"] -->|I2C| U2
  U2 -->|"ALERT = nINT"| H2
  H2 -->|I2S| U9

Power tree and what the copper carries

text
J1 VBUS_PD, 9 V ─┬─ D1 SMAJ15A to GND
                 └─ F1 5 A ─ R1 10 mOhm (INA226) ─ VIN ─┬─ C3 470 uF
                                                        ├─ U3 TPS565208 ─ 6V0_SERVO ─ C1, C2 470 uF ─ J10-J19 pin 2
                                                        └─ U4 TPS56339 ─ 5V2 ─ D2 SS34 ─┐
J2 VBUS_DATA, 5 V ─ D3 SS34 ────────────────────────────────────────────────────────────┴─ 5V_SYS

5V_SYS ─┬─ H1 pins 1-2 (to B1)
        ├─ FB1 ─ U9 MAX98357A ─ J7 speaker
        └─ U6 AP2112K ─ 3V3_B2

The input enters at the rear left (J1), and F1, R1 and C3 stand in one column above it. The servo buck sits in the middle of the board, with its output node (L1, three 22 uF and C1) on the left, and the ten ports run down both side edges. The 5V2 buck and the two diodes are at the rear right, beside J2.

Load figures (spec 6, all estimates, none measured): VIN 0.68 A typical, about 4.3 A for milliseconds (39 W); 6V0_SERVO 0.58 A typical, a 7-servo burst of 4.6 A for milliseconds, 9 A if every servo stalls (beyond the buck's 5 A by design: firmware must cut torque); 5V_SYS 0.41 A typical, 1.56 A peak. A 27 W (9 V, 3 A) PD charger is the spec's supply.

Net classes (from the brief; a class with a current is never narrowed by the routing ladder): PDIN 0.6 mm (VBUS_PD, VIN_F, VIN; 0.6 mm is the receptacle's VBUS pads and the bucks' VIN pins), SERVO 0.8 mm with 0.8 / 0.4 mm vias (6V0_SERVO), SWNODE 0.6 mm (the two switch nodes), RAIL5V 0.6 mm (5V2, 5V_SYS), USBVBUS 0.6 mm (VBUS_DATA). The tracks only connect the path. The current is carried by the zones below.

Power zones

After routing reaches 0 open, the pour stage lays the plan pours (GND on F.Cu, B.Cu and In1, 6V0_SERVO on In2) and then the brief's board.zones: each a named net's copper over a region on chosen layers, above the plan pours, with every pad joined solid, and where the zone has a stitch pitch, its own 0.6 / 0.3 mm via lattice. Board coordinates are mm from the outline's top-left corner (y = 0 is the front edge). Every reason is also in board.json.

ZoneNetLayersRegionPriorityVias placed
vbus_pdVBUS_PDF.Cu, B.CuJ1's VBUS pads, D1's cathode, F1's input pad (x 9.6-21.6, y 64.4-71.7)120 at 1.2 mm
vin_fVIN_FF.CuF1's output pad to R1, and the INA226's IN+ resistor (x 14.6-19.7, y 57.6-62.7)2-
vin_colVINF.Cu, B.CuR1's VIN pad, C3's + pad, the INA226's IN- / VBUS taps (polygon in x 5.4-19.7, y 51.6-63.4)327 at 1.2 mm
vin_bandVINB.Cufrom the input column to both buck inputs (x 9.6-44.8, y 44.9-57.4)2-
vin_u3, vin_u4VINF.Cu, B.Cueach buck's VIN pin and input capacitors104 and 5 at 1.2 mm
v6_b6V0_SERVOB.Cua U: the left bank strip, a bar along the front (y 7.3-12.5), the right bank strip5-
v6_node6V0_SERVOF.Cu, B.CuL1's output pad, the three 22 uF and C1 (x 14.6-23.0, y 31.6-44.7)68 at 1.2 mm
v6_bank_l, v6_bank_r, v6_c26V0_SERVOF.Cuthe V pins of each bank (x 4.6-7.45 and 56.55-59.4, y 12.5-57.0) and C27, 8-
gnd_out6, gnd_in6, gnd_in5GNDF.Cuthe GND sides of the servo buck's output and input capacitors and of the 5V2 buck's input912, 5 and 0 at 1.2 mm
gnd_front, gnd_mid, gnd_rearGNDF.Cu, B.Cuthe front strip, the middle and the rear right, where the plan pour would otherwise have no vias016, 21 and 51 at 2.4 mm
v5_spine5V_SYSB.Cufrom D2 / D3 at the rear, up the right of the middle (x 45.4-50.8) to H112-
v5_front, v5_link_*5V_SYSF.Cu (+ B.Cu)H1's pins 1-2, and the three places the spine meets F.Cu (D2, D3, H1)12, 133, 5 and 3 at 1.2 mm
sw_6v0, sw_5v2SW_6V0, SW_5V2F.Cuthe gap between each buck's SW pin and its inductor11-
v5v2_out5V2F.CuL2's output pad, the two 22 uF and D2's anode (polygon in x 30.4-36.6, y 51.6-60.4), left of VIN's F.Cu track to U414-

B.Cu is kept free of signal tracks under these zones by seven board.keepouts rectangles (bcu_*), and In2 is kept free of tracks where the VBUS_PD, VIN and the servo buck's via fields need room (in2_*): a stitch via must clear other nets' tracks on every layer. gnd_in5 found no via site (U4's GND pins reach In1 through the plan's own vias). Any GND zone stops the plan's GND stitcher, so the plan's stitching count is 0 and the GND zones stitch themselves. The silkscreen then displaced 25 GND stitching vias under its text, which leaves 208 vias on the board (read off the board: 206 of 0.6 / 0.3 mm and 2 of 0.8 / 0.4 mm; 53 of them are routing vias).

Measured copper on the current path

copper.py (KiCad's Python) lists every track, via and pour of each power net on the final board and exports the copper (tracks, pads, plan pours and zones) as polygons. copper_cut.py (any Python with numpy and scipy) rasterises that copper on a 0.1 mm grid and finds, for each link of the path, the narrowest cross-section the link's whole current must pass: a max-flow / min-cut from the link's source pads to its sink pads, over every layer, with tracks, zones and via barrels together, in parallel. Outer copper is taken as 35 um, inner as 17.5 um (JLCPCB's standard 4-layer build), via plating as 25 um. Each cut is rated with heypcb_kicad.route.ipc2221_amps (IPC-2221, I = k dT^0.44 A^0.725), per layer, summed. Each link is cut a second time with the copper within 1 mm of its pads counted as the pads ("beyond the pads"): that rates the board's own copper between the parts, apart from the parts' fixed lands. Both scripts are copies of quack_core's, adapted.

LinkFrom, toNarrowest cross-section (35 um equivalent)10 C rise20 C riseBeyond the pads, 10 C / 20 C
VBUS_PDJ1 VBUS pads (A4, A9, B4, B9) to F1.11.15 mm of F.Cu, at the receptacle's VBUS pads2.6 A3.6 A9.0 A / 12.2 A (6.23 mm)
VIN_FF1.2 to R1.14.24 mm of F.Cu6.8 A9.2 Apads adjacent
VIN, both bucksR1.2 to U3 and U4 VIN pins and their input capacitors5.09 mm of F.Cu7.8 A10.6 A9.3 A / 12.6 A (In2 0.25, barrels 6.06)
VIN, servo buckR1.2 to U3.3, C7.1, C8.13.08 mm: In2 0.39, 4 via barrels 2.695.5 A7.5 A5.5 A / 7.5 A
SW_6V0U3.2 to L1.10.80 mm of F.Cu: U3's SW pin2.0 A2.8 Apads adjacent
6V0_SERVO, all portsL1.2 to J10-J19 pin 26.09 mm: F.Cu 0.70, 8 via barrels 5.3910.0 A13.5 A10.0 A / 13.5 A
6V0_SERVO, each bankL1.2 (with C11-C13, C1) to J10-J14 or J15-J19 pin 26.09 mm, the same section10.0 A13.5 A10.0 A / 13.5 A
6V0_SERVO, bank to bankJ10-J14 pin 2 to J15-J19 pin 27.61 mm: In2 2.82, B.Cu 4.7810.0 A13.5 A13.4 A / 18.2 A
GND, ports to servo buckJ10-J19 pin 3 to U3.1, C11-C13 pin 28.63 mm of F.Cu11.4 A15.5 A13.3 A / 18.0 A
GND, servo buck to inputU3.1, C7.2, C8.2 to J1 GND pads2.97 mm of F.Cu5.3 A7.1 A13.4 A / 18.2 A (F.Cu 5.74, barrels 2.69)
5V2L2.2 to D2.2 (anode)1.04 mm of F.Cu2.5 A3.3 A2.5 A / 3.3 A
5V_SYSD2.1, D3.1 (cathodes) to J5 pins 1-20.99 mm of F.Cu2.4 A3.2 A2.4 A / 3.2 A

Read off the board (copper_cut.json, copper.json) after the full run with media. "Pads adjacent" means the two terminals are within 2 mm of each other, so the link is the pads' own gap.

What this says against spec 6. At a 10 C rise on 1 oz outer copper:

  • The servo rail has about twice the copper its burst needs. 6V0_SERVO from L1 to the ports rates 10.0 A (13.5 A at 20 C) against the 4.6 A burst and the buck's 5 A limit. The narrowest section is at L1's output node, where the F.Cu node meets the eight vias of v6_node; past that the current spreads over the B.Cu U, the In2 pour and the F.Cu bank strips. The GND return from the ports to the buck's output capacitors rates 11.4 A.
  • The input path carries the 4.3 A peak at a 10 C rise on every board-copper link: VIN_F 6.8 A, VIN to both bucks 7.8 A, VIN to the servo buck 5.5 A, the GND return from the buck input to J1 5.3 A (13.4 A beyond the pads).
  • Two links end on a part's own pins and rate lower by this rule. VBUS_PD leaves the receptacle through its VBUS pads: 1.15 mm of copper at the pads' edges, 2.6 A at 10 C and 3.6 A at 20 C, against the 3 A PD contract and the millisecond 4.3 A peaks. Beyond the pads the zone is 6.23 mm (9.0 A). SW_6V0 is the TPS565208's 0.8 mm SW pin, 2.0 A by the chart against a 5 A switch current. Both are lands fixed by the footprint and well under 2 mm long; IPC-2221's chart is for long conductors, so these figures say little about the real limit, and neither was measured. The receptacle's current rating was not checked (see Check before ordering).
  • 5V2 and 5V_SYS rate 2.5 A and 2.4 A (3.3 A and 3.2 A at 20 C) against the 1.56 A peak. H1's two 5V_SYS pins are JST SH contacts rated 1 A each (catalogue rows), 2 A together, which the spec's 1.6 A respects.
  • Via barrels are rated with the same formula as a plated wall; that is an approximation.

Nothing here is a measured temperature. Measure F1, R1, J1, U3, L1 and the port headers under the real servo load before trusting any of it. The routed widths of the rest of the power nets, read off the board: VBUS_DATA 0.6 mm (0.45 mm necks at pads, 2 vias), SW_5V2 0.6 mm plus its zone, VIN's routed tracks 0.6 mm.

Connectors and pinouts

Every connector follows spec 5 (binding). "Pin n" is pad n of the KiCad footprint. Both harness cables are double-ended, same direction (pin n to pin n), 28 AWG, 150 mm. The SH headers are side-entry with their mouths at the front edge; the board's header pin counts (10, 7, 2) all differ, so no cable fits a wrong header.

H1: J5, JST SH-10 (SM10B-SRSS-TB, C160409) to B1 J5

PinNetDirectionLevel / typeNotes
15V_SYSB2 -> B14.85 V nominal (5V2 - SS34), <= 1.6 A total on pins 1-2source B2
25V_SYSB2 -> B1as pin 1
3GND-
4GND-
5USB_DNbothUSB 2.0 FS D-, 90 Ohm pair with 6ESD on B2 (U5); B1 GPIO19
6USB_DPbothUSB 2.0 FS D+B1 GPIO20
7GND-separates the USB pair from the UART
8BUS_TXB1 -> B23.3 V UART, 1 Mbps, 8N1, idle highB1 GPIO42 -> U7 A + Q1 base network (10 k pull-up on B2)
9BUS_RXB2 -> B13.3 V UARTU8 Y -> B1 GPIO44; 10 k pull-up on B2
10SERVO_ENB1 -> B23.3 V CMOS, active high-> U3 EN via 1 k; 100 k pull-down on B2

The board's nets carry the spec's names (USB_DN, USB_DP, BUS_TX and so on). The USB pair is routed as two plain signals, without an impedance class (USB full speed). The mounting tabs are grounded.

H2: J6, JST SH-7 (SM07B-SRSS-TB, C160406) to B1 J6

PinNetDirectionLevel / typeNotes
1GND-
2I2C_SDAboth3.3 V open drain, 400 kHzpull-ups 2.2 k on B1 only (none on B2)
3I2C_SCLB1 ->3.3 V open drain
4nINTB2 -> B1open drain, active lowINA226 ALERT; 10 k pull-up on B1 (GPIO3)
5I2S_BCLKB1 -> B23.3 V, 3.072 MHz (48 kHz x 64)33 Ohm series at B1; -> U9 BCLK
6I2S_WSB1 -> B23.3 V, 48 kHz33 Ohm series at B1; -> U9 LRCLK
7I2S_AMP_SDB1 -> B23.3 V I2S data-> U9 DIN

The mounting tabs are grounded.

SPK: J7, JST SH-2 (SM02B-SRSS-TB, C160402)

Pin 1 OUTP (SPK_P, marked "+" on the silkscreen), pin 2 OUTN (SPK_N). A bridge-tied load: neither wire is ground. 4-8 Ohm, about 1 W speaker (spec 5). The mounting tabs are grounded.

USB-C: J1 PWR and J2 DATA (HRO TYPE-C-31-M-12, C165948)

  • J1 PWR. CC1 / CC2 to the CH224K; VBUS to D1 and F1; D+ / D- to the CH224K's DP / DM (BC1.2 only, not to B1).
  • J2 DATA. CC1 / CC2 each 5.1 kOhm to GND; D+ / D- through U5 to H1 pins 6 / 5; VBUS through D3 to 5V_SYS. The board never drives this VBUS.
  • J2 only (a PC): logic runs, servos stay off (VIN reads 0 V). J1 only: everything runs, with no USB data. Both: 5V_SYS takes the higher of 5V2 and J2's VBUS, each through its own SS34.

Servo ports: J10-J19 (HC-5264-3A, C2845815; footprint Molex_SPOX_5267-03A vertical)

PadNetSilkscreenNotes
1BUS_DATAD3.3 V half-duplex, 1 Mbps; 10 k pull-up to 3V3_B2; ESD5Z5.0 at each bank
26V0_SERVOVsource B2 (U3); at most 1 A per port (stall)
3GNDG

Watch the numbering: Feetech numbers the servo's own plug "1 GND, 2 Vcc, 3 Signal"; Waveshare numbers the mating header "1 DATA, 2 VCC, 3 GND". The board follows Waveshare (pad 1 = DATA), as spec 5 binds, and prints D / V / G beside every port. Pad 1 (square) is the outboard pin in both banks.

Port to servo ID (binding for firmware, spec 5), printed beside each port:

PortJ10J11J12J13J14J15J16J17J18J19
ServoID 2 pan LID 5 upper lid LID 7 lower lid LID 9 brow LID 3 tiltID 1 pan RID 4 upper lid RID 6 lower lid RID 8 brow Rspare
SilkJ10 ID2 PAN LJ11 ID5 ULID LJ12 ID7 LLID LJ13 ID9 BROW LJ14 ID3 TILTJ15 ID1 PAN RJ16 ID4 ULID RJ17 ID6 LLID RJ18 ID8 BROW RJ19 SPARE

Test pads

PadNetSilkscreenBoard position (x, y)
TP1VINVIN12.80, 58.30
TP26V0_SERVO6V021.55, 33.00
TP35V25V228.00, 50.30
TP45V_SYS5V40.90, 68.55
TP53V3_B23V348.35, 62.35
TP6BUS_DATABUS26.00, 17.10
TP7SERVO_ENEN29.40, 18.85
TP8GNDGND22.60, 16.60

Outline, holes and connector positions (for the mechanism CAD)

Board coordinates are mm from the outline's top-left corner, F face up; y = 0 is the front edge (toward the face). The head frame H follows spec 4.2 (binding): F face at Z = -60.0, Y = 32 - x, X = -30 - y. Read off the board with KiCad 10.0.6's pcbnew.

  • Outline: 64.0 x 80.0 mm, fillet 3.0 mm, 1.6 mm thick. H: X -30 (front edge) to -110 (rear edge), Y +32 (x = 0, the robot's left) to -32.
  • Holes: four 2.2 mm non-plated holes for M2 at (4, 4), (60, 4), (4, 76), (60, 76) = H (X, Y) (-34, +28), (-34, -28), (-106, +28), (-106, -28), onto the base plate's bosses (tops at Z -61.6). No track or via comes within 2.75 mm of a hole's centre.
PartBoard centre (x, y), rotationH (X, Y) of the centreExtent on the boardFaces
J1 USB-C PWR(17.00, 76.30), 0(-106.30, +15.00)body x 12.53-21.47, y 72.65-79.95rear: mouth at the rear edge (H X -110), facing -X
J2 USB-C DATA(47.00, 76.30), 0(-106.30, -15.00)body x 42.53-51.47, y 72.65-79.95rear, as J1
J5 H1 SH-10(38.50, 3.40), 180(-33.40, -6.50)courtyard x 31.56-45.44, y 0.08-6.72; pin 1 at (43.00, 5.40)front: mouth toward the front edge, facing +X
J6 H2 SH-7(23.50, 3.40), 180(-33.40, +8.50)courtyard x 18.06-28.94, y 0.08-6.72; pin 1 at (26.50, 5.40)front, as J5
J7 SPK SH-2(13.00, 3.40), 180(-33.40, +19.00)courtyard x 10.06-15.94, y 0.08-6.72; pin 1 at (13.50, 5.40)front, as J5
J10-J14 (left bank)pin 1 at x 3.50, y 16.50 / 26.00 / 35.50 / 45.00 / 54.50pin 1 at Y +28.50, X -46.50 / -56.00 / -65.50 / -75.00 / -84.50pins at x 3.5, 6.0, 8.5; courtyards x 0.50-11.50, 6.0 mm deep in yup (+Z), vertical headers
J15-J19 (right bank)pin 1 at x 60.50, y 15.20 / 24.70 / 34.20 / 43.70 / 53.20pin 1 at Y -28.50, X -45.20 / -54.70 / -64.20 / -73.70 / -83.20pins at x 60.5, 58.0, 55.5; courtyards x 52.50-63.50up (+Z)
C1, C2 (470 uF, 6.3 x 7.7 mm cans)(16.00, 31.00), (48.00, 31.00)(-61.00, +16.00), (-61.00, -16.00)courtyards 7.2 x 9.5 mm
C3 (470 uF can)(7.00, 64.00)(-94.00, +25.00)courtyard x 3.41-10.59, y 59.25-68.75
L1, L2 (FXL0630, 7 x 6.6 mm)(24.30, 41.00), (38.30, 53.50)(-71.00, +7.70), (-83.50, -6.30)courtyards about 9 x 7.2 mm

Every part is on the F side. The tallest are the 5264 headers, the 470 uF cans and the inductors; the spec allows 12 mm on F (Z -48). The through-hole tails of J10-J19 and the USB-C receptacles' shell legs come through to the B side, where the spec allows 2 mm; their length below the board was not checked. The pipeline's STEP (fab/iris_brainstem.step) uses generated bodies, not vendor models, so take heights from the parts' drawings.

Where the board differs from the spec

SpecOn the boardWhy
U5 USBLC6-2SC6 C2687116 (UMW)C7519, STMicroelectronics' own USBLC6-2SC6The pinned table prefers ST's part over the clone; same pinout, same KiCad symbol
"PD OK" LED from 3V3_B2 through a resistor into PGLED (D6) and 2.2 kOhm from the CH224K's own VDD into PGWith only J2 plugged in, 3V3_B2 is up while the CH224K is unpowered; an LED from 3V3_B2 into PG would back-feed the unpowered chip. From VDD it draws about 0.6 mA of the 5.7 mA the 1 kOhm VDD resistor supplies at 9 V
C1-C3 "470 uF 16 V polymer", C2977552the spec's own C2977552, which is RVT1C471M0607, a general-purpose aluminium electrolytic (185 mA ripple at 120 Hz, catalogue row)Kept the spec's part number. TI's TPS565208 table assumes 20-68 uF of ceramics; the 940 uF of electrolytic bulk on 6V0 is outside it (see Check before ordering)
Layers "F / GND / 6V0 + 5V pours / B"F.Cu / In1 GND / In2 signal + 6V0_SERVO pour / B.Cu power zonesThe 5 V rails need little copper (1.6 A); B.Cu carries the 6V0_SERVO U, the VIN band and the 5V_SYS spine, with signal tracks kept off those zones, and In2 carries signals
Test pads VIN, 6V0, 5V2, 5V_SYS, 3V3_B2, BUS_DATA, SERVO_ENthe same plus GND (TP8)A probe needs a ground next to the bus pads
(not specified)SH header mounting tabs grounded; 10 Ohm / 100 nF INA226 input filter; 1 uF on J2's VBUSData sheet practice (INA226: 10 Ohm or less per line)

Everything else follows spec 4.2's parts table and spec 5's contracts: the same reference designators (U1-U9, D1-D5, C1-C3, F1, R1, J1, J2, J5-J7, J10-J19), the same parts and the same pinouts. Part numbers came from the pinned table or from live jlcsearch lookups on 2026-10-03, pinned in parts/lcsc_pinned.json with that date.

What it measured

A full run with media on 2026-10-03 (./run.sh --board boards/iris_brainstem, KiCad 10.0.6, Freerouting 2.4.1). Gate numbers are from report.json. Anything marked read off the board was measured on kicad/iris_brainstem.kicad_pcb with pcbnew.

GateResult
Composition97 parts, 48 nets (13 block instances of 12 new brainstem_* blocks)
Part binding85 of 97 parts bound to an LCSC number, 0 unsourced, 0 identity conflicts. The other 12 are not BOM parts: the four mounting holes and the eight test pads. 24 distinct Extended parts, about $72 in JLC loading fees
ERC (kicad-cli sch erc --severity-all)0 errors, 1 warning (pin_to_pin: the MAX98357A's exposed pad, typed "unspecified" in KiCad's symbol, on GND)
Netlist round tripidentical, 48 nets
Routing, rung 1, fanout on230 -> 0 open by Freerouting alone, 28.3 s, 53 vias. This solve is kept
Routing, rung 1, fanout off0 open after the last-mile router closed one 3V3_B2 connection (4 vias), 89.8 s
Net classesnone narrowed (every power class carries a current)
Copper770 tracks, 2001.4 mm (F.Cu 1318.6, In2 581.2, B.Cu 101.5), 53 routing vias
Pours and zones (laid only after a measured 0 open)Plan: GND on F.Cu, B.Cu and In1, 6V0_SERVO on In2. The 25 board.zones above them, with 180 zone vias (GND 105, VIN 36, VBUS_PD 20, 5V_SYS 11, 6V0_SERVO 8). 0 open after the pours and after stitching, 0 island-repair vias
Silkscreen55 words and marks placed (24 words, 30 port letters, the speaker's "+"), 39 designators seated and 34 hidden, the 6 back-side title lines placed as one block (offset 5.0, -3.0 mm from the brief's spot). The text displaced 25 GND stitching vias; 6 footprint silk strokes at or past the edge were dropped
DRC (kicad-cli pcb drc --severity-all --schematic-parity)fresh, 0 errors, 0 unconnected, 0 parity issues, 2 warnings (lib_footprint_mismatch on J1 and J2: the silk clip dropped 3 of each receptacle's 5 silk strokes at the rear edge, read off the board). One repair before the final check: J13 pin 3's starved thermal became a solid zone connection
DFM (jlcpcb_4layer)0 errors, 1 warning: 330 stock-footprint silk strokes at 0.12 mm, which the fab prints at its 0.15 mm minimum
Fab gateready, no blockers. 4 copper gerbers and a gerber job with LayerNumber 4, 1.6 mm; drill, BOM, JLC CPL (9 rotations corrected), schematic PDF, STEP
3D, renders, videoall ran: 63 3D frames, the renders (492.7 s, on a machine shared with other boards' runs) and the design-process video (225 stills; 151.4 s at 1920 x 1080 by ffprobe)

Nothing on the board was edited by hand: every track came from Freerouting, every pour and stitching via from the pipeline.

Why the brief looks the way it does

Measured on the runs of 2026-10-03; each reason is also in board.json beside its key.

  • B.Cu is a power layer. Seven B.Cu track keep-outs keep Freerouting's signals off the bank strips, the front bar, the VIN band and the 5V_SYS spine, so no signal track splits the zones there.
  • Stitched zones carry the higher priority. Where two zones of one net overlap, only the higher priority fills. vin_col (stitched, F.Cu and B.Cu) placed 0 vias under the B.Cu VIN band until the band went one priority below it; then 29 (27 after the last placement changes).
  • In2 keep-outs give the via fields room. A stitch via must clear other nets' tracks on every layer, so In2 tracks are kept out of the input column and the servo buck's input and output via fields. The 5V2 buck's In2 keep-out was narrowed to x 40.6-44.6: wider, the USB pair could not leave the rear right and the USB D- line stayed open.
  • The test pads sit on their own rails. A row of test pads across the middle needed long traces through the power copper; the VIN pad's trace cut the servo buck's output-capacitor ground off its vias (its GND return fell to 0.59 mm).
  • The 5 V rails stay at 0.6 mm, and 5V2's output has a zone. At 0.8 mm Freerouting ran 5V2 and 5V_SYS as long In2 runs, which rate lower on 0.5 oz copper, and left the USB D- line open. At 0.6 mm 5V2 is F.Cu only, but its routed track from L2 to D2 measured 0.51 mm at the min-cut, 1.5 A at 10 C against the 1.56 A peak. The v5v2_out zone, added on the same route, took it to 1.04 mm (2.5 A).
  • The 5V_SYS spine's links were moved to clear other nets. Its front link sat behind H1's USB_DP track (min-cut 0.25 mm) until it moved to x 41.5-45; its rear arm knocked out the 5V2 buck's VIN field (0 vias) until it moved to y 61.2-63.4.
  • C3, TP1 and the PD OK row were moved for their labels. C3 moved 2 mm toward the rear so J14's D / V / G letters fit; TP1 moved to (12.8, 58.3) and the CH224K's support row 0.25 mm lower so "VIN" and "PD OK" find a spot. The speaker's "+" is a silk.switches entry, because silk.polarity would also print "-" beside the grounded mounting tabs.
  • copper_cut.py sums duplicate graph edges in 64 bits. J1's A4 / B9 and A9 / B4 VBUS pads overlap, and two infinite-capacity edges summed in 32 bits wrapped negative and read as a flow of 0. quack_core's copy has the same line.

Check before ordering

  • The charger must offer 9 V at 3 A (27 W or more). The CH224K asks for 9 V only. A charger without a 9 V profile stays at 5 V: the PD OK LED stays off, the TPS565208 cannot make 5.93 V from 5 V (its maximum duty of 83 % needs at least 7.1 V in), and firmware must keep SERVO_EN low (spec 8: only above 8.5 V VIN). The 5V2 buck runs in dropout at 5 V, so 5V_SYS is lower until 9 V arrives.
  • Part stock. The TPS565208DDCR (C2650336) had 1,233 in stock at the 2026-10-03 lookup. The spec's fallback is the TPS54560BDDAR (C1850354, 11,483 then), which needs a 5 A Schottky and a different package: a re-layout of the servo buck, not a drop-in. Re-check every part's stock at order time, in particular CH224K C970725 (7,051), SM07B-SRSS-TB C160406 (9,286), FXL0630-5R6-M C475914 (10,037) and the 54.9 k resistor C23077 (15,112). 24 distinct Extended parts.
  • Inrush at plug-in. 470 uF (C3) and the bucks' input capacitors sit on VIN behind F1 and R1, with nothing to limit the inrush when the contract steps VBUS to 9 V. USB-C and USB PD limit the capacitance a sink may present; a charger may see this as an over-current and drop the contract. The spec chose this bulk; test with the intended chargers, and add a soft-start switch in a revision if one trips.
  • Servo buck stability with 940 uF of electrolytic bulk. TI's table for the TPS565208 (D-CAP2) gives 20-68 uF of output capacitance at 5-6.5 V out; C1 and C2 add 940 uF of aluminium electrolytic at the banks. Their ESR damps them, but check load steps and ripple on the bench.
  • Copper weight. The ratings above assume JLC's standard 4-layer build: 1 oz outer, 0.5 oz inner. The gerber job the pipeline writes declares 35 um on all four layers; order the stack-up the ratings assume, or re-rate. 2 oz outer copper would raise the outer-layer share of each figure by about 65 % (2^0.725).
  • Connector ratings. The HRO TYPE-C-31-M-12's VBUS current rating and the 5264 headers' per-pin rating were not checked against data sheets; the spec's per-port stall is 1 A.
  • B-side clearance. The 5264 headers' tails and the USB-C shell legs protrude below the board; check them against the base plate (spec: 2 mm on the B side).
  • JLC's CPL. The pipeline corrected 9 rotations. Check the placement preview, in particular the polarity of D1-D3, C1-C3 and D6, and pin 1 of U1-U9.
  • Firmware is not written. The board relies on it (spec 8): SERVO_EN only while the INA226 reads VIN of 8.5 V or more, cut the servos above a 3.3 A one-second average, stagger servo starts by 2 ms or more, provision servo IDs one at a time (every servo ships as ID 1).

Data sheet facts used

Each value is cited where it is used, in the block files' notes. Data sheets were read for values and are not stored in this repository.

Licence

The Iris Brainstem design files in this folder (board.json, copper.py, copper_cut.py, this README) and the brainstem_* blocks are released under the CERN Open Hardware Licence Version 2 - Strongly Reciprocal (CERN-OHL-S-2.0). KiCad's symbol, footprint and 3D libraries keep their own licence (CC-BY-SA-4.0 with the KiCad library exception). Part numbers and stock figures are catalogue facts.

Files

  • board.json: the brief. Blocks, net classes, keep-outs, power zones, placement (with a reason per lock), routing and silk settings.
  • copper.py (KiCad's Python) and copper_cut.py (numpy and scipy): the copper measurement above. They write build/iris_brainstem/copper.json, copper_geom.json and copper_cut.json.
  • ../../blocks/brainstem_*.json: the 12 blocks written for this board. Each block's notes give the KiCad 10 symbol pinout it was wired from and the data sheet its values came from.
  • ../../parts/lcsc_pinned.json: the 7 parts and 3 resistor values this board added, each with its 2026-10-03 lookup.
  • The pipeline's outputs are in build/iris_brainstem/ (not committed): report.json, the KiCad project, fab/ (gerbers, drill, BOM, JLC CPL, schematic PDF, STEP), the renders and the video.

To rebuild, from the repository root:

bash
./run.sh --board boards/iris_brainstem              # the pipeline, with renders and video (5-15 min)
/Applications/KiCad/KiCad.app/Contents/Frameworks/Python.framework/Versions/Current/bin/python3 \
    boards/iris_brainstem/copper.py                 # power copper -> build/iris_brainstem/copper*.json
python boards/iris_brainstem/copper_cut.py          # a Python with numpy and scipy

Parts

97
QtyValueFootprintReferences
10SERVOConnector_Molex:Molex_SPOX_5267-03A_1x03_P2.50mm_VerticalJ10, J11, J12, J13, J14, J15, J16, J17, J18, J19
9100nFCapacitor_SMD:C_0603_1608MetricC5, C6, C9, C10, C16, C17, C24, C25, C27
710kResistor_SMD:R_0603_1608MetricR3, R9, R14, R17, R18, R20, R21
610uFCapacitor_SMD:C_0805_2012MetricC7, C8, C14, C15, C26, C28
622uFCapacitor_SMD:C_0805_2012MetricC11, C12, C13, C18, C19, C20
41uFCapacitor_SMD:C_0603_1608MetricC4, C21, C22, C23
4M2MountingHole:MountingHole_2.2mm_M2H1, H2, H3, H4
310Resistor_SMD:R_1206_3216MetricR5, R6, R7
3470uF 16VCapacitor_SMD:CP_Elec_6.3x7.7C1, C2, C3
21kResistor_SMD:R_0603_1608MetricR2, R10
25.1kResistor_SMD:R_0603_1608MetricR15, R16
2ESD5Z5.0Diode_SMD:D_SOD-523D4, D5
2SS34Diode_SMD:D_SMAD2, D3
1100kResistor_SMD:R_0603_1608MetricR11
110mResistor_SMD:R_1206_3216MetricR1
1120R@100MHzInductor_SMD:L_0603_1608MetricFB1
11MResistor_SMD:R_0603_1608MetricR22
12.2kResistor_SMD:R_0603_1608MetricR4
120kResistor_SMD:R_0603_1608MetricR19
13.3uHInductor_SMD:L_Changjiang_FXL0630L1
133Resistor_SMD:R_0603_1608MetricR12
13V3_B2TestPoint:TestPoint_Pad_D1.5mmTP5
15.6uHInductor_SMD:L_Changjiang_FXL0630L2
154.9kResistor_SMD:R_0603_1608MetricR13
15AFuse:Fuse_Littelfuse-NANO2-451_453F1
15V2TestPoint:TestPoint_Pad_D1.5mmTP3
15V_SYSTestPoint:TestPoint_Pad_D1.5mmTP4
168kResistor_SMD:R_0603_1608MetricR8
16V0TestPoint:TestPoint_Pad_D1.5mmTP2
174LVC1G125Package_TO_SOT_SMD:SOT-23-5U8
174LVC1G126Package_TO_SOT_SMD:SOT-23-5U7
1AP2112K-3.3Package_TO_SOT_SMD:SOT-23-5U6
1BUS_DATATestPoint:TestPoint_Pad_D1.5mmTP6
1CH224KPackage_SO:SSOP-10-1EP_3.9x4.9mm_P1mm_EP2.1x3.3mmU1
1GNDTestPoint:TestPoint_Pad_D1.5mmTP8
1H1Connector_JST:JST_SH_SM10B-SRSS-TB_1x10-1MP_P1.00mm_HorizontalJ5
1H2Connector_JST:JST_SH_SM07B-SRSS-TB_1x07-1MP_P1.00mm_HorizontalJ6
1INA226Package_SO:TSSOP-10_3x3mm_P0.5mmU2
1MAX98357APackage_DFN_QFN:TQFN-16-1EP_3x3mm_P0.5mm_EP1.23x1.23mmU9
1MMBT3906Package_TO_SOT_SMD:SOT-23Q1
1Red (PD OK)LED_SMD:LED_0603_1608MetricD6
1SERVO_ENTestPoint:TestPoint_Pad_D1.5mmTP7
1SMAJ15ADiode_SMD:D_SMAD1
1SPKConnector_JST:JST_SH_SM02B-SRSS-TB_1x02-1MP_P1.00mm_HorizontalJ7
1TPS56339Package_TO_SOT_SMD:SOT-23-6U4
1TPS565208Package_TO_SOT_SMD:SOT-23-6U3
1USB-C DATAConnector_USB:USB_C_Receptacle_HRO_TYPE-C-31-M-12J2
1USB-C PWRConnector_USB:USB_C_Receptacle_HRO_TYPE-C-31-M-12J1
1USBLC6-2SC6Package_TO_SOT_SMD:SOT-23-6U5
1VINTestPoint:TestPoint_Pad_D1.5mmTP1

Similar boards

  • 4 layers101 × 51.5 mmQuack core, the printed circuit board in 3D

    Quack core

    HeyPCB/quack-core

    Brain board for the Open Duck Mini: Pi Zero 2W carrier, 14-servo STS bus, fused 2S power path in stitched copper zones (15-18 A battery side), USB-C charging with balancing, IMU.

    138 parts1CERN-OHL-S-2.0
  • 4 layers80 × 40 mmIris cortex, the printed circuit board in 3D

    Iris cortex

    HeyPCB/iris-cortex

    Iris Cortex: head controller of the Iris robot head. ESP32-S3 (16 MB flash, 8 MB PSRAM), OV2640 eye-camera FPC, iris-ring LED drivers, harness hub.

    77 partsCERN-OHL-S-2.0
  • 4 layers70.5 × 79.5 mmM4 CAN Feather Carrier, the printed circuit board in 3D

    M4 CAN Feather Carrier

    2468shrm/M4_CAN_Feather_Carrier_v6

    Sixth version of the M4 Feather CAN Express carrier board. Hopefully, "the last".

    70 parts1
  • 4 layers21.7 × 89.8 mmEuroPlatvorm, the printed circuit board in 3D

    EuroPlatvorm

    nanassound/eurorack-nanassound

    Eurorack modules of Nanas Sound

    34 parts27
  • 6 layers80 × 60 mmIce core, the printed circuit board in 3D

    Ice core

    enkhbold470/ice-core

    iCE40UP5K FPGA board with 8 MB PSRAM and three Pmods, programmed over USB-C by an RP2040. 6-layer KiCad 10 board.

    78 partsCERN-OHL-S-2.0
  • 4 layers74 × 52 mmMIsBkit Rev3, the printed circuit board in 3D

    MIsBkit Rev3

    alvarohub/workshop_MattersOfBehaviour

    88 parts

Questions

How big is the Iris brainstem PCB?

It measures 64 × 80 mm and has 4 copper layers, 1.6 mm thick.

What parts does the Iris brainstem use?

97 parts, built around the SN74LVC1G125DBVR-TP, SN74LVC1G126DBVR-TP, CH224K and INA226AIDGSR. 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 Iris brainstem KiCad files?

From the HeyPCB/iris-brainstem repository on GitHub, at the commit this page was made from: the board is kicad/iris_brainstem.kicad_pcb and its schematic kicad/iris_brainstem.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the Iris brainstem design in my own project?

Its repository publishes it under the CERN-OHL-S-2.0 licence: you may reuse it on that licence's terms (keep the author's notice, and for a copyleft licence share your changes alike).