Fix PCB file format and add placement script
- Fixed KiCad 8 PCB file format (text rotation syntax) - PCB now loads correctly with board outline and labels - Added Python placement script for KiCad scripting console - Updated PCB_LAYOUT.md with quick start instructions Next step: Open in KiCad, run Update PCB from Schematic, then use Freerouting or manual routing to complete traces.
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
KiCad PCB Component Placement Script for SN-L00
|
||||
|
||||
Run this script in KiCad's Scripting Console (Tools > Scripting Console)
|
||||
after running "Update PCB from Schematic" to place all components.
|
||||
|
||||
Usage in KiCad scripting console:
|
||||
exec(open('/path/to/place_components.py').read())
|
||||
"""
|
||||
|
||||
import pcbnew
|
||||
|
||||
# Component placement coordinates (mm) based on CPL_PCBWay.csv
|
||||
# Format: {Reference: (x, y, rotation, layer)}
|
||||
# Layer: "F.Cu" for top, "B.Cu" for bottom
|
||||
|
||||
PLACEMENTS = {
|
||||
# Capacitors
|
||||
"C1": (10.0, 60.0, 0, "F.Cu"),
|
||||
"C2": (18.0, 60.0, 0, "F.Cu"),
|
||||
"C3": (21.0, 60.0, 0, "F.Cu"),
|
||||
"C4": (7.0, 68.0, 0, "F.Cu"),
|
||||
"C5": (21.0, 68.0, 0, "F.Cu"),
|
||||
|
||||
# Resistors
|
||||
"R1": (10.0, 35.0, 0, "F.Cu"),
|
||||
"R2": (24.0, 36.0, 90, "F.Cu"),
|
||||
"R3": (7.0, 76.0, 90, "F.Cu"),
|
||||
"R4": (21.0, 76.0, 90, "F.Cu"),
|
||||
"R5": (18.0, 76.0, 90, "F.Cu"),
|
||||
"R6": (18.0, 72.0, 90, "F.Cu"),
|
||||
|
||||
# Diodes
|
||||
"D1": (7.0, 65.0, 0, "B.Cu"), # Bottom layer
|
||||
"D2": (24.0, 31.5, 90, "F.Cu"),
|
||||
"D3": (24.0, 70.0, 90, "F.Cu"),
|
||||
"D4": (24.0, 74.0, 90, "F.Cu"),
|
||||
|
||||
# ICs
|
||||
"U1": (14.0, 65.0, 0, "B.Cu"), # LDO on bottom
|
||||
"U2": (7.0, 72.0, 0, "F.Cu"), # Schmitt trigger
|
||||
"U3": (21.0, 72.0, 0, "F.Cu"), # Op-amp
|
||||
|
||||
# Connectors
|
||||
"J1": (14.0, 92.0, 0, "F.Cu"), # Power header
|
||||
"J2": (7.0, 83.0, 0, "F.Cu"), # TRIG jack
|
||||
"J3": (21.0, 83.0, 0, "F.Cu"), # RETURN jack
|
||||
|
||||
# Switch
|
||||
"SW1": (14.0, 31.5, 0, "F.Cu"),
|
||||
|
||||
# Modules (hand-solder, placement reference only)
|
||||
"MOD1": (14.0, 46.5, 0, "F.Cu"), # RP2040-Zero
|
||||
"MOD2": (14.0, 17.5, 0, "F.Cu"), # OLED
|
||||
}
|
||||
|
||||
def place_components():
|
||||
"""Place all components according to the PLACEMENTS dictionary."""
|
||||
board = pcbnew.GetBoard()
|
||||
|
||||
if not board:
|
||||
print("Error: No board loaded!")
|
||||
return
|
||||
|
||||
placed = 0
|
||||
not_found = []
|
||||
|
||||
for ref, (x, y, rotation, layer) in PLACEMENTS.items():
|
||||
# Find the footprint by reference
|
||||
fp = board.FindFootprintByReference(ref)
|
||||
|
||||
if fp is None:
|
||||
not_found.append(ref)
|
||||
continue
|
||||
|
||||
# Convert mm to internal units (nanometers)
|
||||
pos = pcbnew.VECTOR2I(pcbnew.FromMM(x), pcbnew.FromMM(y))
|
||||
fp.SetPosition(pos)
|
||||
|
||||
# Set rotation (in tenths of degrees)
|
||||
fp.SetOrientationDegrees(rotation)
|
||||
|
||||
# Set layer (flip if on bottom)
|
||||
if layer == "B.Cu" and fp.GetLayer() == pcbnew.F_Cu:
|
||||
fp.Flip(pos, False)
|
||||
elif layer == "F.Cu" and fp.GetLayer() == pcbnew.B_Cu:
|
||||
fp.Flip(pos, False)
|
||||
|
||||
placed += 1
|
||||
print(f"Placed {ref} at ({x}, {y}) rot={rotation}° on {layer}")
|
||||
|
||||
if not_found:
|
||||
print(f"\nNot found (run 'Update PCB from Schematic' first): {not_found}")
|
||||
|
||||
print(f"\nPlaced {placed}/{len(PLACEMENTS)} components")
|
||||
|
||||
# Refresh the board view
|
||||
pcbnew.Refresh()
|
||||
|
||||
|
||||
def add_mounting_holes():
|
||||
"""Add M3 mounting holes at standard Eurorack positions."""
|
||||
board = pcbnew.GetBoard()
|
||||
|
||||
# Check if mounting holes already exist
|
||||
for fp in board.GetFootprints():
|
||||
if "MountingHole" in fp.GetValue():
|
||||
print("Mounting holes already exist, skipping...")
|
||||
return
|
||||
|
||||
# Would need to load footprint from library - simplified for this script
|
||||
print("Add mounting holes manually:")
|
||||
print(" MH1: (14, 5) - Top")
|
||||
print(" MH2: (14, 95) - Bottom")
|
||||
print(" Footprint: MountingHole:MountingHole_3.2mm_M3")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("SN-L00 Component Placement Script")
|
||||
print("=" * 40)
|
||||
place_components()
|
||||
add_mounting_holes()
|
||||
print("\nDone! Run DRC and then route traces.")
|
||||
Reference in New Issue
Block a user