Skip to content

feat(pcb): per-console power distribution + monitoring CAN node (PDU) — INA180 telemetry #202

Description

@mottihoresh

Body consolidated 2026-07-08 — the original exploratory scope (below-the-fold history in comments) converged over 6 comments into a built board. This body now reflects current state; the comment thread holds the decision history.

Status — boards built, firmware bench done; soak next

PDU rev 0.2.0 assembled (#351, closed) and running PDU_Left firmware; bench sections 1, 2, 6 (client) and 7 pass (2026-10-23 update below). Remaining: sections 3–5 against a real load in the soak (#291), test_node_telem. Next board revision: #352 (rev 0.3.0). Rev 1 is instrumentation-first: measure the real cockpit load and let that data size the final fuses and shunts. (The original status from 2026-07-08 — routed, DRC 0/0, PR #217 — is history.)

Role / architecture

  • ~3 PDUs, one per console (Left · Right · Main Instrument). Each injects + monitors + fuses its console's power locally.
  • Sits PSU → PDU → console J_BUS. GND + CAN stay continuous across all PDUs; +12V/+5V are segmentable (a heavy zone dead-ends its OUT power pins → next zone gets a fresh injected feed).
  • Built on the PanelGroup base (STM32F103C8 + SN65HVD230 CAN + AMS1117) + design-block library (feat(pcb): OpenSkyhawk Design Block library (reusable power/CAN/MCU/harness circuits) #201). Own NODE_ID.

Locked design — as fabricated, rev 0.2.0 (see DESIGN-NOTES.md for full BOM/rationale)

Function Part Note
Current sense ×2 INA180A2 (SOT-23-5, gain 50) + 0.1%/25 ppm dividers → STM32 ADC analog high-side; NOT INA219/INA226 (relaxed accuracy → cheaper, inspectable SOP; INA219 = documented fallback if absolute-V ever needed; INA3221 QFN-banned)
Shunt ×2 10 mΩ 2512, 3 W, ±50 ppm/°C (RES-0R010-1PCT-2512, LCSC C2903468) Kelvin (4-terminal) via pad routing; re-sourced from C346481 / C500740 (both dead, see 2026-10-01 update)
Voltage sense dividers 12 V 33k/10k · 5 V 10k/13k, after the fuse (load side) rail-V + fuse-open detect (12 V; a blown F2 takes the PDU's own 5 V with it). 0.1 % on the ratio resistors from rev 0.3.0 (#352)
Temp NTC B3450 ±1% + STM32 internal sensor TMP117 dropped (WSON-banned)
Fuse ×2 12V 5 A · 5V 2 A MINI blade + holder source-side, off-board consumable; GND never fused
PSU input Mini-Fit Jr 4-pin 2×2 — J1: +12V_IN / +5V_IN / GND / GND J_PSU_IN
Bus J2 BUS OUT Mini-Fit Jr 8-pin (1–2 +12V, 3 +5V, 4/7/8 GND, 5/6 CANH/CANL — same as the PanelGroup / Gateway J_BUS) · J3 CAN IN Mini-Fit Jr 4-pin 2×2 (CANH / GND / GND / CANL; → CANH / CANL / GND / GND in #352) CAN IN is for a run that carries CAN without power; same housing as J1, so the harnesses can be swapped (#352 makes GND line up)
Input TVS D1 SMBJ12A (12V) · D2 SMBJ6.0A (5V, LCSC C5331096) per the #214 input-rail standard
  • Copper: large pours (12V 6–10 mm / 5V 5–8 mm / GND max, via-stitched) — sized for Kelvin accuracy + thermal margin, not current (a console is ~2–3 A). Fuse-aware neck rule: ≥2 mm per-console, ≥5 mm whole-bus — documented in docs/_source/base-boards.md § Pour sizing + base-boards-power-pour.svg.
  • Servo power: 12V rail → local buck → servos, never logic 5V (+ bulk cap + polyfuse). Servos become a 12V load (captured by the 12V INA180); keeps 5V monitoring clean. In hardware-standards.md.
  • Fault flags (TELEM_n, as built in feat(firmware): PDU monitoring node — telemetry firmware + new CAN telemetry packet class #216): per rail UNDER_V · OVER_V · OVER_CURRENT · FUSE_OPEN (12 V) · SENSOR_FAULT; board UNCAL_VDDA · UNCAL_ZERO · TEMP_WARN · TEMP_CRIT · NTC_FAULT. The worst one also goes to HEALTH_n.faultId; CAN health is reported by the node-status frames, not a PDU flag.

Remaining before this closes

Split off / related

Update — 2026-09-21 (Firmware v0.2.0 milestone)

Update — 2026-10-01 (PDU rev 0.2.0 boards ordered)

Ordered alongside the PanelGroup Rev 2 run in #209, since both had diverged from their fabbed
revision and neither had been assembled.

  • JLC W2026093021050394 (InvenTree PO-0018) — PDU rev 0.2.0 ×5 (Y23) + a 130×100 top-only
    solder-paste stencil (SO12609300758). Arrives ~Oct 15–22.
  • LCSC WM2610010130 (PO-0019) — PDU shortfall covered: INA180A2 ×10, fuse holders ×20,
    10 mΩ shunt ×20, 1 kΩ ×100, 1.5 kΩ ×100, 100 nF ×100.

Pre-fab gates: ERC 0 · DRC 0 violations / 0 unconnected / 0 schematic parity · silkscreen gate
passed (connector pin labels were already complete — 24 pins checked against their nets; only the
revision text needed reformatting to REVISION 0.2.0 | POWER DISTRIBUTION UNIT).

Shunt re-sourced — RES-0R010-1PCT-2512 had no live supplier. C346481 went out of stock
2026-07-10 and its replacement C500740 followed on 09-30. Now sourced as C2903468
(HoJLR2512-3W-10mR-1%, 2512, 3 W, ±50 ppm/°C, molded alloy non-inductive), added as an alternate
on the same IPN with both dead SKUs marked inactive, and set as the KiCad LCSC field on R1/R2.

Tempco history is C346481 ±100 → C500740 ±25 → C2903468 ±50. A step down from what it replaces, but
still better than the ±100 ppm this design originally accepted — and irrelevant against the real
error budget, where the shunt's own ±1 % tolerance (±30 mA at 3 A) is five times the ±50 ppm term
(±6 mA over 40 °C) and Vrefint contributes more again. 5× C500740 are already in stock, enough
for two PDUs, so nothing is blocked.

Rating on R1/R2 also corrected 2 W → 3 W to match the part actually fitted.

Fuses are still not a tracked part. F1/F2 are holders (XF-508P-B-B, C19727305) and the BOM
lists only the holders — nothing records what goes in them. Ratings are decided in
PCB/Base/Power/PDU/DESIGN-NOTES.md: F1 = 5 A on 12 V, F2 = 2 A on 5 V, standard MINI blade
(ATM/APM — not low-profile APS, which is the common mis-buy). Treated as an automotive consumable
bought outside InvenTree, but worth surfacing on the BOM or silk so an assembler sees it.

Firmware bench, accuracy and tuning on the PDU — carried from #216 (PR #343, merged)

The PDU firmware (PowerMonitor, Firmware/Panels/PDU_Left|Right|Center) is merged. Its logic and
the sampling path are proven on a non-PDU STM32F103 (logic tests 106/106, real-bus smoke, 1000
scans/s, calibration survives a reflash) — the measurements themselves are not. These steps
prove them on the real board, per PDU, before the v0.2.0 tag. Equipment: multimeter, a known load
(power resistor or electronic load) with an ammeter in series, a thermometer. Paper accuracy after
calibration: voltage ≈ ±0.5 %, current ≈ ±1.5 % + 10–20 mA — the bands below have margin over that.

1 — Bring-up

  • Flash the console's sketch (PDU_Left = 3, PDU_Right = 4, PDU_Center = 5); DiagSerial (115200) boot banner shows the right NODE_ID; the node appears in the client roster — PDU_Left: NODE_ID 3 confirmed on CAN (HB/HEALTH 0x103/0x143, kind PDU) rather than from the banner, which wasn't captured; in the client roster as PDU_Left prototype: replace Arduino Mega injector with RP2040 #3
  • RAW before calibration: rails read near 12 V / 5 V, temperature near room, scans/s ≈ 1000 — 12.263 V / 5.052 V, 27.0 °C, 1000 scans/s

2 — Calibrate (once per board; survives reflashes)

  • Measure the 3V3 rail with the DMM → CAL VDDA <mV>; CAL SHOW reports VDDA = yes and a Vrefint between 1100 and 1300 mV — DMM 3304 mV → Vrefint 1209 mV
  • Console load disconnected → CAL ZERO; it accepts (raw zero under 75 mA on 12 V / 120 mA on 5 V) and CAL SHOW reports ZERO = yes — raw 14 mA / 57 mA; zero12dmA=149, zero5dmA=576

3 — Accuracy against the meter (record PDU vs meter for each)

  • 12 V rail: PDU vAvg vs DMM at the bus-out connector — within ±100 mV
  • 5 V rail: same — within ±50 mV
  • Idle current after CAL ZERO: both rails within ±20 mA of 0 — 12 V ±1 mA, 5 V 0 mA
  • 12 V current at ~0.5 A and ~2 A known load vs the series ammeter — within ±(1.5 % + 20 mA) — waived: no load or ammeter on the bench. The 12 V channel has never carried current — first look in the soak (test(hardware): soak test panel — panel-mount controls on a printed or laser-cut faceplate, harnessed to two PanelGroups #291)
  • 5 V current at ~0.5 A and ~1.5 A — within ±(1.5 % + 20 mA) — waived: no reference load. Plausible: tracks real load steps (blank PanelGroup +44 mA, Gateway STM32 +18 mA, PanelBridge board +16 mA)
  • Board temperature vs a thermometer at the NTC, at room temperature — within ±1 °C — waived: no thermometer. Plausible: NTC 25–27 °C at room temperature
  • Out of band → set the gain trim / NTC offset and re-check — not needed: nothing measured out of band (bench-only for now: CalRecord has iGain* / vGain* / ntcOffsetDC fields but no CAL command sets them yet — add one in a small follow-up PR if a board needs it)

4 — Fault behaviour

  • Pull the 12 V fuse → FUSE_OPEN + UNDER_V flags on the 12 V page within ~1 s; the node turns amber in the client; refit → clears
  • Load above the over-current threshold for > 100 ms → OVER_CURRENT; below 90 % → clears after ~0.5 s — waived: no safe 4.5 A / 1.8 A load on the bench

6 — End to end

  • Tests/PanelBridge test_node_telem (USB-UART adapter on PA2/PA3 @ 250000, any STM32 board) — covered by the end-to-end run: real PDU frames → real PanelBridge → _NODE_TELEM → client. The sketch's drop / liveness edge cases weren't run on hardware
  • PDU telemetry visible end to end in the client → acceptance of feat: node data layer — PDU telemetry, node mapping, new-node detection SkyHawkClient#61 — _NODE_TELEM lines on the SimGateway CDC; client Cockpit tab matches RAW (12.30 V / 5.04 V / 0.09 A / 25 °C)

7 — Client cockpit checks with a real PDU (carried from SkyHawkClient fix-track chunk 2, OpenSkyHawk/SkyHawkClient#131; built and covered by automated tests, never run against a real PDU). Run with the client build from main once chunk 2 is merged.

  • A new PDU on the bus opens the Adopt dialog wherever it's clicked (never a board panel)
  • After adopting, a PDU that goes offline still reads as a PDU (its reported kind is stored) — PDU held in reset with SW1: only PDU_Left dropped, still shown as a PDU, its boards stayed linked
  • Power-zone pickers offer only PDUs in your cockpit (hidden ones included); Add all / pre-fill give "No power zone" when the default PDU isn't added — picker checked on the real PDU (hidden one listed with a "hidden" label); Add all / pre-fill covered by the earlier fake-data run
  • Hide the PDU: its boards keep their links; it never reads "(not added)"
  • Forget is refused while the PDU is online (incl. while only its telemetry arrives) and right after a reconnect; allowed offline, and it unlinks its boards — real PDU: disabled online, enabled offline, unlinked both boards, PDU returned as new; telemetry-only and just-reconnected cases covered by the fake-data run
  • The Forget note's fed-board count includes hidden boards — real PDU showed 2 fed boards; the hidden-board case is covered by the fake-data run
  • Importing a config whose boards link to a PDU outside your cockpit brings them in as "No power zone", and the preview says so — fake-data run only; not repeated on the real PDU

Update — 2026-10-22 (PDU 0.2.0 assembled + powered)

PDU 0.2.0 assembled alongside the PanelGroup and Gateway (record in #351): SMBJ TVS D1/D2 were fitted reversed (footprint issue, below) and flipped before first power-up; it then drew 30 mA on 5V with no firmware. Firmware bench (sections 1–7 above) runs in its own worktree session. As fitted: R5 and R20 both 0.1 % 10k; R14 fitted.

PDU — next revision

Moved to #352 (PDU rev 0.3.0): crystal load caps to GND, GND-compatible J3 CAN IN pinout, precision resistor fields, connector legends, fuse ratings on BOM/silk. The TVS item is dropped — the reversed TVS were an assembly misread of the cathode dot, not a footprint defect. Full PSU IN / CAN IN swap-proofing is tabled as a Notion idea.

Update — 2026-10-23 (PDU 0.2.0 firmware bench, PDU_Left)

Sections 1, 2, 6 and 7 pass on the real board; section 3's load and temperature checks and the over-current check are waived (no reference equipment). Tuning against a real console load (old section 5) and the full-console power-up check are removed — no real console exists to test against; the PduConfig.h defaults stand. Left (next bench session): 12 V and 5 V vs the DMM (probe C9 / C10 to GND) and the F1 fuse pull — then this issue can close.

Rework needed to bring it up — none of it firmware:

  • R18 (33 Ω SWDIO series): dry joint → SWD couldn't connect. Reflowed.
  • J6 (DEBUG SERIAL): pin 2 (TX) shorted to pin 3 (GND) from the earlier connector rework. Cleared.
  • HSE didn't start (RCC_CR HSERDY = 0 → firmware CLOCK FAULT, CAN at ~111 kbps instead of 500k). Design bug, below. Bodged C21/C22's shared node to GND (C19 pad 1) → 72 MHz, CAN 500k.

Bench numbers (calibrated, PanelGroups fed through J2): 12 V 12.27–12.30 V, 5 V 5.04–5.06 V, NTC 25–27 °C, 1000 scans/s, flags clear. The 5 V INA180 tracks load steps (blank PanelGroup +44 mA, Gateway STM32 +18 mA, PanelBridge board +16 mA; PanelGroup with firmware ≈ 70 mA). The 12 V current channel has not seen a real load yet — first check in the soak.

Bench gotcha: an ST-Link with its 3.3 V wire on a board's SWD header feeds that board's 3V3 from USB (~35–40 mA here) and hides it from the PDU's 5 V reading. Leave the 3.3 V wire off for any power measurement.

C21/C22 detail and the bodge are in #352. Every PDU 0.2.0 board needs the bodge (C21/C22 shared node → GND). Gateway, PanelGroup, ASN-41 and Armament_MCU crystals checked — correct.

Activity

  1. mottihoresh commented on Jun 30, 2026

    @mottihoresh
    CollaboratorAuthor

    PSU selected + power spec documented (PR #203)

    Source PSU: GOLDEN FIELD NX650 — 650W, 80+ Gold, fully modular, DC-DC, ~$60. Over-provisioned ~13× (cockpit ≈ 50W); chosen for clean modular cabling + expansion headroom. DC-DC topology → no minimum-load resistor needed.

    Constraints found (feed the injection + monitoring design)

    • Single +12V rail = 54A, and consumer ATX has NO per-pin / per-connector protection — only rail-level OCP (~60A) + dead-short SCP. A 15A fault through a 5A connector burns it long before OCP trips. → Per-lead source-fusing is mandatory — the fuse is the per-connector protection (12V ~5A / 5V ~3–4A, GND unfused). Strengthens the Fusing section above.
    • +5V is only on the IDE/SATA cables — PCIe / CPU / 12V-2x6 are +12V-only. The NX650 ships 2× IDE cables (3×SATA + 1×Molex each) → only 2 independent feeds that carry 5V. Impacts multi-zone injection: a 3rd 5V zone needs a 3rd IDE/SATA cable or a custom 6-pin→Mini-Fit lead. Use the Molex ends (~11A) for heavier feeds, SATA (~few A) for light; 12V-only zones (backlight) can use the PCIe cable.
    • All ports share the same internal rails (single-rail DC-DC) — the limit is the cable/connector, not a separate rail. Sum of all leads ≪ 54A / 18A.
    • Modular cables are brand-specific — ATX 3.1 standardizes only the device-side connectors (SATA/Molex/PCIe/24-pin), not the PSU-side modular sockets. Never reuse another PSU's modular cables.
    • Turn-on: jumper PS_ON# → GND (no motherboard).

    Soft-power tie-in for this node

    The monitoring MCU could run on +5VSB (always-on, 2.5A) and own PS_ON# control — giving a soft power button + AC-present sense + per-zone soft-enable, alongside the INA219 telemetry. Folds power sequencing into the same node.

    Documented

    docs/_source/base-boards.md → new Source fusing & per-console injection + PSU / source supply sections (PR #203). The segmentable pass-through (jumper / DNP) design-in is reflected there so future boards stay re-injectable with no redesign.

  2. mottihoresh commented on Jul 1, 2026

    @mottihoresh
    CollaboratorAuthor

    PDU design review — refined scope for the power node

    Converged design after external review + load re-analysis. The node is now framed as a PDU (Power Distribution Unit) — a smart per-console power injection node, not a per-device distributor.

    Architecture

    • ~3 PDUs, one per console: Left Console · Right Console · Main Instrument Panel. Each injects + monitors + protects its console's power locally. (= the per-console injection plan, made concrete.)
    • Sits between PSU → console J_BUS (feeds the base-board bus pass-through in base-boards.md). GND + CAN stay continuous across all PDUs.

    Rails monitored: 12V + 5V

    3.3V is generated locally on each board (AMS1117) → no central 3V3 monitoring.

    Current monitoring — INA226 (supersedes the earlier INA219 note)

    One INA226 per rail (12V, 5V). Chosen over INA219 for an instrumentation board:

    • 16-bit ADC (vs 12-bit); input offset ~±10µV vs ~±100µV → ~10× better low-current accuracy (idle current is the whole point of Rev1).
    • Alert pin → hardware over/under-current IRQ to the STM32 (not polling) → serves fault detection.
    • Programmable averaging (1–1024) → clean readings of PWM LED + servo loads. 36V headroom.
    • Cost delta trivial at our volume (6 units × ~$1 ≈ $6). Bare VSSOP-10 on the PCB, not a module.
    • (Alt for a simpler later rev: INA260 = integrated 2mΩ shunt, no Kelvin — but fixed shunt, coarse at low current. Rev1 = INA226 + external shunt.)

    Power path + shunt

    Power In -> Fuse -> Shunt -> Console Output
    
    • Fuse protects everything downstream.
    • Shunt: 10mΩ, 2W, Kelvin (4-terminal) → ±81.92mV / 10mΩ = ~8.19A full-scale, 0.25mA/LSB. Design the footprint so a different shunt value can be swapped later.
    • Kelvin sense: INA226 sense lines connect directly to the shunt Kelvin pads via thin dedicated traces — never share high-current copper.
    • Fuse-open detection needs voltage sense on BOTH sides of the fuse (INA226 alone reads "0 current" — can't tell fuse-open from no-load).

    Temperature — TMP117

    One digital temp sensor near (not under) the 12V shunt. Overheat detection + thermal-design validation for Rev1.

    Superseded (2026-10-23): TMP117 was dropped (WSON/DSBGA only — banned package). As built: 10 kΩ NTC thermistor TH1 (B3450, ±1 %, 1206) between the 12 V and 5 V pours, read on PA6, plus the STM32 internal sensor. See the issue body's Locked design table and PCB/Base/Power/PDU/DESIGN-NOTES.md § B3.

    Fault detection (firmware, over CAN as a bitmap)

    12V/5V UV · 12V/5V OV · overcurrent · fuse-open · sensor failure · CAN failure · temp warning · temp critical.

    Copper — 2-layer, 1oz

    Large pours (not traces): 12V ~6–10mm, 5V ~5–8mm, GND max + heavily via-stitched top↔bottom. Note the pours are sized for low-R (Kelvin accuracy) + thermal margin at the aggregation point, not current (a console is only ~2–3A). No narrow necks at connector / fuse / shunt / output.

    Servo power — 12V→buck, NEVER logic 5V (new standard)

    5–6 MG90 servos/console ≈ 2–3A running (up to ~6A stall) if put on 5V → brownout + I²C glitches + blows the 2-feed 5V budget. So:

    12V console rail -> local buck (5/6V) -> servos   (+ local bulk cap + polyfuse)
    

    Same power on 12V = ~1–1.5A (buck ~halves rail current) + isolated from logic. Servos become just a 12V load → captured by the 12V INA226; 5V monitoring stays clean. No dedicated servo PDU/output needed.

    Revised per-console load budget

    Rail Load ~Current/console
    12V LEDs ~1A + servo-buck ~1–1.5A ~2–3A
    5V logic + OLED only (servos moved off) ~1A

    Corrected LED budget: 500 LEDs → 100× 5-series strings → ~3–4A total cockpit-wide (not 20A). Keeping servos off 5V also resolves the "+5V only on 2 IDE/SATA feeds" constraint.

    Rev1 = instrumentation platform

    Primary purpose is measurement, not optimization. Collect idle / startup / lighting / peak / normal current → let real data drive final fuse sizes, whether more/specialized PDUs are justified, shunt values, and rail separation. Revisit the 3-zone architecture after a few months of data.

    PDU outputs (Rev1)

    • 12V — monitored + fused
    • 5V — monitored + fused
    • No dedicated servo output (handled locally via buck).

    To do

  3. mottihoresh commented on Jul 3, 2026

    @mottihoresh
    CollaboratorAuthor

    State going into the PDU build — decisions from 2026-07-03 (docs in PR #212, unmerged)

    Refinements this session that feed the PDU design. Docs updated in docs/_source/base-boards.md + docs/architecture/power.md (PR #212).

    Resolved

    • Connector split (3-pin CAN + 6-pin power) → DROPPED. Keep the fabbed 8-pin J_BUS. The power-vs-CAN split is realized as a Y-harness into J_BUS_IN at each injection node, not a second board connector:
      • +12V / +5V / GND ← from the PSU/PDU (through this console's fuse)
      • CANH / CANL / GND ← from the previous node's J_BUS_OUT (its power pins dead-end → power never crosses the console boundary; CAN stays one continuous bus)
      • GND is the single common net tying both. Board keeps one 8-pin J_BUS footprint.
    • Monitor = INA226 (confirmed — the body still says INA219, see stale-body note below).

    Refined

    • Fuse blanket = +12V 5 A · +5V 4 A (5V poured, not a 0.5 mm trace) — whole-bus upper bound; per-console / per-zone comes down, final sizing data-driven (Rev1 instrumentation-first).
    • Copper sized to the fuse, not the load. 5 mm of 1 oz external ≈ 7 A (IPC-2221 @10 °C; 1 mm ≈ 2.5 A) → clears the 5 A/4 A blanket. The 1 mm / 2.5 A figure is a local sub-1 A tap only, never the fused trunk (it had contradicted the 5 A blanket — fuse > copper — now resolved). Pour-neck rule is fuse-aware: ≥2 mm per-console segment (≤~3 A), ≥5 mm whole-bus. The PDU's 12V 6–10 mm / 5V 5–8 mm pours clear this comfortably (they're Kelvin-accuracy + thermal driven, not current).
    • Granularity follows consumption. A console is the default injection zone; a power-hungry group graduates to its own dedicated PDU (12V/5V direct from PSU, its own fuse sized to just that group). PSU ~54 A @12v = ample headroom → the per-zone fuse is downstream protection + fault isolation, not source rationing. Rev1 default stays ~3 PDUs / console.

    Build note — GND at injection (two sources)

    At an injection node GND arrives from both the PSU return (fat, 18 AWG) and the previous node's CAN harness (thin, ~24 AWG). Same net. Keep the PSU GND as the dominant low-impedance return; treat the CAN-side GND as a reference tie only — else the thin CAN-GND wire carries power return it isn't sized for.

    Stale in the body (for tonight)

    • INA219 → INA226 (per the 2026-07-01 design-review comment).
    • Open decision "connector split scope" → now resolved (dropped, use J_BUS).

    Still open / not yet in any doc

    • Servo-power standard (12V → local buck → servos, never logic 5V + bulk cap + polyfuse) → add to hardware-standards.md (already a to-do here).
    • 12V load-budget refresh — power.md board table (≤500 mA/board) + cockpit ~3 A are LED-only; servos-on-12V push cockpit to ~6–8 A.
    • PDU pour widths (12V 6–10 mm / 5V 5–8 mm) live only in comments — not a committed PCB doc yet.
  4. mottihoresh commented on Jul 3, 2026

    @mottihoresh
    CollaboratorAuthor

    PDU Rev1 — parts research complete, board scaffolded (2026-07-03)

    Sensing/power-path parts locked and datasheet-verified. Board scaffolded at PCB/Base/Power/PDU/ on branch pcb/pdu-power-202; full BOM + rationale in PCB/Base/Power/PDU/DESIGN-NOTES.md.

    Locked BOM (per PDU)

    Function Part LCSC Notes
    Current sense ×2 INA180A2IDBVR (SOT-23-5, gain 50) — analog → STM32 ADC; unidirectional high-side
    Shunt ×2 Milliohm HoRCG27284R010F1T 10mΩ 2728 4W ±25ppm C53115028 Kelvin via pad routing
    Voltage sense 0.1% 25ppm dividers → STM32 ADC (both sides of each fuse) — rail-V + fuse-open
    VDDA ref STM32 internal Vrefint (free) — LM4040 footprint DNP
    Temp NTC APV ANTC3216-103F3450FB (±1%, B3450) + STM32 internal sensor C52155460 between 12V/5V pours
    Fuse ×2 MINI blade (5A on 12V, 2A on 5V) + XFCN XF-508P-B-B holder C19727305 MINI/APM, DIP-4
    PSU input Molex Mini-Fit Jr 6-pin 2×3 (2×+12V / 1×+5V / 3×GND) — GND ~7A return over 3 pins
    Bus ×2 Molex Mini-Fit Jr 5566-08A2 (J_BUS_IN/OUT) — reused
    MCU / CAN / LDO STM32F103C8 · SN65HVD230 · AMS1117-3.3 — reused blocks (PanelGroup_Base)

    ADC use 7/10 on F103C8 · sensing ≈ $0.70/board.

    Key decisions (supersede stale body text)

    • Current/voltage monitor: INA180 + dividers — NOT INA219/INA226. Relaxed accuracy target (±10–20 mA; absolute voltage not critical, brownout/droop trends enough) made the 16-bit INA226 unnecessary. INA180A2 (analog) is cheapest in an inspectable SOP-class package and ≤ the $1/chip budget. INA219 ($0.98/rail, digital self-cal) is the documented fallback if absolute-V accuracy is ever required. INA3221 (3-ch, would be one chip for both rails) is QFN → banned by the inspectability rule.
    • INA180 offset: ±500µV max @vcm=12V → ~±50 mA raw floor on the 12V rail. Removed by a one-point FW zero-cal (read at I=0, subtract) at bring-up; residual = drift only.
    • Temperature: NTC + STM32 internal sensor — TMP117 dropped (ships WSON/DSBGA only → banned). NTC ±1% B3450 gives ~±0.3–0.5 °C. Also enabling the free STM32 internal temp sensor as node die-temp telemetry (cross-node convention tracked separately).
    • Connector split (3-pin CAN + 6-pin power): already dropped — power/CAN split is a Y-harness into the fabbed 8-pin J_BUS. PSU-side input is a separate 6-pin Mini-Fit Jr.

      Superseded (2026-10-23): as built, rev 0.2.0 has J1 PSU IN as a 4-pin 2×2 Mini-Fit (+12V / +5V / GND / GND), J2 BUS OUT 8-pin, and a separate 4-pin J3 CAN IN for runs that carry CAN without power. See the issue body's Locked design table and feat(pcb): PDU rev 0.3.0 — crystal load caps to GND, GND-compatible CAN IN, next-revision fixes #352 (J3 re-pin).

    • Soft-power / PS_ON#: dropped — not on these cards (PSU jumpered always-on).
    • 5V fuse = 2A (not the old 4A blanket) — per-console 5V is ~1A after servos move to a 12V→buck (servos not fitted yet).

    FW carry-forward (bring-up)

    1. INA180 one-point zero-cal (offset).
    2. VDDA correction via internal Vrefint (F103 uncalibrated → one-point cal).
    3. Internal-temp-over-CAN convention for all nodes.

    Next

    B2 schematic — stamp the reused blocks (STM32 core / SN65HVD230 CAN / AMS1117) from PanelGroup_Base.

  5. mottihoresh commented on Jul 4, 2026

    @mottihoresh
    CollaboratorAuthor

    PCB stage complete — PR #217 (2026-07-04)

    Hardware deliverable done. PR #217 (pcb/pdu-power-202 → main) — board routed, DRC 0/0, ERC-clean, 3D models.

    BOM closed — every LCSC datasheet-verified, new parts in InvenTree, reused parts pull LCSC from InvenTree (source of truth). Full table: PCB/Base/Power/PDU/DESIGN-NOTES.md.

    Key part decisions (supersede earlier body/comments):

    • Current/voltage monitor = INA180A2 + 0.1%/25ppm dividers, NOT INA219/INA226 (relaxed accuracy → cheaper analog; INA3221 QFN-banned).
    • Temp = NTC B3450 ±1% + STM32 internal sensor, TMP117 dropped (WSON-banned).
    • Shunt = CSRF2512 2512 C346481 (reverted from 2728 C53115028 — no stock footprint).

      Superseded (2026-10-23): C346481 went out of stock; the shunt is now 10 mΩ 2512 3 W ±50 ppm, LCSC C2903468 (see the 2026-10-01 update and the Locked design table in the issue body).

    • Connectors = Mini-Fit Jr 5566 (J_PSU_IN 4-pin + J_BUS 4/8-pin), chxunda clones OK.
    • Fuse inserts (5A/2A MINI blade) = off-board consumable, not PCBA.

    Split off:

    Order status: bare boards ordered (JLCPCB fab, in transit). Components (LCSC parts, per DESIGN-NOTES BOM) pending — batched with the Right Nav LCSC order.

    Remaining before this closes: merge #217 · receive boards + components · hardware bench verify. Firmware tracked separately in #216.

  6. 2 remaining items

  7. mottihoresh commented on Jul 6, 2026

    @mottihoresh
    CollaboratorAuthor

    5 V input TVS changed: SMBJ5.0A → SMBJ6.0A (2026-07-05)

    Reason: 5.0A standoff (5.0 V) sits at nominal → leaks ≤800 µA near the +5 % rail corner (5.25 V). 6.0A (6.0 V standoff) clears 5.25 V → leakage ~0. ~1 V more clamp (9.2→10.3 V), still < DRV8833 VM abs-max 11.8 V. Identical DO-214AA footprint → drop-in, no layout change.

    Done (PR #218):

    • DESIGN-NOTES.md protection section + BOM: D2 SMBJ5.0A/C113974 → SMBJ6.0A/C140903.

    Still open on this board:

    • D2 schematic symbol still reads SMBJ5.0A → swap to SMBJ6.0A on the next KiCad touch (GUI: change value/MPN/LCSC only, footprint unchanged).
    • Order SMBJ6.0A (not 5.0A) for the 5 V position; 12 V stays SMBJ12A. Confirm the 12 V bulk cap is ≥25 V.

    12 V TVS (D1 SMBJ12A) unchanged.

  8. mottihoresh commented on Jul 6, 2026

    @mottihoresh
    CollaboratorAuthor

    5V TVS supplier part locked: LCSC C5331096 (MSKSEMI SMBJ6.0A) — supersedes the placeholder C140903.

  9. changed the title [-]feat(pcb): power distribution + monitoring CAN node (segmentable injection, INA219 telemetry)[/-] [+]feat(pcb): per-console power distribution + monitoring CAN node (PDU) — INA180 telemetry[/+] on Jul 8, 2026
  10. added this to the Firmware v0.2.0 milestone on Sep 21, 2026
  11. self-assigned this
    on Sep 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requesthardwarePCB, KiCad, and hardware designneeds testingFirmware / Code is complete including unit tests, final bench testing needs to be done.

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions