#!/usr/bin/env python3
"""Week 5 design checks for the body board. Run before trusting the layout."""
import math

V33, RPULL = 3.3, 10_000.0
VARIANTS = {"no leg": None, "short shin": 22_000.0, "default": 10_000.0, "long shin": 4_700.0}

print("ID sense: 3.3 V through a 10k pull-up, leg resistor to GND\n")
print(f"{'variant':12} {'R_leg':>8} {'V_id':>7} {'ADC':>6}")
vs = []
for name, r in VARIANTS.items():
    v = V33 if r is None else V33 * r / (r + RPULL)
    vs.append((name, v)); print(f"{name:12} {'open' if r is None else f'{r/1000:.1f}k':>8} {v:7.3f} {int(v/V33*4095):6d}")
vs.sort(key=lambda t: t[1])
gaps = [(vs[i+1][1]-vs[i][1]) for i in range(len(vs)-1)]
print(f"\nsmallest gap between bands: {min(gaps):.3f} V = {min(gaps)/V33*100:.0f}% of full scale")
print("rule: >10% of full scale.", "PASS" if min(gaps)/V33 > 0.10 else "FAIL")

# worst case with 1% resistors: band edges move
def band(r, tol=0.01, rp_tol=0.01):
    if r is None: return (V33, V33)
    lo = V33*(r*(1-tol))/(r*(1-tol)+RPULL*(1+rp_tol))
    hi = V33*(r*(1+tol))/(r*(1+tol)+RPULL*(1-rp_tol))
    return (lo, hi)
print("\nwith 1% resistors:")
edges = sorted([(band(r), n) for n, r in VARIANTS.items()])
worst = min((edges[i+1][0][0]-edges[i][0][1]) for i in range(len(edges)-1))
for (lo, hi), n in edges: print(f"  {n:12} {lo:.3f} .. {hi:.3f} V")
print(f"  worst margin between adjacent bands: {worst*1000:.0f} mV", "PASS" if worst > 0.1 else "FAIL")

# trace current, IPC-2221 external layer: I = k dT^0.44 A^0.725, k=0.048, A in mil^2
def width_mm_for(I, dT=20.0, oz=1.0):
    A = (I/(0.048*dT**0.44))**(1/0.725)          # mil^2
    return A/(1.378*oz)*0.0254                    # mil -> mm
print("\ntrace width needed (1 oz copper, 20 C rise, IPC-2221 external):")
for I, what in [(0.5,"logic 5V"),(1.8,"one port, 3 servos walking"),(5.4,"three ports walking"),(11.0,"six ports walking")]:
    print(f"  {I:5.1f} A  {width_mm_for(I):6.2f} mm   {what}")
print("\n=> per-port 12V stub at 2.0 mm is good for ~2 A. The main 12V and GND rails")
print("   are drawn 6 mm wide (~5 A) and get a soldered 18 AWG wire on top for the rest.")
