Electrical Wiring
Complete electrical wiring diagram for the kart, covering the shutdown circuit, power distribution at multiple voltages, and signal routing between all subsystems.
Wire Color Code
This is the colour convention for the wiring we build ourselves — the hand-made harness between subsystems. It is a house guideline, not a rule the whole kart obeys: this is a prototype assembled from third-party parts, and those parts keep their vendors' own colour codes. Two notable exceptions:
- Off-the-shelf DC-DC power regulators land on the rear Wago connectors with their own fixed output-wire colours, following the module's standard rather than this table.
- Festo sensor and valve cables follow EN 60947-5-2 (see the pressure-sensor note below) — e.g. blue is ground and black is a signal output, the opposite of this table.
Where we do run our own wire:
| Color | Meaning | Hex |
|---|---|---|
| Black | Power GND — return for motors, valves, coils, and the power rails | #333 |
| Black + white stripe | Signal GND — return for sensors and analog/logic references | #333 / #fff |
| Red | 12 V power | #d32f2f |
| Orange | 5 V power | #e65100 |
| Yellow | 3.3 V power | #f9a825 |
| White / Gray | Deliberately unassigned — carries no meaning | #bbb |
White and gray are the escape hatch, and that is their job. Every other colour in the table is a promise about what the wire carries, so using one wrongly is worse than using none: someone later reads the promise and trusts it. White carries no promise, so you can wire anything with it — a one-off, a bodge, a bus nobody has a convention for — without breaking the code or having to invent a new colour first. Reach for white whenever the right colour is not obvious. Signal wires we run ourselves (I²C, analog, PWM) use white or gray by default, unless a specific convention applies to that bus.
A stripe modifies the base colour rather than adding a second meaning, so the white stripe on signal ground is not an exception to this: the wire is black, and black means ground. Solid white and striped black are hard to confuse in the harness.
Why two grounds
Motor, valve, and coil currents are large and switch fast. Sharing a return wire with a sensor puts that current's voltage drop directly in series with the sensor reading, so the measurement moves when the motor does. Separating the returns keeps that drop out of the sensitive path.
Both grounds are the same electrical node — they are joined at exactly one point, the
star point. On this kart that point is the rear ground Wago terminal block, near the
battery and the 12 V / 24 V regulators; it appears in the wire list below as the device
wago_gnd. Two joins would create a loop and undo the separation, so no other place in the
harness may bond the two. The stripe is there so that anyone tracing the harness can tell,
without a meter, which return a wire belongs to and therefore where it is allowed to land.
If striped wire is hard to source in a given gauge, use plain black with a white heatshrink band at both ends — same meaning, same rule.
Global Wiring Diagram
Hand-crafted SVG. Real Festo product photos for the pneumatic brake chain (VPPM, EBS, ADN actuator); inline schematic-style symbols for the rest (battery cell stack, BLDC motor with U/V/W terminals, mushroom kill switches, op-amp triangle, SDC relay coil + NO contacts). Open full-size in a new tab ↗
Tip: All switches in the shutdown chain are in series — opening any one cuts power to the relay coil, which disables the motor controller.
Manual / autonomous mode switch
A single DPDT (double-pole double-throw) switch on the kart panel decides the mode. Both poles are in use, and both are plain metal contacts — which is the point of the design:
- Pole 1 — throttle source. Selects what reaches the traction ESC's throttle input: the
accelerator pedal in manual, or the medulla's autonomous command (
CMD_ACC_DAC, out of the medulla on CN10.1) in autonomous. - Pole 2 — steering motor. Breaks the cable from the Cytron H-bridge to the steering motor, so in manual mode the steering motor is physically disconnected from its driver.
What this buys, and why it is a switch rather than electronics. Manual mode does not depend on the medulla, on firmware, or on anything being powered. With the whole electronics side dead, the pedal still reaches the ESC and the steering motor is still disconnected, because metal is touching metal. No software fault can accelerate or steer the kart while a human is driving it — the firmware is not in the path to make a mistake in. Any scheme where a chip or a microcontroller output performs this selection is strictly weaker, because it can only be as trustworthy as the code and the supply behind it.
The Cytron's 48 V supply is deliberately not switched. It stays permanently powered on the PACK48 rail. Gating it through the mode switch was tried and reverted: the inrush at every switch-to-autonomous browned out the Orin. Only the motor cable is broken, not the driver's supply.
The medulla cannot currently tell which mode the kart is in. Nothing routes the switch position
back to it, so firmware knows only what it last commanded. The intended fix for the next board
revision is a third pole on the switch, shorting a sense wire to ground in autonomous against a
pull-up on the medulla — one wire, read-only, which firmware can observe but never drive. It is not
built yet; the medulla pin is part of the v2 pin allocation still being decided in dv-hardware.
Wire list (whole kart)
One row per net (electrical node) across the whole kart — the tabular companion to the diagram above. The Connected pins column lists every device.pin tied together; medulla (the kart's ESP32-S3 interface PCB) CNx.y terminals map to GPIOs on the Kart Medulla connector pinout. This table is generated from wiring/wiring.yaml — edit the YAML, not the table; completeness is checked by scripts/check_wiring.py.
Scope and source of truth
Only the kart-medulla PCB has a KiCad project (dv-hardware) as its authoritative netlist — trust that for the medulla-internal nets. The rest of the kart (power distribution, traction, shutdown chain, motor) is not in KiCad; those rows are transcribed from the diagram and subsystem docs and should be field-verified before you rely on them. Wire colours follow the house code for wiring we run ourselves; vendor cables (Festo, power modules) keep their own colours, and 48 V pack cabling has no assigned code colour.
| Net | System | V | Colour | Connected pins | Notes |
|---|---|---|---|---|---|
| PACK48 | Power | 48V | — | battery.posbuck_48_12.in+esc.v+cytron.vin |
High-current traction feed. The Cytron sits here permanently, not on the 12 V rail and not switched by the mode switch. |
| 12V | Power | 12V | red | buck_48_12.out+medulla.CN1.2orin.pwr12kill1.acompressor.pos |
|
| 5V | Power | 5V | orange | medulla.CN2.3motor.hall5vacc_pedal.vccbrake_pedal.vcc |
Rail from Orin USB VBUS / XW-1224 buck (split-rail) |
| 3V3 | Power | 3.3V | yellow | medulla.CN1.1medulla.CN6.3steer_sensor.vcc |
|
| 24V (planned) | Power | 24V | — | press1.supplypress2.supplyvppm.v24 |
Shared sensor/VPPM rail, buck-boost not yet fitted |
| GND | Power | 0V | black | wago_gnd.pwrbattery.negbuck_48_12.in-buck_48_12.out-esc.v-medulla.CN1.3medulla.CN9.3medulla.CN10.3cytron.gndvppm.gndcompressor_fet.sourceebs_coil.bsdc_relay.coil- |
Power return: motors, valves, coils, rails. Ties to GND_SIG only at wago_gnd. |
| GND_SIG | Power | 0V | black/white | wago_gnd.sigsteer_sensor.gndacc_pedal.gndbrake_pedal.gndpress1.gndpress2.gndhyd1.gndhyd2.gndmotor.hallgnd |
Sensor/analog return. Black + white stripe. Single tie to GND at the rear wago_gnd block. |
| USB_ESP32 | Compute | 5V | orange | orin.usb_esp32medulla.USB |
Orin↔ESP32 command/telemetry (USB serial, no CAN) |
| USB_ZED | Compute | 5V | orange | orin.usb_zedzed2.usb |
USB 3.0 |
| MOTOR_U | Traction | 48V | — | esc.umotor.u |
|
| MOTOR_V | Traction | 48V | — | esc.vmotor.v |
|
| MOTOR_W | Traction | 48V | — | esc.wmotor.w |
|
| I2C_SDA | Steering | 3.3V | white/gray | medulla.CN4.2steer_sensor.sda |
|
| I2C_SCL | Steering | 3.3V | white/gray | medulla.CN4.1steer_sensor.scl |
|
| STEER_ANGLE_PWM (planned) | Steering | 3.3V | white/gray | medulla.CN5.2steer_sensor.pwm |
Future MT6701 single-wire PWM (R10 removed) |
| CMD_STEER_PWM | Steering | 3.3V | white/gray | medulla.CN9.1cytron.pwm |
|
| CMD_STEER_DIR | Steering | 3.3V | white/gray | medulla.CN8.3cytron.dir |
|
| STEER_M+_SW | Steering | 48V | — | cytron.mplusmode_switch.steer_in |
Cytron output up to the mode switch's second pole. M+ is the switched conductor — confirmed by Rubén 2026-08-08; M- runs straight through. |
| STEER_M+ | Steering | 48V | — | mode_switch.steer_outsteer_motor.mplus |
Open in manual mode — the switch's second pole physically disconnects the steering motor, so a firmware fault cannot steer the kart while a human is driving it. |
| STEER_M- | Steering | 48V | — | cytron.mminussteer_motor.mminus |
|
| PEDAL_ACC | Throttle | 0–5V | white/gray | acc_pedal.sigmedulla.CN6.2mode_switch.manual |
One net, two consumers: the medulla reads it on an ADC, and it goes to the mode switch's manual contact. In manual mode the pedal reaches the ESC through metal contacts only — the medulla is not in that path and does not need to be powered. |
| CMD_ACC_DAC | Throttle | 0–5V | white/gray | medulla.CN10.1mode_switch.auto |
|
| CMD_ACC_ESC | Throttle | 0–5V | white/gray | mode_switch.commonesc.throttle |
Gated throttle to the ESC |
| PEDAL_BRAKE | Brake | 0–5V | white/gray | brake_pedal.sigmedulla.CN6.1 |
|
| CMD_BRAKE_5V | Brake | 0–5V | white/gray | medulla.CN10.2opamp.in |
|
| CMD_BRAKE_10V | Brake | 0–10V | white/gray | opamp.outvppm.setpoint |
Proportional brake setpoint |
| CMD_COMPRESSOR_PWM | Brake | 3.3V | white/gray | medulla.CN8.2compressor_fet.gate |
Ex-BUZZ terminal |
| COMPRESSOR_MOTOR (in-design) | Brake | 12V | — | compressor.negcompressor_fet.drain |
12 V→~7.4 V via low-side PWM; FET/flyback sizing TBD |
| EBS_COIL | Brake | 12V | red | sdc_relay.no3ebs_coil.a |
12 V gated by the SDC relay; Festo form-C connector |
| PRESSURE_1 | Sensors | 0–10V | black | press1.outmedulla.CN7.1 |
Festo EN 60947-5-2: black = signal |
| PRESSURE_2 | Sensors | 0–10V | black | press2.outmedulla.CN7.2 |
Festo EN 60947-5-2: black = signal |
| HYDRAULIC_1 (planned) | Sensors | 3.3V | white/gray | hyd1.sigmedulla.CN9.2 |
Terminal reserved; hydraulic sensor not installed yet |
| HYDRAULIC_2 (planned) | Sensors | 3.3V | white/gray | hyd2.sigmedulla.CN5.1 |
Terminal reserved; hydraulic sensor not installed yet |
| MOTOR_HALL_1 | Sensors | 5V | white/gray | motor.hall1medulla.CN7.3 |
Level-shifted to 3.3 V on PCB |
| MOTOR_HALL_2 | Sensors | 5V | white/gray | motor.hall2medulla.CN2.2 |
Level-shifted on PCB |
| MOTOR_HALL_3 | Sensors | 5V | white/gray | motor.hall3medulla.CN2.1 |
Level-shifted on PCB |
| SDC_1 | Shutdown | 12V | white/gray | kill1.bimpact.a |
|
| SDC_2 | Shutdown | 12V | white/gray | impact.bres.a |
|
| SDC_3 | Shutdown | 12V | white/gray | res.bkill2.a |
|
| SDC_4 | Shutdown | 12V | white/gray | kill2.bkill3.a |
|
| SDC_5 | Shutdown | 12V | white/gray | kill3.bsdc_relay.coil+medulla.CN8.1 |
Coil node; medulla pulls it low via Q3 (S3 board), low-side of the relay coil — Q3 is N-channel so its reference must be ground. Confirmed by Rubén 2026-07-19. Its source belongs on PWR_GND in medulla-v2. |
| ESC_KEY_1 | Shutdown | — | white/gray | sdc_relay.no1esc.key1 |
Relay NO closes the ESC 2-wire key loop |
| ESC_KEY_2 | Shutdown | — | white/gray | sdc_relay.no2esc.key2 |
|
| REVERSE | Misc | 5V | white/gray | medulla.CN4.3ebox_reverse.rev |
Pull to 0 V to engage reverse (via Q4, BSS123) |
44 nets over 123 declared pins — 95% wired. Generated from wiring/wiring.yaml; run uv run python scripts/check_wiring.py to re-check completeness.
Festo pressure sensor connector (M8, 3-pin)
The two pneumatic-pressure sensors are Festo SDE5-D10-NF-Q6E-V-M8 (part 567465, 0–10 bar range, 0–10 V analog output; datasheet). Each has an M8×1, A-coded, 3-pin plug and connects with the NEBU-M8G3-K-2.5-LE3 cable (part 541333, wire colours to EN 60947-5-2). Both sensors share this identical pinout.
| M8 pin | Cable wire | Function | On the kart |
|---|---|---|---|
| 1 | Brown (BN) | Supply + | 24 V rail — sensor rated 15–30 V DC. This 24 V is a planned shared supply with the VPPM valve (from a 9–36 V → 24 V buck-boost, not yet fitted); the SDE5 also runs fine at 15–19 V. |
| 3 | Blue (BU) | 0 V / GND | Common ground |
| 4 | Black (BK) | Analog output 0–10 V | Proportional to 0–10 bar; divided + clamped on the medulla (ESP32-S3 PCB) to ≤ 3.3 V before its ADC |
Socket face (looking into the cable's M8 socket): pin 4 top, 3 left, 1 right.
Watch the colours: these are Festo's standard cable colours per EN 60947-5-2 — they do not follow the kart's colour code above. On this cable black is the signal output (not ground) and blue is ground. Wire by pin number, not by colour.
The outputs feed the ESP32 medulla as PRESSURE_1 and PRESSURE_2 (terminals CN7.1 / CN7.2) — see Kart Medulla → Connector pinout. The former PRESSURE_3 terminal (CN5.2) has been repurposed to the steering-angle PWM input (see below), so it no longer reads a pressure sensor. Each sensor's supply and its divider/clamp live on the medulla PCB, not in the harness.
Steering angle sensor wiring
The steering-angle sensor tells the medulla where the front wheels point, closing the steering position loop.
A MagnTek MT6701 encoder, sending its angle as a PWM duty cycle on a single wire (3.3 V CMOS square wave, ~994 Hz frame), into the freed PRESSURE_3 terminal. Mounted and reading on the kart since 2026-07.
One wire rather than a bus, because the run is long: the kart-medulla PCB is at the rear of the kart next to the Orin (they connect over USB), while the sensor stays on the steering shaft at the front — about 1.2 m apart. I²C does not survive that: it is single-ended open-drain, easy to glitch alongside the 48 V motor phases, and one glitch on SCL hangs the bus — which the on-board PCF8574 shares, so a front-cable disturbance would take down more than the steering read. A PWM duty cycle on one wire is robust over the distance and never touches that bus. See Angle Sensor.
| MT6701 module pin | Medulla terminal / ESP32-S3 | Notes |
|---|---|---|
| VCC | 3.3 V (CN1.1 / CN6.3) | 5 V only needed for a one-time EEPROM burn |
| GND | Signal GND (GND_SIG) |
Not yet resolved to a terminal. CN1.3 / CN9.3 / CN10.3 are the medulla's ground terminals, but they are currently recorded on the power ground net, and this sensor's return belongs on signal GND. Landing it on a power-ground terminal would bond the two grounds a second time. Check the KiCad project for the kart-medulla PCB's analog ground before wiring — see the open task in tasks.md. |
| SDA | GPIO 8 (I²C) | MT6701 address 0x06 (PCF8574 is 0x20 — no clash). Used for config + a bench angle cross-check |
| SCL | GPIO 9 (I²C) | |
| OUT (PWM) | CN5.2 → R8 → R9 → GPIO 1 | 20 kΩ series into the ESP32-S3 MCPWM capture. Board rework: remove R10 only (keep R8 + R9). |
| MODE | Tie for I²C/SSI | If left in ABZ mode, I²C won't respond |
The PWM wire is a plain signal line (kart color code: white/gray); keep it short and ideally twisted with its ground or shielded. Board topology after rework: CN5.2 —[R8 10k]— node —[R9 10k]— GPIO 1 —[R10 removed]. See Angle Sensor for why the MT6701 was chosen, and Kart Medulla for the terminal-level detail.
Festo valve & actuator connectors
Beyond the pressure sensors, the pneumatic brake chain uses two more Festo connector types. Full part detail is in the Pneumatic Braking BOM; the wiring-relevant summary:
- VPPM proportional brake valve (VPPM-8L-L-1-G14-0L10H-V1P-S1C1, part 571293; catalog doc · datasheet) — sets the autonomous brake pressure. Cable NEBU-M12W8-K-2-N-LE8 (part 542256), M12 8-pin shielded. Supply 24 V (21.6–26.4 V), setpoint 0–10 V from the medulla brake DAC (MCP4922 channel B → ×2 op-amp), max draw ~300 mA. Pins 1 and 5 are digital inputs D1/D2 (control-response select) — energising them locks out the valve's front-panel button config, so leave them per the datasheet. Take the per-wire colour map from the 542256 cable datasheet (linked in the BOM); it is deliberately not reproduced here rather than risk an unverified pinout.
- Solenoid valve coils (EBS = Emergency Braking System, plus the spare ASB = Autonomous Service Brake) — DIN form connectors, not M8/M12. The EBS coil (VACF-B-C1-5, part 8030810) is form C and mates with the MSSD-EB plug (part 151687); the spare ASB coil (VACF-B-B2-5, part 8030801) is form B and needs its own plug — they are not interchangeable. Both coils are 12 V DC / 3.4 W off the 12 V rail. See the BOM for the coil-interchangeability warning.
Related Pages
- Net Name Nomenclature — signal naming conventions across PCBs
- Throttle Pedal — pedal sensor wiring
- Steering Angle Sensor — AS5600 → MT6701 sensor choice and calibration
- Kart Medulla (ESP32-S3) — microcontroller wiring connections
- Pneumatic Braking — ASB + EBS pneumatic circuit and valve coil wiring