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
README.md+65−8@@ -7,11 +7,15 @@ steers the converter through a single analog control input. Charges a 12 V SLA/A battery to a 14.2 V absorption setpoint across the panel's full 6–24 V range. Four-layer KiCad board, 189 × 129 mm. The schematic and the PCB are both emitted by-Python — no part of either was drawn by hand. The copper has been through five-revisions, each one driven by what an electrothermal model and a first-build audit-measured on the revision before it, both run against the board file itself. As of-revision 5 the board is **electrically complete**: every net connected, every net one-continuous piece of copper, zero different-net clearance defects.+Python — no part of either was drawn by hand. The copper went through five revisions,+each one driven by what an electrothermal model and a first-build audit measured on the+revision before it, both run against the board file itself.++**Revision 5 is the final hardware revision.** The board is electrically complete —+every net connected, every net one continuous piece of copper, zero different-net+clearance defects — and the three remaining avenues for improving it were each measured+and found closed. [Why there is no revision 6](#why-there-is-no-revision-6) records what+they were. --- @@ -258,7 +262,7 @@ of being skipped. **What that bought, and what it cost.** The same model, run on the board at each revision: -| Measurement | Rev 1 | Rev 2 | Rev 3 | Rev 4 | Rev 5 (current) |+| Measurement | Rev 1 | Rev 2 | Rev 3 | Rev 4 | Rev 5 (final) | |---|---:|---:|---:|---:|---:| | Panel input path resistance | 11.578 mΩ | 5.454 mΩ | 3.866 mΩ | 3.866 mΩ | **3.866 mΩ** | | Panel input current density (p99) | 122.55 A/mm² | 55.24 A/mm² | 40.50 A/mm² | 40.50 A/mm² | **40.50 A/mm²** |@@ -315,6 +319,52 @@ left sits in short runs right at pads, where the pad's own width sets the limit amount of widening in open board helps. Reducing it further is a placement and package problem, not a trace-width one. +### Why there is no revision 6++Revision 5's measurements were worked for a revision 6 and did not yield one. Three+avenues were examined; all three are closed, and the reasons are worth recording, because+they are what distinguishes a design at its limit from one merely at a stopping point.++**The two worst resistances cannot be improved with more copper.** The battery-bus feed+to the 5 V POL (60.2 mΩ) and the raw VBATT path (31.1 mΩ) are both dominated by *length*+rather than width, and the established fix for that on this board is a direct parallel+run between the case's own terminal pads — the technique that took the charge path from+92 mΩ to 8.6 mΩ in revisions 2 and 3. Both candidates were retried against revision 5's+geometry. `RS2.2 → U8.10` and `RS2.2 → U9.3` find no legal path on any of the three+routing layers plus the escape layer, at every width from 1.2 mm down to 0.4 mm. They are+**blocked, not short of search space**, and that distinction was tested rather than+assumed: the router's search window is the endpoints' bounding box expanded by the+margin, so at the 60 mm margin used here — with endpoints 84 mm and 66 mm apart — the+window already covers essentially the whole board.++**Every current-carrying net is already at its full width target.** Re-measured against+the final geometry, `widen.py` reports `/VBATT` and `Net-(Q4-D)` at 1.60 mm and+`Net-(Q2-S)` and `/PANEL_PROT` at 2.00 mm — their targets — everywhere the surrounding+copper permits. The pass is at a fixed point. There is no segment left that geometry+would allow to grow, so raising the targets would change nothing except the margin+against neighbouring copper.++**The peak current density is a package limit, not a layout one.** The 67.0 A/mm² on the+buck-side switch node sits in short segments right at the pads, where `Net-(Q2-S)` runs+1.60 mm against its 2.00 mm target because the pad itself is narrower than the trace+wants to be. Widening in open board does not touch it. Moving that number means moving Q2+or changing its footprint — reopening the fanout and courtyard work of revision 4 to buy+a figure already down from 122.6 A/mm² at revision 1.++What remains on the table is precisely what revision 4 traded away on purpose: revision+3's copper was better on six of ten resistance cases, and recovering it means putting the+bypass capacitors and POL inductors back where they were — 62 mm and 14 mm from the pins+they serve. On a board whose remaining purpose is to work the first time it is built,+that is not a trade worth reopening.++### Reproducibility++The electrothermal run was executed twice against the same board file, in separate+processes. Both runs recorded the same board SHA-256, solved all fourteen cases, and+agreed to **zero relative difference** on every resistance, voltage drop, copper loss and+current-density figure, with the thermal solution identical to six decimal places. The+numbers on this page are a property of the board file, not of a particular run.+ ## Key design values | Parameter | Value | Basis |@@ -395,7 +445,7 @@ simulate — against the previous revision's measurements. | **Rev 2** | Correctness over completeness | 0 shorts, 0 clearance violations, 0 mechanical findings; connectivity traded down to 13 unconnected items. Peak current density halved. Silkscreen and pad-orientation work brought cosmetic findings from 86 to 14 and fixed 21 physically mis-oriented pads on the power FETs and diodes | | **Rev 3** | Copper, measured | Same verification results, unconnected items down to 4, every resistance case improved — several by more than half. 2,785 segments widened, six parallel paths added | | **Rev 4** | First-build survival | An audit of what DRC does not check found four real defects and fixed them: bypass capacitors up to 62.5 mm from their pin, 96 vias below the fab's annular-ring minimum, exposed ground pads with no vias, and both POL inductors 14 mm from their switch node. Cost some of rev 3's copper margin to do it |-| **Rev 5** *(current)* | Electrically complete | The three links the autorouter never closed were a resolution problem, not a congestion one, so they were routed on a 0.025 mm raster instead — all three closed, nothing else moved. Reading KiCad's actual fill polygons then found the fourth unconnected item was a switching regulator's ground pin stranded in an unfillable sliver of pour. **0 unconnected items, 0 split nets, 0 audit problems**, and every simulation case solves |+| **Rev 5** *(final)* | Electrically complete | The three links the autorouter never closed were a resolution problem, not a congestion one, so they were routed on a 0.025 mm raster instead — all three closed, nothing else moved. Reading KiCad's actual fill polygons then found the fourth unconnected item was a switching regulator's ground pin stranded in an unfillable sliver of pour. **0 unconnected items, 0 split nets, 0 audit problems**, and every simulation case solves | The audit that opened rev 1 is why `check_board.py` exists: it runs DRC and classifies every finding as electrical, mechanical or cosmetic with the different-net test made@@ -404,7 +454,9 @@ filed as a harmless warning. ## Known limitations -Not built, not bench-tested.+Not built, not bench-tested. This is the final hardware revision, so these are the items+the first build should be prepared for rather than a list of things pending another+layout pass. - **Nothing is left unrouted.** As of revision 5 there are no links to close by hand before fabrication; the three that previously needed it are routed and verified.@@ -420,6 +472,11 @@ Not built, not bench-tested. - **The three hand-routed links run at 0.15–0.25 mm**, the board minimum. They carry small-signal currents, so that is electrically fine, but they are the narrowest copper on the board and worth a look under magnification on the first article.+- **Revision 3's copper was better on six of ten resistance cases**, and that gap is+ permanent — revision 4 spent it on bypass-capacitor and inductor placement, and+ [the analysis above](#why-there-is-no-revision-6) shows it cannot be won back without+ undoing that. The largest single consequence is 54 mV of drop on the 0.9 A feed to the+ 5 V POL, which is a performance number on a rail with ample headroom. - 11 cosmetic findings remain: 7 silkscreen overlaps in the densest clusters and 4 footprint-library metadata mismatches. Nothing on silkscreen sits over a pad.
page.json+2−2@@ -32,8 +32,8 @@ "electrothermal-simulation" ], "slug": "mppt-power-system",- "version": "7.0.0",- "description": "A 30 W solar battery charger with regulated 5 V / 3.3 V rails. STM32G031 MCU runs P&O MPPT plus a CC/CV charge state machine and drives a TI LM5175 4-switch synchronous buck-boost via its FB pin; two INA180 shunt amplifiers close the current loops and an LM74700 provides active reverse-polarity protection. Charges a 12 V SLA/AGM battery to 14.2 V across the panel's full 6-24 V range. 189 x 129 mm 4-layer board, 5,752 track segments, generated entirely from Python. Five revisions driven by an electrothermal model and a first-build audit run against the published board file. Electrically complete as of revision 5: 0 unconnected items, 0 shorts, 0 clearance violations, 0 mechanical DRC findings, every net one continuous piece of copper, fab-capable drills and annular rings, every IC bypassed within 10 mm, and all fourteen simulation cases solve.",+ "version": "7.1.0",+ "description": "A 30 W solar battery charger with regulated 5 V / 3.3 V rails. STM32G031 MCU runs P&O MPPT plus a CC/CV charge state machine and drives a TI LM5175 4-switch synchronous buck-boost via its FB pin; two INA180 shunt amplifiers close the current loops and an LM74700 provides active reverse-polarity protection. Charges a 12 V SLA/AGM battery to 14.2 V across the panel's full 6-24 V range. 189 x 129 mm 4-layer board, 5,752 track segments, generated entirely from Python. Five revisions driven by an electrothermal model and a first-build audit run against the published board file, and revision 5 is final: 0 unconnected items, 0 shorts, 0 clearance violations, 0 mechanical DRC findings, every net one continuous piece of copper, fab-capable drills and annular rings, every IC bypassed within 10 mm, all fourteen simulation cases solving, and the three remaining routes to a better board each measured and found closed.", "dependencies": {}, "author": { "name": "TylerK",