Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to open KiCad footprints and libraries #9

Open
ghost opened this issue Apr 23, 2024 · 3 comments
Open

Unable to open KiCad footprints and libraries #9

ghost opened this issue Apr 23, 2024 · 3 comments

Comments

@ghost
Copy link

ghost commented Apr 23, 2024

I cannot complete any of the examples, except for the ones that do not include any parts:

l_code$ python esp32_motor-pcb-x3_final.py
Circuit:  Parts: 17  Nets: 36
Traceback (most recent call last):
  File "/home/twinlizzie/Ngnuity-Repos/sylvie-2024/schematics/skidl_code/esp32_motor-pcb-x3_final.py", line 270, in <module>
    sp = SkiPart(brd.DC(part.loc), part, side=side)
  File "/home/twinlizzie/miniconda3/lib/python3.10/site-packages/pcbflow/kicad.py", line 286, in __init__
    lfn = self._find_footprint_file(skipart.footprint)
  File "/home/twinlizzie/miniconda3/lib/python3.10/site-packages/pcbflow/kicad.py", line 316, in _find_footprint_file
    raise FileNotFoundError("Unable to find KiCAD footprints directory")
FileNotFoundError: Unable to find KiCAD footprints directory

Not sure how to set the footprint directory. I've tried modifying kicad.py itself, with a little bit of luck, though it only leads to more errors.

Code:

import os
import sys
import math
import glob
import shapely.geometry as sg

from pcbflow import *
from skidl import *

# Set the default tool to KiCad 7 for footprint management.
set_default_tool(KICAD7)

