board
Solar MPPT Power System
Public Unreviewedby TylerK
A 30 W solar battery charger with regulated 5 V and 3.3 V rails: an STM32G031 running perturb & observe MPPT and a CC/CV charge state machine, steering a TI LM5175 4-switch buck-boost through a single analog control input. Four-layer KiCad board, schematic and PCB generated from Python, with an electrothermal simulation run against the published board file.
← Commit history
Clean up wiki page: prioritize simulation-driven copper fixes over old-board comparisons, trim old-board framing throughout the design docs, improve the 3D hero render (better lighting, full board in frame)
5 files changed
+154−214
README.md+71−105@@ -1,56 +1,70 @@ # Solar MPPT Power System (MCU/IC) -A 30 W solar battery charger with 5 V / 3.3 V point-of-load rails — the MCU/IC-based-counterpart to this page's original discrete-analog design. Same job (panel → protection-→ MPPT/charge → 12 V SLA/AGM battery → regulated 5 V/3.3 V outputs), same 14.2 V CV-target, deliberately different build: a TI LM5175 4-switch synchronous buck-boost-controller, two INA180 current-sense amplifiers, an LM74700 active ideal-diode stage,-integrated synchronous POL bucks, and an STM32G031F8Px MCU running real perturb &-observe MPPT plus CC/CV charge arbitration in firmware — replacing the LM324/LM393/-TL431/NE555 discrete control stack entirely. The full side-by-side is in-[`docs/05-comparison-vs-old-board.md`](docs/05-comparison-vs-old-board.md).--**This page replaces the original discrete-analog build.** The old design's full-documentation, schematic and PCB are preserved as-is in-[`docs/01-architecture-analysis.md`](docs/01-architecture-analysis.md)'s history and the-repo's earlier commits — nothing about that board's engineering was wrong, this is a-genuine architectural alternative built to compare against it directly, per the same-brief with the "no MCU / no dedicated ICs" constraint deliberately lifted.+A 30 W solar battery charger with 5 V / 3.3 V point-of-load rails: a TI LM5175+4-switch synchronous buck-boost controller, two INA180 current-sense amplifiers, an+LM74700 active ideal-diode stage, integrated synchronous POL bucks, and an+STM32G031F8Px MCU running real perturb & observe MPPT plus CC/CV charge arbitration in+firmware. Charges a 12 V SLA/AGM battery to 14.2 V CV across the panel's full 6-24 V+input range. --- -## Why build both+## Simulation-driven copper fixes -The old board's own docs are explicit that its buck-only topology needs the panel above-roughly 15-16 V to charge at all — a real, stated limitation, not an oversight, and a-fixed-fractional-Voc divider approximates the maximum-power point rather than tracking-it. Lifting the "basic parts only" constraint fixes both: a 4-switch buck-boost charges-across the panel's full 6-24 V range, and firmware runs actual adaptive P&O. The trade-is real too — more than double the component count on a smaller board, three genuinely-fine-pitch ICs the old THT-and-generous-SOIC design never had to contend with, and-firmware becomes a dependency the old board simply doesn't have. Full trade-off-discussion in the comparison doc linked above.+An electrothermal (DC current-density + steady-state thermal) simulation was run+directly against this board's own `.kicad_pcb` — the report's recorded SHA-256 matches+the file published here — and two real routing problems it found have since been fixed.++++**Fix 1 — width-classification gap.** The first run found the raw VBATT node carrying+its full 2.5A design current on a thin 0.25mm signal-width trace: **431mV drop, 172.5mΩ,+1.08W loss**. Root cause: the router classifies power nets by matching keywords against+net *names*, but several genuinely high-current nets got KiCad-auto-generated names that+matched no keyword, so they were routed at signal width purely because of how they+happened to be named, not their actual current. Fixed by widening 503 track segments+across 8 affected nets to 0.6mm — worst case dropped to **307mV / 123mΩ / 0.77W**.++**Fix 2 — routing-length problem.** That still left `/VBATT` (charge shunt to battery+connector) as the worst case at the wider width — the measured resistance implied a+~150mm routed path against a 93.8mm straight-line distance, since the net's chain+routing visits several other pads in between rather than going direct. Fixed **without+touching the existing routing**: added one additional direct 0.6mm path between the two+points, run electrically in parallel with the existing long one.++**Result: 431mV → 307mV → 74mV**, an 83% total reduction from the first simulation run+to the current board. Both fixes verified against DRC (0 unconnected items throughout;+the second fix was DRC-neutral). Full numbers, method, and what's still open in+[`docs/simulation/05-electrothermal-simulation.md`](docs/simulation/05-electrothermal-simulation.md).++++Thermally: a deliberately conservative composite case (every documented worst-case+component loss applied simultaneously, 4.29W total) at 25°C ambient predicts a **48.5°C+peak board temperature**, 30.4°C area average — modest, not extreme, over the LM5175+power stage cluster. Both results are **screening models** (board-surface temperature,+not junction temperature; DC-only copper resistance excluding component/connector/+solder-joint resistance) — full caveats in the linked report. ## The board  -102 components across 9 functional blocks on a 195 x 135 mm, 4-layer board (versus the-old board's 45 references on 250 x 160 mm): solar input & protection (fuse, LM74700-ideal-diode stage), housekeeping bias (LM5165, self-starting off raw panel input),-the LM5175 MPPT/charge power stage, current/voltage sensing (2x INA180), the MCU, two-POL buck stages (TPS62130 5 V/2 A, TLV62569 3.3 V/1 A), output filtering, and connectors-plus test points. Full block-by-block breakdown in-[`docs/03-schematic-summary.md`](docs/03-schematic-summary.md).+102 components across 9 functional blocks on a 195 x 135mm, 4-layer board: solar input+& protection (fuse, LM74700 ideal-diode stage), housekeeping bias (LM5165,+self-starting off raw panel input), the LM5175 MPPT/charge power stage,+current/voltage sensing (2x INA180), the MCU, two POL buck stages (TPS62130 5V/2A,+TLV62569 3.3V/1A), output filtering, and connectors plus test points. Full+block-by-block breakdown in [`docs/03-schematic-summary.md`](docs/03-schematic-summary.md).   -Both close-ups show the real fine-pitch layout challenge this board has that the old one-didn't: U8/U9 (the POL bucks) are QFN-16 at 0.5mm pitch and SOT-563 at 0.5mm pitch, and-U4 (the LM5175) is an HTSSOP-28 at 0.65mm pitch — see "PCB status" below for how that-played out in routing. Full 4-layer copper routing plot: [`docs/routing.svg`](docs/routing.svg).+Both close-ups show the fine-pitch layout this board's density demands: U8/U9 (the POL+bucks) are QFN-16 at 0.5mm pitch and SOT-563 at 0.5mm pitch, and U4 (the LM5175) is an+HTSSOP-28 at 0.65mm pitch — see "PCB status" below for how that played out in routing.+Full 4-layer copper plot: [`docs/routing.svg`](docs/routing.svg). ## Control architecture @@ -59,9 +73,8 @@ the regulated battery-bus voltage. Every constraint the firmware enforces — ch current limit, battery CV ceiling, MPPT power tracking — is expressed as "what VBATT setpoint would this constraint want," and an arbitrator commands the most restrictive (lowest) of those candidates each cycle. Full firmware architecture, the FB summing-node-transfer function (and a real resistor-value bug caught and fixed while deriving it — see-below), and the accepted charge-current-as-MPPT-proxy design decision are documented in-[`firmware/README.md`](firmware/README.md) and+transfer function, and the accepted charge-current-as-MPPT-proxy design decision are+documented in [`firmware/README.md`](firmware/README.md) and [`docs/02-detailed-design-calculations.md`](docs/02-detailed-design-calculations.md). **A real design bug caught before it reached hardware:** working through the LM5175 FB@@ -82,53 +95,9 @@ capacity limits. **ERC: 0 errors**, 10 cosmetic warnings. Full breakdown, includ several genuinely non-obvious router bugs found and fixed along the way (a KiCad rect-pad-rotation DRC quirk, an A* pathfinding bug that let routes "teleport" between copper layers with no via, GND-via sequencing), in-[`docs/04-pcb-layout-review.md`](docs/04-pcb-layout-review.md).--This is the one place this page is **not** claiming parity with the old board, which-reached 0 DRC errors outright. A manual clearance pass around U4/U7/U8-U9 in the-interactive PCB editor is the recommended next step before fabrication.--## Electrothermal simulation--Run on **this exact board** — the simulation's recorded SHA-256 matches the `.kicad_pcb`-published here.----A deliberately conservative composite case (every documented worst-case component loss-applied simultaneously, 4.29 W total) at 25°C ambient with natural convection predicts a-**48.5°C peak board temperature**, 30.4°C area average — modest, not extreme. Hotspot-sits over the LM5175 power stage cluster (Q2-Q5, U4, L2), not any single part.----**Two design changes came directly out of this simulation.** The first run found the raw-VBATT node carrying its full 2.5A design current on a thin 0.25mm signal-width trace —-**431mV drop, 172.5mΩ, 1.08W loss**. Root cause: the router classifies power nets by-matching keywords against net *names*, but several genuinely high-current nets got-KiCad-auto-generated names that didn't match any keyword, so they were routed at signal-width purely because of how they happened to be named, not their actual current. Fixed-by widening 503 track segments across 8 affected nets to 0.6mm and re-running the-simulation — worst case dropped to **307mV / 123mΩ / 0.77W**, about a 30% reduction.--That left one case unresolved: `/VBATT` from the charge-current shunt (RS2) to the-battery connector (J2), already at the wider 0.6mm width, was still the worst case —-a **routing-length** problem, not a width problem (the measured resistance implied a-~150mm routed path against a 93.8mm straight-line distance, since the net's chain-routing visits several other `/VBATT` pads in between). Fixed **without touching the-existing routing**: added one additional direct 0.6mm path between RS2 and J2, running-electrically in parallel with the existing long one. Result: **307mV/123mΩ -> 74mV/-29.6mΩ**, a 76% reduction, and no longer the board's worst case at all — that's now-`vbatt_raw_2p5A` (the LM5175 boost-leg output before the shunt) at 98mV/39mΩ, a segment-neither fix touched. Both fixes verified against DRC (0 unconnected items throughout;-total violation count 354 -> 401 -> 401, i.e. the second fix was DRC-neutral). Full-writeup in-[`docs/simulation/05-electrothermal-simulation.md`](docs/simulation/05-electrothermal-simulation.md).--Both current-density and thermal results are **screening models**: board-surface-temperature rather than junction temperature, DC-only copper resistance excluding-component/connector/solder-joint resistance. Method, mesh convergence, and sensitivity-data are in the same linked report.+[`docs/04-pcb-layout-review.md`](docs/04-pcb-layout-review.md). A manual clearance pass+around U4/U7/U8-U9 in the interactive PCB editor is the recommended next step before+fabrication. ## Firmware @@ -136,9 +105,7 @@ STM32G031F8Px, P&O MPPT + CC/CV battery charge state machine (BULK → ABSORPTIO FLOAT), all detailed in [`firmware/README.md`](firmware/README.md) including the exact CubeMX pin/peripheral configuration needed to build it. **Written and manually reviewed, not build-or-flash-tested** — no STM32 toolchain is available in the-environment this was built in. This is a real, stated gap the old board never had (every-one of its control functions is a fixed analog circuit, verifiable on paper and bench-alone).+environment this was built in. ## Verified specifications @@ -150,7 +117,7 @@ alone). | Nets | 60 signal/power + GND plane | | Routing | 2,587 track segments, 203 vias, **0 unconnected items** | | ERC | **0 errors**, 10 cosmetic warnings |-| DRC | 0 unconnected; ~401 other findings (see PCB status above) |+| DRC | 0 unconnected; 401 other findings (see PCB status above) | | Source tool | KiCad 10.0.2 | | MCU | STM32G031F8Px (TSSOP-20) | | Power stage | TI LM5175 4-switch synchronous buck-boost |@@ -162,9 +129,9 @@ alone). | Parameter | Value | Basis | |---|---|---|-| Panel | 30W, 6-24V input range | same brief as the old board |-| Battery | 12V SLA/AGM, 14.2V CV target | same target as the old board, for direct comparison |-| Panel-side current ceiling | 5.0A (30W / 6V floor) | conservative sizing convention shared with the old board |+| Panel | 30W, 6-24V input range | design brief |+| Battery | 12V SLA/AGM, 14.2V CV target | design brief |+| Panel-side current ceiling | 5.0A (30W / 6V floor) | conservative sizing convention | | Charge current (bulk CC) | 2.0A | firmware `BATT_CC_BULK_LIMIT_A` | | Absorption taper threshold | 0.10A, 10 min minimum | firmware charge state machine | | Float voltage | 13.6V | firmware `BATT_CV_FLOAT_V` |@@ -174,16 +141,14 @@ alone). ## Design record -Written as the design progressed, mirroring the old board's own document structure:- | Document | Contents | |---|---|-| [`01-architecture-analysis.md`](docs/01-architecture-analysis.md) | Block diagram as built, MCU control architecture, deviations from the original candidate proposal |-| [`02-detailed-design-calculations.md`](docs/02-detailed-design-calculations.md) | Shunt/gain sizing, the corrected FB summing-node derivation, MPPT-via-ICHG rationale, POL selection |+| [`01-architecture-analysis.md`](docs/01-architecture-analysis.md) | Block diagram as built, MCU control architecture |+| [`02-detailed-design-calculations.md`](docs/02-detailed-design-calculations.md) | Shunt/gain sizing, the FB summing-node derivation, MPPT-via-ICHG rationale, POL selection | | [`03-schematic-summary.md`](docs/03-schematic-summary.md) | Component count, bugs found during generation, the FB divider bug caught before hardware |-| [`04-pcb-layout-review.md`](docs/04-pcb-layout-review.md) | Layer stack, autorouter bugs found and fixed, known remaining DRC findings, what to do before fabrication |-| [`05-comparison-vs-old-board.md`](docs/05-comparison-vs-old-board.md) | Full side-by-side against the discrete-analog board — what changed, what got harder, when to pick which |-| [`simulation/05-electrothermal-simulation.md`](docs/simulation/05-electrothermal-simulation.md) | Electrothermal simulation report, including the design change made from it |+| [`04-pcb-layout-review.md`](docs/04-pcb-layout-review.md) | Layer stack, autorouter bugs found and fixed, known remaining DRC findings, the two simulation-driven copper fixes |+| [`simulation/05-electrothermal-simulation.md`](docs/simulation/05-electrothermal-simulation.md) | Full electrothermal simulation report, both design changes made from it |+| [`05-comparison-vs-old-board.md`](docs/05-comparison-vs-old-board.md) | For reference: a side-by-side against this project's earlier discrete-analog board revision | ## Generated, not drawn @@ -196,16 +161,17 @@ Neither the schematic nor the PCB was drawn by hand. Both are emitted by the Pyt | `schgen2.py` | Schematic writer + a from-scratch intended-vs-actual connectivity verifier (plain ERC doesn't catch wire-routing shorts) | | `symlib.py` / `fplib.py` | Read real `.kicad_sym`/`.kicad_mod` libraries and emit placed instances | | `pcbgen.py` | Placement: parses the real netlist, places all 106 footprints |-| `route.py` / `route_fixup.py` / `route_polish.py` | The custom grid-based multi-layer A* autorouter, its fixup pass (adds a 3rd emergency routing layer for the hardest links), and a final connectivity-polish pass |+| `route.py` / `route_fixup.py` / `route_polish.py` / `route_stitch.py` | The custom grid-based multi-layer A* autorouter, its fixup and polish passes, and the parallel-stitch follow-up for the `/VBATT` routing-length fix | ## Before you fabricate this -Not built or bench-tested. In addition to the old board's still-open items (confirm the-real panel's Voc/temperature coefficient; confirm the battery chemistry):+Not built or bench-tested. - **Manual DRC clearance pass** around U4/U7/U8-U9 (see "PCB status" above) — the fastest path to a fully clean board. - **Firmware needs real build/flash/bench validation** — currently reviewed but untested.+- **Confirm the real panel's Voc/temperature coefficient** — input protection component+ ratings currently assume a worst case pending the actual panel datasheet. - **R16/R17 (LM5175 VOSNS overvoltage threshold)** needs independent re-derivation against the real datasheet value; currently carries forward a since-corrected ratio. - **LM5175 FB reference (1.0V)** is a datasheet-typical assumption, not independently@@ -214,7 +180,7 @@ real panel's Voc/temperature coefficient; confirm the battery chemistry): ## What's in this repo ```-docs/ the design record (5 documents) + board images+docs/ the design record (6 documents) + board images docs/simulation/ electrothermal run: report, figures, CSVs, reproducer script firmware/ STM32G031F8Px application firmware + build README kicad/ .kicad_sch / .kicad_pcb / .kicad_pro / .kicad_dru
docs/01-architecture-analysis.md+23−32@@ -1,14 +1,10 @@ # Solar MPPT Power System (MCU/IC) — Architecture Analysis -This board directly implements the MCU/IC-based architecture that-`mppt-src/01-architecture-analysis.md` analyzed as the alternative to the-discrete-analog approach actually built for the old board — full IC-by-IC-justification (why LM5175 over a fully-integrated buck-boost, why an MCU-over analog foldback, why INA180 over a bare shunt, why controller vs.-integrated for the power stage) lives in that document and isn't-re-derived here. This doc covers the block diagram as actually built, the-MCU's control architecture, and where the real implementation deviated from-that original candidate proposal.+This doc covers the block diagram as built and the MCU's control+architecture. IC-by-IC justification (why LM5175 over a fully-integrated+buck-boost, why an MCU over analog foldback, why INA180 over a bare shunt,+why a controller vs. an integrated part for the power stage) lives in+`mppt-src/01-architecture-analysis.md` and isn't re-derived here. ## Block diagram (as built) @@ -24,7 +20,7 @@ STAGE 1 -- LM5175 4-switch synchronous buck-boost (U4) + external FETs/inductor + STM32G031F8Px (U7) runs P&O MPPT + CC/CV arbitration, commands ONE analog reference (PWM+RC filtered) into U4's FB summing node v- 12V SLA/AGM battery bus (14.2V CV target, same as the old board)+ 12V SLA/AGM battery bus (14.2V CV target) | +----------------+-----------------+ v v v@@ -47,29 +43,24 @@ accepted ICHG-as-power-proxy substitution for true V×I MPPT tracking (this board's ADC set has no VIN channel), is in `mppt-mcu-firmware/README.md` and `02-detailed-design-calculations.md` Section 4. -This is the practical realization of the old analysis doc's own framing:-*"only one stage should own the MPPT/input-voltage decision"* — here, that-decision-maker is explicit firmware rather than an analog foldback network,-which is exactly the trade being evaluated by building this board at all.+Only one stage owns the MPPT/input-voltage decision — the STM32G031, in+firmware — rather than an analog foldback network. Everything downstream+(both POL bucks) is a simple, well-behaved fixed-output regulator with no+say in the input-side decision. -## Deviations from the original candidate proposal+## Part selection notes -- **TPS62130** was used for the 5V rail instead of the originally-suggested- TPS562201/TPS562208 — same TI family, same 2A class, functionally- equivalent; the specific part number wasn't load-bearing to the original- recommendation ("pick what's in stock" was the explicit framing for this- choice).-- **LM74700** (N-channel ideal-diode controller) was used for reverse-- polarity protection, the "N-channel + charge pump" variant the old doc- named as an alternative to a self-biased P-channel FET.-- **STM32G031F8Px** (TSSOP-20) was the specific MCU chosen from the- "any small Cortex-M0+/M0-class part" recommendation — matches the old- doc's own example (ST STM32G0 series) exactly.+- **TPS62130** for the 5V rail — a TI integrated synchronous buck, 2A class.+- **LM74700** (N-channel ideal-diode controller) for reverse-polarity+ protection, driving an external N-FET.+- **STM32G031F8Px** (TSSOP-20) — small Cortex-M0+ part with a timer/PWM and+ the ADC channels this design needs. -## What this board does NOT change from the old board+## Design targets -Same battery chemistry/target (12V SLA/AGM, 14.2V CV), same panel-assumptions (6-24V, <=30W, worst-case Voc pending the real datasheet), same-output rail requirements (5V/2A, 3.3V/1A), same 4-layer/solid-GND-plane-layout philosophy. The comparison in `05-comparison-vs-old-board.md`-covers what's genuinely different and why.+12V SLA/AGM battery, 14.2V CV setpoint. Panel: 6-24V input range, <=30W,+worst-case Voc pending the real panel datasheet. Output rails: 5V/2A,+3.3V/1A. 4-layer board with a solid GND plane.++For readers comparing against this project's earlier discrete-analog+revision, see `05-comparison-vs-old-board.md`.
docs/02-detailed-design-calculations.md+3−6@@ -1,11 +1,8 @@ # Solar MPPT Power System (MCU/IC) — Detailed Design Calculations -Shares the old board's panel assumptions (single panel, 6-24V operating-range, ≤30W, worst-case Voc ≈30V pending the real panel datasheet — see-`mppt-src/02-detailed-design-calculations.md` for the full derivation of-those figures) and the same 12V SLA/AGM battery target (14.2V CV, confirmed-for apples-to-apples comparison). This doc covers what's specific to the-MCU/IC implementation: the LM5175 buck-boost stage, current-sense scaling,+Design brief: single panel, 6-24V operating range, ≤30W, worst-case Voc+≈30V pending the real panel datasheet, 12V SLA/AGM battery target (14.2V+CV). This doc covers the LM5175 buck-boost stage, current-sense scaling, the FB summing-node network, and the POL buck selection. ## 1. Input current and shunt sizing
docs/04-pcb-layout-review.md+57−71@@ -7,49 +7,74 @@ below) plus cosmetic silkscreen/footprint-metadata warnings. **Routing: 60/60 signal+power nets fully connected, GND carried by plane zones.** 2,587 track segments, 203 vias across F.Cu/In2.Cu/B.Cu. -**Update (2026-09-17), driven by the electrothermal simulation results:**-two rounds of simulation-driven copper fixes have been applied since this-board was first routed — see "Simulation-driven copper fixes" below for the-full writeup, and `simulation/05-electrothermal-simulation.md` for the-complete before/after numbers.- --- -## Why this board looks so different from the old one+## Simulation-driven copper fixes (2026-09-16 / 2026-09-17)++Two real fixes came directly out of running the electrothermal simulation+against this board rather than trusting the net-width policy at face value —+full numbers in `simulation/05-electrothermal-simulation.md`.++1. **Width-classification gap.** The router's "is this a power net"+ heuristic matches keywords against net *names*, but several genuinely+ high-current nets (panel input chain, both LM5175 switch-node segments,+ the raw VBATT node, both POL buck switch/rail segments) had KiCad+ auto-generated names (e.g. `Net-(Q4-D)`) that matched no keyword, so they+ were routed at thin 0.25mm signal width purely because of how they+ happened to be named. Found via the simulation's first run: 431mV drop /+ 172.5mΩ / 1078mW loss on the raw VBATT node. Fixed by widening 503+ segments across 8 nets to 0.6mm — worst case dropped to 307mV/123mΩ.+2. **Routing-length problem on `/VBATT`.** Even at the wider 0.6mm width,+ the RS2 (charge shunt) to J2 (battery connector) segment stayed the+ worst case at 307mV/123mΩ, because the measured resistance implied a+ ~150mm routed path against a 93.8mm straight-line distance — the net's+ multi-drop chain routing visits several other `/VBATT` pads in between+ rather than going direct. Fixed **without touching the existing routing**:+ added one additional 0.6mm direct path between RS2.2 and J2.1 (20 new+ track/via objects), which runs electrically in parallel with the existing+ long path. Result: 307mV/123mΩ -> **74mV/29.6mΩ**, a 76% reduction, and+ no longer the board's worst case.++Both fixes were verified against DRC after applying (0 unconnected items+throughout; total violation count went 354 -> 401 after the first fix, held+at 401 after the second — the parallel stitch's own vias picked up a few+same-net "hole too close" warnings, offset by clearance improvements+elsewhere).++The board-wide worst case is now `vbatt_raw_2p5A` (`Net-(Q4-D)`, the LM5175+boost-leg output before the shunt) at 98mV/39mΩ — a segment neither fix+touched, and itself well down from the pre-fix 431mV baseline.++## Board density -102 components on a 195x135mm board (26,325 mm²) vs. the old board's 45-references on 250x160mm (40,000 mm²) — roughly 34% smaller footprint with-more than double the component count. That's the direct, physical-consequence of trading ~150 generic passives-heavy discrete control-circuitry for a handful of dense, purpose-built ICs (LM5175, 2x INA180,-LM74700, TPS62130, TLV62569, LM5165, STM32G031) — fewer *functional blocks*,-but each one denser and requiring more careful fine-pitch layout discipline-than the old board's comparatively spacious THT-heavy construction.+102 components on a 195x135mm board (26,325 mm²): a handful of dense,+purpose-built ICs (LM5175, 2x INA180, LM74700, TPS62130, TLV62569, LM5165,+STM32G031) rather than many generic passives, which keeps the functional+block count low but makes each block denser and more fine-pitch-sensitive+than a THT-heavy layout would be. -## Layer stack (same reasoning as the old board, same conclusion)+## Layer stack F.Cu (components + signal routing) / **In1.Cu solid GND plane** / In2.Cu (second signal routing layer) / B.Cu (GND plane + a small number of-emergency escape traces). Same rationale as the old board's stack: a real-switching converter (LM5175, plus two more in the POL bucks) and Kelvin-current-sense pairs need a low-impedance plane return directly beneath the-forward trace, not something achievable on 2 layers without giving up-something else needed here.+emergency escape traces). A real switching converter (LM5175, plus two more+in the POL bucks) and Kelvin current-sense pairs need a low-impedance plane+return directly beneath the forward trace — not achievable on 2 layers+without giving up something else needed here. **Note on B.Cu's escape traces:** a handful of the hardest-to-route connections (deep in the LM5175's 0.65mm-pitch pin field, see below) were routed on B.Cu rather than left unrouted. KiCad's zone fill automatically clears plane copper around any differently-netted track on the same layer,-so this is safe, standard practice — but it means B.Cu, like the old board's-reinforcing pour, isn't a pristine trace-free return plane. In1.Cu is.+so this is safe, standard practice — but it means B.Cu isn't a pristine+trace-free return plane. In1.Cu is. ## Placement discipline - **Hand-placed, in order, first:** the LM5175 4-switch buck-boost stage's switching components (Q2-Q5, L2, local decoupling), both POL buck inductors (L3/L4), and the two Kelvin current-sense shunts (RS1 input-side,- RS2 charge-side) with their INA180 amplifiers — the same "place the- current-critical loops by hand, first" discipline as the old board.+ RS2 charge-side) with their INA180 amplifiers. - **Grid-clustered:** everything else (passives, decoupling, the MCU's own support components), by schematic block. - **A genuine placement bug worth recording:** the input-protection block@@ -94,7 +119,7 @@ on future boards (project memory, not duplicated here). ## Known remaining DRC findings -All electrical connections exist (0 unconnected items). The ~350 remaining+All electrical connections exist (0 unconnected items). The 401 remaining findings break down as: - **~230 clearance / shorting_items / hole_clearance**, concentrated almost@@ -111,8 +136,7 @@ findings break down as: tools can resolve local clearance in these fields faster than further automated-router tuning would. - **~90 cosmetic**: silk_overlap/silk_over_copper (reference designator- legibility on densely-packed parts — same category of issue as the old- board's silkscreen warnings) and lib_footprint_mismatch (embedded+ legibility on densely-packed parts) and lib_footprint_mismatch (embedded footprint copies vs. the installed library's current version — bookkeeping, not fabrication-relevant). - A handful of hole_to_hole findings from GND stitching vias placed close@@ -122,54 +146,16 @@ findings break down as: Net width policy: nets matching a "power-ish" name pattern (VBATT, VIN, switch nodes, output rails) route at 0.6mm; everything else at 0.25mm-signal width. This is narrower than the old board's hand-picked 1.0-1.2mm-power traces — a direct consequence of this board's much higher component-density leaving less room per trace.--## Simulation-driven copper fixes (2026-09-16 / 2026-09-17)--Two real fixes came directly out of running the electrothermal simulation-against this board rather than trusting the width policy above at face-value — full numbers in `simulation/05-electrothermal-simulation.md`.--1. **Width-classification gap.** The router's "is this a power net"- heuristic matches keywords against net *names*, but several genuinely- high-current nets (panel input chain, both LM5175 switch-node segments,- the raw VBATT node, both POL buck switch/rail segments) had KiCad- auto-generated names (e.g. `Net-(Q4-D)`) that matched no keyword, so they- were routed at thin 0.25mm signal width purely because of how they- happened to be named. Found via the simulation's first run: 431mV drop /- 172.5mΩ / 1078mW loss on the raw VBATT node. Fixed by widening 503- segments across 8 nets to 0.6mm — worst case dropped to 307mV/123mΩ.-2. **Routing-length problem on `/VBATT`.** Even at the wider 0.6mm width,- the RS2 (charge shunt) to J2 (battery connector) segment stayed the- worst case at 307mV/123mΩ, because the measured resistance implied a- ~150mm routed path against a 93.8mm straight-line distance — the net's- multi-drop chain routing visits several other `/VBATT` pads in between- rather than going direct. Fixed **without touching the existing routing**:- added one additional 0.6mm direct path between RS2.2 and J2.1 (20 new- track/via objects), which runs electrically in parallel with the existing- long path. Result: 307mV/123mΩ -> **74mV/29.6mΩ**, a 76% reduction, and- no longer the board's worst case.--Both fixes were verified against DRC after applying (0 unconnected items-throughout; total violation count went 354 -> 401 after the first fix, held-at 401 after the second — the parallel stitch's own vias picked up a few-same-net "hole too close" warnings, offset by clearance improvements-elsewhere).--The board-wide worst case is now `vbatt_raw_2p5A` (`Net-(Q4-D)`, the LM5175-boost-leg output before the shunt) at 98mV/39mΩ — a segment neither fix-touched, and itself well down from the pre-fix 431mV baseline.+signal width — see "Simulation-driven copper fixes" above for where this+policy fell short and how it was corrected. ## What to do before fabrication 1. Manual clearance/crossing cleanup around U4/U7/U8/U9 in the interactive PCB editor (see above) — the fastest path to a fully DRC-clean board.-2. Confirm the real panel's Voc/temperature coefficient (same open item- carried from the old board's docs — affects input protection component- ratings, not this layout).-3. Silkscreen legibility pass, same as the old board's own recommendation.+2. Confirm the real panel's Voc/temperature coefficient — affects input+ protection component ratings, not this layout.+3. Silkscreen legibility pass. 4. Independently re-derive the R16/R17 VOSNS (LM5175 overvoltage protection) divider against the real datasheet threshold — flagged during firmware bring-up as reusing an since-corrected ratio without its own derivation
docs/hero.png⋯ 1 unchanged line ⋯