shibosoftwaredev/f1c100s-linux-nema17-stepper-controller
A four-layer NEMA 17 motor-controller PCB combining an Allwinner F1C100S Linux computer, USB‑PD/buck power system, W5500 Ethernet, STM32 real-time motion control, DRV8825 stepper driver, protection/temperature/current telemetry, USB interfaces, and local LED/buzzer diagnostics.
- Version
- 0.4.56
- License
- unset
- Stars
- 0
scripts/audit-jlcpcb-via-clearance.py
"""Check drilled vias against foreign copper, separately from native DRC.
JLCPCB specifies 0.2 mm via-hole-to-track clearance and prefers a via pad
0.15 mm larger than its hole. This design keeps the required 0.30/0.45 mm
through-vias; use 0.20 mm from the drill edge to foreign traces and lands.
Source: https://jlcpcb.com/capabilities/pcb-capabilities (Drilling/Traces).
"""
from route_geometry import *
from shapely.strtree import STRtree
c = load_circuit()
root = connectivity(c)
m = json.loads(Path('routing/net-map.json').read_text())
ports = {e['pcb_port_id']: e for e in c if e['type'] == 'pcb_port'}
physical = json.loads(Path('routing/physical-copper.json').read_text())
items = []
for w in physical['wires']:
items.append((w['net'], LineString(w['points']).buffer(w['width']/2, quad_segs=12),
dict(kind='track', layer=w['layer'], width=w['width'], points=w['points'])))
for e in c:
if e['type'] not in ['pcb_smtpad', 'pcb_plated_hole']: continue
p = ports.get(e.get('pcb_port_id'))
net = m['roots'].get(root(p['source_port_id'])) if p else None
items.append((net, geometry(e, 'outer_' if e['type'] == 'pcb_plated_hole' else ''),
dict(kind='land', id=e[e['type']+'_id'])))
tree = STRtree([g for n, g, info in items])
failures = []
for v in physical['vias']:
hole = Point(v['x'], v['y']).buffer(.15, quad_segs=32)
for index in tree.query(hole.buffer(.2)):
net, copper, info = items[int(index)]
if net == v['net']: continue
clearance = hole.distance(copper)
if clearance < .2 - .0002:
failures.append(dict(via=v, otherNet=net, copper=info,
drillEdgeClearance=round(clearance, 6), required=.2))
report = dict(viaHoleDiameter=.3, viaPadDiameter=.45,
source='https://jlcpcb.com/capabilities/pcb-capabilities',
sessionSha256=json.loads(Path('routing/import-report.json').read_text())['session_sha256'],
failures=failures)
Path('reports/jlcpcb-via-clearance.json').write_text(json.dumps(report, indent=2) + '\n')
print(json.dumps(dict(vias=len(physical['vias']), drillClearanceIssues=len(failures))))
for f in failures[:20]: print(json.dumps(f))
if failures: raise SystemExit(1)