if __name__ == "__main__":
    ###
    ### SKiDL Circuit Declarations
    ###

	# Create ESP32 and TMC5160 headers with updated part names
	esp32_header1 = Part("Connector_Generic", "Conn_01x15", footprint="PinSocket_1x15_P2.54mm_Vertical")
	esp32_header2 = Part("Connector_Generic", "Conn_01x15", footprint="PinSocket_1x15_P2.54mm_Vertical")
	
	tmc5160_header1 = Part("Connector_Generic", "Conn_01x08", footprint="PinSocket_1x08_P2.54mm_Vertical")
	tmc5160_header2 = Part("Connector_Generic", "Conn_01x08", footprint="PinSocket_1x08_P2.54mm_Vertical")
	
	tmc5160_header1b = Part("Connector_Generic", "Conn_01x08", footprint="PinSocket_1x08_P2.54mm_Vertical")
	tmc5160_header2b = Part("Connector_Generic", "Conn_01x08", footprint="PinSocket_1x08_P2.54mm_Vertical")
	
	tmc5160_header1c = Part("Connector_Generic", "Conn_01x08", footprint="PinSocket_1x08_P2.54mm_Vertical")
	tmc5160_header2c = Part("Connector_Generic", "Conn_01x08", footprint="PinSocket_1x08_P2.54mm_Vertical")
	
	# Create 1x4 connector for stepper motor connections
	stepper_motor_header = Part("Connector_Generic", "Conn_01x04", footprint="PinHeader_1x04_P2.54mm_Vertical")
	stepper_motor_header_b = Part("Connector_Generic", "Conn_01x04", footprint="PinHeader_1x04_P2.54mm_Vertical")
	stepper_motor_header_c = Part("Connector_Generic", "Conn_01x04", footprint="PinHeader_1x04_P2.54mm_Vertical")
	
	# Create 1x4 connector for CAN Bus connections
	can_bus_header = Part("Connector_Generic", "Conn_01x04", footprint="PinHeader_1x04_P2.54mm_Vertical")
	
	# Create 100uF 63V capacitor with correct footprint
	capacitor = Part("Device", "C", value="100uF", voltage="63V", footprint="Capacitor_THT:CP_Radial_D10.0mm_P5.00mm")
	capacitor_b = Part("Device", "C", value="100uF", voltage="63V", footprint="Capacitor_THT:CP_Radial_D10.0mm_P5.00mm")
	capacitor_c = Part("Device", "C", value="100uF", voltage="63V", footprint="Capacitor_THT:CP_Radial_D10.0mm_P5.00mm")
	
	# Create a 3-pin terminal block for 36V connections
	terminal_block = Part("Connector_Generic", "Conn_01x03", footprint="TerminalBlock_Phoenix_PT-1,5-2-5.0-H_1x02_P5.00mm_Horizontal")
	
	# Create through-hole solder pads for 36V+ and 36V_GND connections with 2.54mm spacing
	terminal_block_2 = Part("Connector_Generic", "Conn_01x02", footprint="TerminalBlock_Phoenix_MPT-0,5-2-2.54_1x02_P2.54mm_Horizontal")
	
	# Create 36V_V+ and 36V_GND nets.
	V_plus_36V = Net("36V_V+")
	GND_36V = Net("36V_GND")
	
	# Define the GPIO pins according to ESP32 30pin version.
	esp32_vin = esp32_header1[1]
	esp32_gnd1 = esp32_header1[2]
	esp32_3v3 = esp32_header2[1]
	esp32_gnd2 = esp32_header2[2]
	esp32_gpio2 = esp32_header2[4]
	esp32_gpio4 = esp32_header2[5]
	esp32_gpio5 = esp32_header2[8]
	esp32_gpio12 = esp32_header1[4]
	esp32_gpio13 = esp32_header1[3]
	esp32_gpio14 = esp32_header1[5]
	esp32_gpio15 = esp32_header2[3]
	esp32_gpio16 = esp32_header2[6]
	esp32_gpio17 = esp32_header2[7]
	esp32_gpio18 = esp32_header2[9]
	esp32_gpio19 = esp32_header2[10]
	esp32_gpio21 = esp32_header2[11]
	esp32_gpio22 = esp32_header2[14]
	esp32_gpio23 = esp32_header2[15]
	esp32_gpio25 = esp32_header1[8]
	esp32_gpio26 = esp32_header1[7]
	esp32_gpio27 = esp32_header1[6]
	esp32_gpio32 = esp32_header1[10]
	esp32_gpio33 = esp32_header1[9]
	
	# Define the pins for TMC5160
	tmc5160_pins = {
	    'gnd2': tmc5160_header1[8], 
	    '3v3': tmc5160_header1[7],
	    'm2b': tmc5160_header1[6],
	    'm1b': tmc5160_header1[5],
	    'm1a': tmc5160_header1[4],
	    'm2a': tmc5160_header1[3],
	    'gnd1': tmc5160_header1[2],
	    'vmot': tmc5160_header1[1],
	    'en': tmc5160_header2[1],
	    'sdi': tmc5160_header2[2],
	    'sck': tmc5160_header2[3],
	    'csn': tmc5160_header2[4],
	    'sdo': tmc5160_header2[5],
	    'step': tmc5160_header2[7],
	    'dir': tmc5160_header2[8]
	}
	
	# Define the pins for TMC5160b
	tmc5160b_pins = {
	    'gnd2': tmc5160_header1b[8], 
	    '3v3': tmc5160_header1b[7],
	    'm2b': tmc5160_header1b[6],
	    'm1b': tmc5160_header1b[5],
	    'm1a': tmc5160_header1b[4],
	    'm2a': tmc5160_header1b[3],
	    'gnd1': tmc5160_header1b[2],
	    'vmot': tmc5160_header1b[1],
	    'en': tmc5160_header2b[1],
	    'sdi': tmc5160_header2b[2],
	    'sck': tmc5160_header2b[3],
	    'csn': tmc5160_header2b[4],
	    'sdo': tmc5160_header2b[5],
	    'step': tmc5160_header2b[7],
	    'dir': tmc5160_header2b[8]
	}
	
	# Define the pins for TMC5160c
	tmc5160c_pins = {
	    'gnd2': tmc5160_header1c[8], 
	    '3v3': tmc5160_header1c[7],
	    'm2b': tmc5160_header1c[6],
	    'm1b': tmc5160_header1c[5],
	    'm1a': tmc5160_header1c[4],
	    'm2a': tmc5160_header1c[3],
	    'gnd1': tmc5160_header1c[2],
	    'vmot': tmc5160_header1c[1],
	    'en': tmc5160_header2c[1],
	    'sdi': tmc5160_header2c[2],
	    'sck': tmc5160_header2c[3],
	    'csn': tmc5160_header2c[4],
	    'sdo': tmc5160_header2c[5],
	    'step': tmc5160_header2c[7],
	    'dir': tmc5160_header2c[8]
	}
	
	# Create VIN and GND nets.
	vin = Net("VIN")
	gnd = Net("GND")
	
	# Create 3.3v gnd net.
	vcc_gnd = Net("VCC_GND")
	
	# Connect 36V_V+ and 36V_GND to the terminal block
	V_plus_36V += terminal_block[1]  # Connect 36V_V+ to the first pin of the PT terminal block slot 1
	GND_36V += terminal_block[2]     # Connect 36V_GND to the third pin of the PT terminal block slot 2
	
	# Connect VIN and GND to ESP32 header 2.
	vin += terminal_block_2[1] # Connect VIN to the MPT TerminalBlock slot 1
	gnd += terminal_block_2[2] # Connect GND to the MPT TerminalBlock slot 2
	
	# Connect capacitor between 36V_V+ and 36V_GND nets
	capacitor[1, 2] += V_plus_36V, GND_36V
	capacitor_b[1, 2] += V_plus_36V, GND_36V
	capacitor_c[1, 2] += V_plus_36V, GND_36V
	
	# Connect one pin of the limit switch header to the resistor and the other pin to ESP32 3.3v (Pull-down Resistor!)
	# limit_switch_header[1] += resistor1[2], esp32_header1[5]  # Connect pin 1 of limit switch header to one pin of the resistor, and pin 5 on esp32 header 1
	# limit_switch_header[2] += esp32_header2[1]           # Connect pin 2 of limit switch header to ESP32 3.3v pin
	
	# Connect VIN and GND to ESP32 and TMC5160 pins.
	vin += esp32_vin
	gnd += esp32_gnd1
	
	vcc_gnd += esp32_gnd2
	
	# vcc_gnd += resistor1[1] # GND connected to Resistor pin 1
	
	# Connect all the CAN Bus headers to the ESP32 Header 2
	can_bus_header[1] += esp32_3v3 # 3.3v
	can_bus_header[2] += esp32_gnd2 # GND
	can_bus_header[3] += esp32_gpio4 # CAN TX
	can_bus_header[4] += esp32_gpio5 # CAN RX
	
	# First TMC5160 Instance
	esp32_3v3 += tmc5160_pins['3v3']
	esp32_gnd2 += tmc5160_pins['gnd2']
	V_plus_36V += tmc5160_pins['vmot']
	GND_36V += tmc5160_pins['gnd1']
	vcc_gnd += tmc5160_pins['gnd2']
	esp32_gpio13 += tmc5160_pins['dir']
	esp32_gpio12 += tmc5160_pins['step']
	esp32_gpio15 += tmc5160_pins['en']
	esp32_gpio23 += tmc5160_pins['sdi']
	esp32_gpio19 += tmc5160_pins['sdo']
	esp32_gpio18 += tmc5160_pins['sck']
	esp32_gpio14 += tmc5160_pins['csn']
	stepper_motor_header[1] += tmc5160_pins['m2a']
	stepper_motor_header[2] += tmc5160_pins['m1a']
	stepper_motor_header[3] += tmc5160_pins['m1b']
	stepper_motor_header[4] += tmc5160_pins['m2b']
	
	# Second TMC5160 Instance
	esp32_3v3 += tmc5160b_pins['3v3']
	esp32_gnd2 += tmc5160b_pins['gnd2']
	V_plus_36V += tmc5160b_pins['vmot']
	GND_36V += tmc5160b_pins['gnd1']
	vcc_gnd += tmc5160b_pins['gnd2']
	esp32_gpio27 += tmc5160b_pins['dir']
	esp32_gpio26 += tmc5160b_pins['step']
	esp32_gpio17 += tmc5160b_pins['en']
	esp32_gpio23 += tmc5160b_pins['sdi']
	esp32_gpio19 += tmc5160b_pins['sdo']
	esp32_gpio18 += tmc5160b_pins['sck']
	esp32_gpio25 += tmc5160b_pins['csn']
	stepper_motor_header_b[1] += tmc5160b_pins['m2a']
	stepper_motor_header_b[2] += tmc5160b_pins['m1a']
	stepper_motor_header_b[3] += tmc5160b_pins['m1b']
	stepper_motor_header_b[4] += tmc5160b_pins['m2b']
	
	# Third TMC5160 Instance
	esp32_3v3 += tmc5160c_pins['3v3']
	esp32_gnd2 += tmc5160c_pins['gnd2']
	V_plus_36V += tmc5160c_pins['vmot']
	GND_36V += tmc5160c_pins['gnd1']
	vcc_gnd += tmc5160c_pins['gnd2']
	esp32_gpio32 += tmc5160c_pins['dir']
	esp32_gpio2 += tmc5160c_pins['step']
	esp32_gpio22 += tmc5160c_pins['en']
	esp32_gpio23 += tmc5160c_pins['sdi']
	esp32_gpio19 += tmc5160c_pins['sdo']
	esp32_gpio18 += tmc5160c_pins['sck']
	esp32_gpio33 += tmc5160c_pins['csn']
	stepper_motor_header_c[1] += tmc5160c_pins['m2a']
	stepper_motor_header_c[2] += tmc5160c_pins['m1a']
	stepper_motor_header_c[3] += tmc5160c_pins['m1b']
	stepper_motor_header_c[4] += tmc5160c_pins['m2b']

    ###
    ### pcbflow PCB Declarations
    ###

	# Create a pcbflow Board instance
	brd = Board((100, 100))  # Adjust the board size as per your requirement

	brd.add_inner_copper_layer(2)

	# Place 2 mm mounting holes in the corners
	holes = ((5, 5), (5, 25), (50, 5), (50, 25))
	for hole in holes:
		brd.add_hole(hole, 2.0)

	# Assign a convenient reference to the default SKiDL circuit
	ckt = default_circuit

	print("Circuit:  Parts: %d  Nets: %d" % (len(ckt.parts), len(ckt.nets)))

	# Assign part locations
	esp32_header1.loc = (35, 15)
	esp32_header2.loc = (45, 15)
	tmc5160_header1.loc = (25, 15)
	tmc5160_header2.loc = (55, 15)
	tmc5160_header1b.loc = (20, 10)
	tmc5160_header2b.loc = (60, 10)
	tmc5160_header1c.loc = (15, 5)
	tmc5160_header2c.loc = (65, 5)
	stepper_motor_header.loc = (30, 5)
	stepper_motor_header_b.loc = (50, 5)
	stepper_motor_header_c.loc = (70, 5)
	can_bus_header.loc = (65, 5)
	capacitor.loc = (25, 5)
	capacitor_b.loc = (45, 5)
	capacitor_c.loc = (65, 5)
	terminal_block.loc = (70, 5)
	terminal_block_2.loc = (75, 5)

	# Instantiate SkiPart(PCBPart) instances
	sides = ["top"] * 17  # Assuming all parts are on the top side

	for part, side in zip(ckt.parts, sides):
		sp = SkiPart(brd.DC(part.loc), part, side=side)
		# "fanout" GND and VDD vias from parts with GND and VDD net connections
		sp.fanout(["VDD"])
		sp.fanout(["GND"], relative_to="inside")


	# Finish the PCB with an outline and poured copper layers
	brd.add_outline()
	brd.fill_layer("GTL", "GND")
	brd.fill_layer("GBL", "GND")

	# Save the rendered PCB to asset files
	brd.save("%s" % (os.path.basename(__file__)[:-3]))

	# Generate the netlist (if required)
	generate_netlist()  # If you need to generate a netlist, add this line

	print("PCB design completed.")

