Add panel-to-PCB mounting system with M3 standoffs
Panel alignment: - PCB offset 10mm from panel top - Component holes aligned: OLED@25mm, jacks@45mm, button@58mm - 4x M3 standoff holes at corners (5,5), (35,5), (5,75), (35,75) Updates: - Panel SVG and spec aligned with PCB layout - Mounting holes added to PCB (Edge.Cuts layer) - Regenerated Gerbers with mounting holes - Updated autoroute.py to add mounting holes automatically DRC: 0 unconnected, 7 cosmetic errors (courtyard overlaps)
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
SN-L00 Command-Line Autoroute Pipeline
|
||||
Run from terminal: python3 scripts/autoroute_cli.py
|
||||
|
||||
Requires: kicad-cli or pcbnew Python module available
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
|
||||
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
KICAD_DIR = os.path.dirname(SCRIPT_DIR)
|
||||
PCB_FILE = os.path.join(KICAD_DIR, "SN-L00.kicad_pcb")
|
||||
DSN_FILE = os.path.join(KICAD_DIR, "SN-L00.dsn")
|
||||
SES_FILE = os.path.join(KICAD_DIR, "SN-L00.ses")
|
||||
FREEROUTING_JAR = "/tmp/freerouting.jar"
|
||||
FREEROUTING_URL = "https://github.com/freerouting/freerouting/releases/download/v2.0.1/freerouting-2.0.1.jar"
|
||||
|
||||
def run(cmd, desc, cwd=None):
|
||||
"""Run command with description"""
|
||||
print(f" {desc}...")
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, cwd=cwd)
|
||||
if result.returncode != 0:
|
||||
print(f" ERROR: {result.stderr}")
|
||||
return False
|
||||
return True
|
||||
|
||||
def main():
|
||||
print("=" * 50)
|
||||
print("SN-L00 Command-Line Autoroute Pipeline")
|
||||
print("=" * 50)
|
||||
|
||||
# Check for kicad-cli
|
||||
kicad_cli = None
|
||||
for path in ["/usr/bin/kicad-cli", "/usr/local/bin/kicad-cli",
|
||||
"/Applications/KiCad/KiCad.app/Contents/MacOS/kicad-cli"]:
|
||||
if os.path.exists(path):
|
||||
kicad_cli = path
|
||||
break
|
||||
|
||||
if not kicad_cli:
|
||||
# Try to find in PATH
|
||||
result = subprocess.run(["which", "kicad-cli"], capture_output=True, text=True)
|
||||
if result.returncode == 0:
|
||||
kicad_cli = result.stdout.strip()
|
||||
|
||||
if not kicad_cli:
|
||||
print("ERROR: kicad-cli not found. Please run in KiCad scripting console instead:")
|
||||
print(" exec(open('scripts/autoroute_full.py').read())")
|
||||
sys.exit(1)
|
||||
|
||||
print(f"Using: {kicad_cli}")
|
||||
|
||||
# Step 1: Run placement script in KiCad
|
||||
print("\n[1/4] Placing components...")
|
||||
# kicad-cli pcb export dsn also runs any embedded scripts, but we need
|
||||
# to place first. For now, assume placement was done or use Python API
|
||||
print(" (Run place_8hp.py in KiCad first, or components should already be placed)")
|
||||
|
||||
# Step 2: Export DSN
|
||||
print("\n[2/4] Exporting DSN...")
|
||||
if not run([kicad_cli, "pcb", "export", "dsn", "-o", DSN_FILE, PCB_FILE],
|
||||
"Exporting Specctra DSN"):
|
||||
sys.exit(1)
|
||||
print(f" Created: {DSN_FILE}")
|
||||
|
||||
# Step 3: Download Freerouting if needed
|
||||
print("\n[3/4] Running Freerouting...")
|
||||
if not os.path.exists(FREEROUTING_JAR):
|
||||
print(" Downloading Freerouting...")
|
||||
if not run(["curl", "-L", "-o", FREEROUTING_JAR, FREEROUTING_URL],
|
||||
"Downloading"):
|
||||
sys.exit(1)
|
||||
|
||||
# Run Freerouting
|
||||
result = subprocess.run(
|
||||
["java", "-jar", FREEROUTING_JAR,
|
||||
"-de", DSN_FILE,
|
||||
"-do", SES_FILE,
|
||||
"-mp", "200",
|
||||
"-mt", "1",
|
||||
"-oit"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
cwd=KICAD_DIR
|
||||
)
|
||||
|
||||
if result.returncode != 0:
|
||||
print(f" Freerouting error: {result.stderr}")
|
||||
sys.exit(1)
|
||||
|
||||
# Parse output for timing
|
||||
for line in result.stdout.split('\n') + result.stderr.split('\n'):
|
||||
if 'completed' in line.lower():
|
||||
print(f" {line.split(']')[-1].strip()}")
|
||||
|
||||
print(f" Created: {SES_FILE}")
|
||||
|
||||
# Step 4: Import SES
|
||||
print("\n[4/4] Importing routed session...")
|
||||
if not run([kicad_cli, "pcb", "import", "ses", "-i", SES_FILE, PCB_FILE],
|
||||
"Importing Specctra session"):
|
||||
# kicad-cli might not support import, manual step needed
|
||||
print(" NOTE: Import via kicad-cli may not be supported.")
|
||||
print(" In KiCad: File → Import → Specctra Session")
|
||||
else:
|
||||
print(f" Imported routes into: {PCB_FILE}")
|
||||
|
||||
print("\n" + "=" * 50)
|
||||
print("DONE! Open PCB in KiCad and run DRC to verify.")
|
||||
print("=" * 50)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user