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.
main
#!/usr/bin/env python3
"""Remove same-net vias drilled on top of each other.
Vias are placed by several passes that do not see each other's output --
routing, stitching, thermal-pad filling, pour stitching, hand-routing -- and
two of them can land within a drill diameter on the same net. Electrically
that is harmless, which is why it survives every net-based check; mechanically
it is two overlapping holes, which a fab will either query or break a drill
on. KiCad reports it as hole_to_hole, actual 0.0000mm.
"""
import math, re, sys
PCB = ("/mnt/c/Users/kirkt/Documents/mppt-power-system-mcu/"
"mppt-power-system-mcu.kicad_pcb")
MIN_SEP = 0.30 # mm between drill centres, comfortably over the rule
def main(path=PCB):
text = open(path, errors="replace").read()
pat = re.compile(r'\t\(via\n(?:[^\n]*\n)*?\t\)\n')
keep, dropped = [], 0
seen = []
out = []
pos = 0
for m in pat.finditer(text):
blk = m.group(0)
at = re.search(r'\(at ([-\d.]+) ([-\d.]+)\)', blk)
net = re.search(r'\(net (?:\d+ )?"?([^")\n]*)"?\)', blk)
if not at:
continue
x, y = float(at.group(1)), float(at.group(2))
n = net.group(1) if net else ""
dup = any(nn == n and math.hypot(x - sx, y - sy) < MIN_SEP
for sx, sy, nn in seen)
if dup:
out.append(text[pos:m.start()])
pos = m.end()
dropped += 1
else:
seen.append((x, y, n))
out.append(text[pos:])
if dropped:
with open(path, "w") as fh:
fh.write("".join(out))
print(f"removed {dropped} duplicate via(s) ({len(seen)} kept)")
return 0
if __name__ == "__main__":
sys.exit(main())