@ghost ghost changed the title Unable to open KiCad symbols and libraries Unable to open KiCad footprints and libraries Apr 23, 2024
@ghost
Copy link
Author

ghost commented Apr 23, 2024

Here's the result if I change FP_LIB_PATH to 'usr/share/kicad/footprints' in kicad.py

(base) twinlizzie@twinlizzie-MS-7C51:~/Ngnuity-Repos/sylvie-2024/schematics/skidl_code$ python esp32_motor-pcb-x3_final.py
Circuit:  Parts: 17  Nets: 36
Traceback (most recent call last):
  File "/home/twinlizzie/Ngnuity-Repos/sylvie-2024/schematics/skidl_code/esp32_motor-pcb-x3_final.py", line 270, in <module>
    sp = SkiPart(brd.DC(part.loc), part, side=side)
  File "/home/twinlizzie/miniconda3/lib/python3.10/site-packages/pcbflow/kicad.py", line 288, in __init__
    super().__init__(
  File "/home/twinlizzie/miniconda3/lib/python3.10/site-packages/pcbflow/kicad.py", line 42, in __init__
    self.parse()
  File "/home/twinlizzie/miniconda3/lib/python3.10/site-packages/pcbflow/kicad.py", line 273, in parse
    self._parse_fp_text(v["fp_text"])
  File "/home/twinlizzie/miniconda3/lib/python3.10/site-packages/pcbflow/kicad.py", line 148, in _parse_fp_text
    layer = self._map_layers(e["layer"])[0]
IndexError: list index out of range

@ghost
Copy link
Author

ghost commented Apr 23, 2024

Bug fixed by adding this layer to the list in kicad.py:

KI_LAYER_DICT = {
"F.SilkS": "GTO",
"F.Paste": "GTP",
"F.Mask": "GTS",
"F.Cu": "GTL",
"F.Fab": "GTD",
"F.CrtYd": "GTO", # Assuming F.CrtYd should map to the same layer as F.SilkS
}

Credits to ChatGPT.

It also seems like I have to use Kicad 5 footprints, though it could have just been an isolated bug with a special component (in this case, a capacitor) that was causing issues.

@michaelgale
Copy link
Owner

@khanumballz glad you found a fix! I would not be surprised if pcbflow has issues with newer versions of KiCAD libraries since the data format and mapping of layers can change. I am surprised ChatGPT was able to offer assistance--I guess pcbflow is somehow part of its massive training dataset!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant