main
Rithesh03 Update 3: PCB design completed - routed board, manufacturing package (prototype, do not order yet), WLED guide, final checklist, Hydrogen feedback 1ed072d 13d ago
"""Draw the LED pad comparison diagram (hardware/layout-review/led-pad-comparison.svg).

All numbers come from the two LED datasheets (see check_footprints.py)."""
import os

HW = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
S = 70          # px per mm
OX, OY = 330, 300


def X(v):
    return OX + v * S


def Y(v):
    return OY + v * S


def rect(x0, x1, y0, y1, style):
    out = []
    for sx in (-1, 1):
        for sy in (-1, 1):
            a, b = sorted((sx * x0, sx * x1))
            c, d = sorted((sy * y0, sy * y1))
            out.append(f'<rect x="{X(a):.1f}" y="{Y(c):.1f}" width="{(b - a) * S:.1f}" '
                       f'height="{(d - c) * S:.1f}" {style}/>')
    return "\n".join(out)


svg = [f'<svg xmlns="http://www.w3.org/2000/svg" width="1260" height="620" font-family="DejaVu Sans" font-size="16">',
       '<rect width="1260" height="620" fill="white"/>',
       '<text x="20" y="32" font-size="22" font-weight="bold">LED footprint: XL pads with both LED options on top (top view, mm)</text>',
       rect(1.55, 2.85, 0.9, 2.2, 'fill="#c9a0a0" stroke="none"'),                               # XL pads
       rect(1.7, 3.2, 1.2, 2.1, 'fill="none" stroke="#2a9d2a" stroke-width="3" stroke-dasharray="10,6"'),  # WS rec pad
       rect(1.7, 2.7, 1.1, 2.1, 'fill="none" stroke="#1f5fd1" stroke-width="3"'),                 # XL terminal
       rect(1.8, 2.7, 1.2, 2.1, 'fill="none" stroke="#e07b00" stroke-width="3" stroke-dasharray="4,4"'),   # WS terminal
       f'<rect x="{X(-2.5)}" y="{Y(-2.5)}" width="{5 * S}" height="{5 * S}" fill="none" stroke="#888" stroke-width="1.5"/>',
       f'<rect x="{X(-2.5)}" y="{Y(-2.7)}" width="{5 * S}" height="{5.4 * S}" fill="none" stroke="#e07b00" stroke-width="1" stroke-dasharray="3,5"/>',
       f'<line x1="{X(-3.4)}" y1="{Y(0)}" x2="{X(3.4)}" y2="{Y(0)}" stroke="#ccc"/>',
       f'<line x1="{X(0)}" y1="{Y(-3)}" x2="{X(0)}" y2="{Y(3)}" stroke="#ccc"/>',
       f'<text x="{X(-3.3)}" y="{Y(-1.55) + 6}">1</text><text x="{X(-3.3)}" y="{Y(1.55) + 6}">2</text>',
       f'<text x="{X(3.05)}" y="{Y(1.55) + 6}">3</text><text x="{X(3.05)}" y="{Y(-1.55) + 6}">4</text>']
lx, ly = 650, 80
legend = [("#c9a0a0", "fill", "Our pads (XL datasheet): 1.3 x 1.3 mm"),
          ("#1f5fd1", "solid", "XL-5050RGBC-2812B metal terminals (1.0 x 1.0)"),
          ("#e07b00", "dots", "WS2812B-B/T metal terminals (0.9 x 0.9)"),
          ("#2a9d2a", "dash", "WS2812B's own recommended pads (1.5 x 0.9)")]
for i, (col, kind, text) in enumerate(legend):
    y = ly + i * 34
    if kind == "fill":
        svg.append(f'<rect x="{lx}" y="{y - 14}" width="30" height="18" fill="{col}"/>')
    else:
        dash = {"solid": "", "dots": 'stroke-dasharray="4,4"', "dash": 'stroke-dasharray="10,6"'}[kind]
        svg.append(f'<rect x="{lx}" y="{y - 14}" width="30" height="18" fill="none" stroke="{col}" stroke-width="3" {dash}/>')
    svg.append(f'<text x="{lx + 42}" y="{y}">{text}</text>')
notes = ["Both parts' terminals land fully on our pads.",
         "Pad reaches past the terminal's outer end (toe):",
         "\u00a0\u00a0\u00a0XL: +0.15 mm (as XL recommends)",
         "\u00a0\u00a0\u00a0WS2812B: +0.15 mm, but WS2812B recommends +0.50 mm",
         "WS2812B on these pads = smaller solder fillet than its",
         "maker intends, and JLCPCB treats a part/footprint",
         "mismatch as 'not populated'.",
         "Result: footprint is for the XL LED only.",
         "Switching to WS2812B needs its own footprint (board change)."]
for i, t in enumerate(notes):
    svg.append(f'<text x="{lx}" y="{ly + 170 + i * 26}" font-size="15"'
               f'{" font-weight=\"bold\"" if i >= 7 else ""}>{t}</text>')
svg.append(f'<text x="{X(-2.5)}" y="{Y(3.25)}" font-size="13" fill="#666">grey = XL body 5.0 x 5.0; orange dotted = WS2812B body 5.0 x 5.4</text>')
svg.append("</svg>")
out = os.path.join(HW, "layout-review", "led-pad-comparison.svg")
open(out, "w").write("\n".join(svg))
print("wrote", out)