Files
can-bus-transceiver/build_can_pcb.py
nearxos 43648b1ffe L2.3 CAN Bus Transceiver: complete PCB layout
- 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
2026-06-22 21:54:07 +03:00

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")