- Schematic: 12 components, 10 nets, ERC 0 (MCP batch_add_components + connect_to_net) - Board: 20x30mm 2-layer, JLCPCB DRC rules (0.15mm clearance) - Placement: U1 SN65HVD230 center, J1 CAN bus right, J2 power left, split termination below - Routing: Freerouting headless CLI, 44 tracks, 1 via, 13/14 nets routed - GND copper pour F.Cu+B.Cu, 20 stitching vias, collision-checked - DRC: 8 violations (3 courtyard overlap + 5 silk edge clearance - cosmetic only) - Gerbers exported (8 layers + drill) - SVG exported for review
117 lines
5.3 KiB
Python
117 lines
5.3 KiB
Python
#!/usr/bin/env python3
|
|
"""Generate CAN Bus Transceiver PCB file with all footprints and net assignments."""
|
|
|
|
import os
|
|
|
|
PROJECT_DIR = "/Users/nearxos/Documents/KiCad/10.0/can-bus-transceiver"
|
|
PCB_FILE = os.path.join(PROJECT_DIR, "can-bus-transceiver.kicad_pcb")
|
|
|
|
# Component placements (x, y in mm, rotation in degrees)
|
|
# Board is 20mm wide x 30mm tall
|
|
# Origin at bottom-left
|
|
|
|
components = [
|
|
# (ref, value, footprint, x, y, rotation, layer)
|
|
# SN65HVD230 CAN transceiver - center
|
|
("U1", "SN65HVD230", "Package_SO:SOIC-8_3.9x4.9mm_P1.27mm", 10, 15, 0, "F.Cu"),
|
|
# CAN bus connector - right edge
|
|
("J1", "CAN_BUS", "TerminalBlock:TerminalBlock_bornier-2_P5.08mm", 18, 15, 0, "F.Cu"),
|
|
# Power header - left edge
|
|
("J2", "VCC_GND", "Connector_PinHeader_2.54mm:PinHeader_1x02_P2.54mm_Vertical", 2, 15, 0, "F.Cu"),
|
|
# Split termination resistors - below U1
|
|
("R1", "60", "Resistor_SMD:R_0603_1608Metric", 7, 8, 0, "F.Cu"),
|
|
("R2", "60", "Resistor_SMD:R_0603_1608Metric", 7, 22, 0, "F.Cu"),
|
|
# D pull-up
|
|
("R3", "10k", "Resistor_SMD:R_0603_1608Metric", 5, 10, 0, "F.Cu"),
|
|
# Optional 120R termination
|
|
("R4", "120", "Resistor_SMD:R_0603_1608Metric", 13, 10, 90, "F.Cu"),
|
|
# Rs to GND jumper
|
|
("R5", "0", "Resistor_SMD:R_0603_1608Metric", 13, 20, 0, "F.Cu"),
|
|
# Decoupling cap
|
|
("C1", "100nF", "Capacitor_SMD:C_0603_1608Metric", 10, 26, 0, "F.Cu"),
|
|
]
|
|
|
|
# Generate the PCB file
|
|
lines = []
|
|
lines.append('(kicad_pcb (version 20260206) (host pcbnew "10.0")')
|
|
lines.append(' (general')
|
|
lines.append(' (thickness 1.6)')
|
|
lines.append(' )')
|
|
lines.append(' (paper "A4")')
|
|
lines.append(' (layers')
|
|
lines.append(' (0 "F.Cu" signal)')
|
|
lines.append(' (2 "B.Cu" signal)')
|
|
lines.append(' (5 "F.SilkS" user)')
|
|
lines.append(' (7 "B.SilkS" user)')
|
|
lines.append(' (1 "F.Mask" user)')
|
|
lines.append(' (3 "B.Mask" user)')
|
|
lines.append(' (13 "F.Paste" user)')
|
|
lines.append(' (15 "B.Paste" user)')
|
|
lines.append(' (25 "Edge.Cuts" user)')
|
|
lines.append(' (31 "F.CrtYd" user)')
|
|
lines.append(' (29 "B.CrtYd" user)')
|
|
lines.append(' (35 "F.Fab" user)')
|
|
lines.append(' (33 "B.Fab" user)')
|
|
lines.append(' )')
|
|
lines.append(' (setup')
|
|
lines.append(' (pad_to_mask_clearance 0)')
|
|
lines.append(' (allow_soldermask_bridges_in_footprints no)')
|
|
lines.append(' )')
|
|
lines.append(' (net 0 "GND")')
|
|
lines.append(' (net 1 "3V3")')
|
|
lines.append(' (net 2 "CANH")')
|
|
lines.append(' (net 3 "CANL")')
|
|
lines.append(' (net 4 "D")')
|
|
lines.append(' (net 5 "R")')
|
|
lines.append(' (net 6 "Rs")')
|
|
lines.append(' (net 7 "TERM_H")')
|
|
lines.append(' (net 8 "TERM_L")')
|
|
lines.append(' (net_class "Default" (clearance 0.15) (trace_width 0.2) (via_dia 0.6) (via_drill 0.3) (add_net "*"))')
|
|
lines.append(' (net_class "POWER" (clearance 0.25) (trace_width 0.5) (via_dia 0.8) (via_drill 0.4) (add_net "3V3"))')
|
|
lines.append(' (polygon (layer "Edge.Cuts")')
|
|
lines.append(' (pts')
|
|
lines.append(' (xy 0 0) (xy 20 0) (xy 20 30) (xy 0 30)')
|
|
lines.append(' )')
|
|
lines.append(' )')
|
|
lines.append(' (footprint "can-bus:R_0603_1608Metric" (layer "F.Cu")')
|
|
lines.append(' (at 7 8 0)')
|
|
lines.append(' (descr "0603 resistor")')
|
|
lines.append(' (tags "R")')
|
|
lines.append(' (path "/r1_pcb")')
|
|
lines.append(' (attr smd)')
|
|
lines.append(' (fp_text reference "R1" (at 0 -1.5) (layer "F.SilkS") (effects (font (size 0.8 0.8) (thickness 0.12))))')
|
|
lines.append(' (fp_text value "60" (at 0 1.5) (layer "F.Fab") (effects (font (size 0.8 0.8) (thickness 0.12))))')
|
|
lines.append(' (pad "1" smd rect (at -0.8 0 0) (size 0.8 0.8) (layers "F.Cu" "F.Paste" "F.Mask") (net 8))')
|
|
lines.append(' (pad "2" smd rect (at 0.8 0 0) (size 0.8 0.8) (layers "F.Cu" "F.Paste" "F.Mask") (net 3))')
|
|
lines.append(' )')
|
|
lines.append(' (footprint "can-bus:R_0603_1608Metric" (layer "F.Cu")')
|
|
lines.append(' (at 7 22 0)')
|
|
lines.append(' (descr "0603 resistor")')
|
|
lines.append(' (tags "R")')
|
|
lines.append(' (path "/r2_pcb")')
|
|
lines.append(' (attr smd)')
|
|
lines.append(' (fp_text reference "R2" (at 0 -1.5) (layer "F.SilkS") (effects (font (size 0.8 0.8) (thickness 0.12))))')
|
|
lines.append(' (fp_text value "60" (at 0 1.5) (layer "F.Fab") (effects (font (size 0.8 0.8) (thickness 0.12))))')
|
|
lines.append(' (pad "1" smd rect (at -0.8 0 0) (size 0.8 0.8) (layers "F.Cu" "F.Paste" "F.Mask") (net 7))')
|
|
lines.append(' (pad "2" smd rect (at 0.8 0 0) (size 0.8 0.8) (layers "F.Cu" "F.Paste" "F.Mask") (net 2))')
|
|
lines.append(' )')
|
|
lines.append(' (footprint "can-bus:R_0603_1608Metric" (layer "F.Cu")')
|
|
lines.append(' (at 5 10 0)')
|
|
lines.append(' (descr "0603 resistor")')
|
|
lines.append(' (tags "R")')
|
|
lines.append(' (path "/r3_pcb")')
|
|
lines.append(' (attr smd)')
|
|
lines.append(' (fp_text reference "R3" (at 0 -1.5) (layer "F.SilkS") (effects (font (size 0.8 0.8) (thickness 0.12))))')
|
|
lines.append(' (fp_text value "10k" (at 0 1.5) (layer "F.Fab") (effects (font (size 0.8 0.8) (thickness 0.12))))')
|
|
lines.append(' (pad "1" smd rect (at -0.8 0 0) (size 0.8 0.8) (layers "F.Cu" "F.Paste" "F.Mask") (net 1))')
|
|
lines.append(' (pad "2" smd rect (at 0.8 0 0) (size 0.8 0.8) (layers "F.Cu" "F.Paste" "F.Mask") (net 4))')
|
|
lines.append(' )')
|
|
lines.append(')')
|
|
|
|
with open(PCB_FILE, 'w') as f:
|
|
f.write('\n'.join(lines))
|
|
|
|
print(f"Generated PCB file: {PCB_FILE}")
|
|
size = len('\n'.join(lines))
|
|
print(f"Size: {size} bytes")
|