working molex footprint generator

This commit is contained in:
Brendan Haines 2022-09-23 19:17:09 -06:00
parent ebe1c4d357
commit 48717f0d28
3 changed files with 87 additions and 21 deletions

View File

@ -54,7 +54,7 @@ class Footprint:
): ):
try: try:
size = (float(size), float(size)) size = (float(size), float(size))
except ValueError: except TypeError:
size = tuple(size) size = tuple(size)
if shape not in [None, "circle", "rect", "round_rect"]: if shape not in [None, "circle", "rect", "round_rect"]:
@ -64,12 +64,12 @@ class Footprint:
self._contents.replace("(attr smd)", "(attr through_hole)") self._contents.replace("(attr smd)", "(attr through_hole)")
self._contents += ( self._contents += (
f' (pad "{id}" thru_hole {shape} ' f' (pad "{id}" {"thru_hole" if hole is not None else "smd"} {shape} '
f"(at {x} {y}) " + f"(at {x} {y}) "
f"(size {size[0]} {size[1]}) " + f"(size {size[0]} {size[1]}) "
f"(drill {hole}) " + (f"(drill {hole}) " if hole is not None else "")
"(layers *.Cu *.Mask)" + ("(layers *.Cu *.Mask)" if hole is not None else '(layers "F.Cu" "F.Paste" "F.Mask")')
")\n" + ")\n"
) )
def add_model( def add_model(
@ -80,7 +80,7 @@ class Footprint:
scale: Tuple[float] = (1, 1, 1), scale: Tuple[float] = (1, 1, 1),
): ):
self._contents += ( self._contents += (
f' (model "{str(path)}" ' f' (model "{str(Path(path).resolve())}" '
f"(offset (xyz {offset[0]} {offset[1]} {offset[2]})) " f"(offset (xyz {offset[0]} {offset[1]} {offset[2]})) "
f"(scale (xyz {scale[0]} {scale[1]} {scale[2]})) " f"(scale (xyz {scale[0]} {scale[1]} {scale[2]})) "
f"(rotate (xyz {rotate[0]} {rotate[1]} {rotate[2]})) " f"(rotate (xyz {rotate[0]} {rotate[1]} {rotate[2]})) "

View File

@ -1,8 +1,9 @@
import zipfile import zipfile
from pathlib import Path from pathlib import Path
from tempfile import TemporaryDirectory from tempfile import TemporaryDirectory
from typing import Union from typing import Optional, Union
import regex as re
import requests import requests
from fp_generator import INCH, Footprint from fp_generator import INCH, Footprint
@ -10,8 +11,8 @@ from fp_generator import INCH, Footprint
dir_ = Path(__file__).parent dir_ = Path(__file__).parent
PARTS = [ PARTS = [
# # Micro-Fit 3.0 Single Row Headers # Micro-Fit 3.0 Single Row Headers
# *[f"43650-{i:02d}10" for i in range(2, 13)], # 1 row, RA, press-fit retention clip *[f"43650-{i:02d}10" for i in range(2, 13)], # 1 row, RA, press-fit retention clip
# *[f"43650-{i:02d}13" for i in range(2, 13)], # 1 row, RA, solder tab # *[f"43650-{i:02d}13" for i in range(2, 13)], # 1 row, RA, solder tab
# *[f"43650-{i:02d}22" for i in range(2, 13)], # 1 row, Vertical, press-fit retention clip # *[f"43650-{i:02d}22" for i in range(2, 13)], # 1 row, Vertical, press-fit retention clip
# *[f"43650-{i:02d}25" for i in range(2, 13)], # 1 row, RA, solder tab # *[f"43650-{i:02d}25" for i in range(2, 13)], # 1 row, RA, solder tab
@ -20,8 +21,8 @@ PARTS = [
# *[f"43045-{i:02d}10" for i in range(2, 25, 2)], # 2 row, RA, solder tab # *[f"43045-{i:02d}10" for i in range(2, 25, 2)], # 2 row, RA, solder tab
# *[f"43045-{i:02d}16" for i in range(2, 25, 2)], # 2 row, Vertical, press-fit retention clip # *[f"43045-{i:02d}16" for i in range(2, 25, 2)], # 2 row, Vertical, press-fit retention clip
# *[f"43045-{i:02d}19" for i in range(2, 25, 2)], # 2 row, RA, solder tab # *[f"43045-{i:02d}19" for i in range(2, 25, 2)], # 2 row, RA, solder tab
# # Eurostyle 5.08mm Headers # Eurostyle 5.08mm Headers
"39531-0002", # "39531-0002",
# Eurostyle 5.08mm Plugs # Eurostyle 5.08mm Plugs
# "39530-0002", # "39530-0002",
] ]
@ -59,11 +60,76 @@ def download_step_molex(part: Union[str, int]) -> None:
raise ValueError(f"Could not download .stp for part {part}") raise ValueError(f"Could not download .stp for part {part}")
def footprint(part: str, lib: Optional[Union[Path, str]] = None):
# remove dash
part = f'{int(str(part).replace("-", "")):09d}'
print(part)
if lib is None:
lib = dir_ / "molex.pretty"
lib = Path(lib)
if part.startswith("43650"):
match = re.match(r"43650(\d\d)(\d\d)", part)
pins = int(match[1])
flavor = int(match[2])
if flavor == 10:
fp = Footprint(part, description=f"connector, Micro-Fit 3.0, 1x{pins:02f}, RA, press-fit retention clip")
fp.add_text("reference", "REF**", -(6.93 + (0.025 + 0.005) * INCH), 0, rotation=90, layer="F.SilkS")
fp.add_text("value", "VAL**", -0.025 * INCH, 0, rotation=90, layer="F.Fab")
fp.add_text("user", r"${REFERENCE}**", 0.025 * INCH, 0, rotation=90, layer="F.Fab")
# fp.add_rect(
# [-0.05 * INCH] * 2,
# (0.05 * INCH + strobe[0] * (cols - 1), 0.05 * INCH + strobe[1] * (rows - 1)),
# layer="F.SilkS",
# )
# fp.add_line((-0.05 * INCH, 0.05 * INCH), (0.05 * INCH, 0.05 * INCH), layer="F.SilkS")
# fp.add_line((0.05 * INCH, -0.05 * INCH), (0.05 * INCH, 0.05 * INCH), layer="F.SilkS")
a, b, c = {
2: (0.380, 0.118, 0.287),
3: (0.498, 0.236, 0.405),
4: (0.616, 0.354, 0.524),
5: (0.734, 0.472, 0.642),
6: (0.852, 0.591, 0.760),
7: (0.970, 0.709, 0.878),
8: (1.088, 0.827, 0.996),
9: (1.206, 0.945, 1.114),
10: (1.325, 1.063, 1.232),
11: (1.443, 1.181, 1.350),
12: (1.561, 1.299, 1.469),
}[pins]
a *= INCH
b *= INCH
c *= INCH
for pad in range(pins):
fp.add_pad(
pad + 1,
(-0.273 + 0.115 / 2) * INCH,
-3.0 * (pins - 1) / 2 + 3.0 * pad,
size=(0.115 * INCH, 0.050 * INCH),
shape="rect",
)
# mechanical holes
for s in [1, -1]:
fp.add_pad(0, 0, s * c / 2, size=(0.095 + 0.050) * INCH, hole=0.095 * INCH, shape="circle")
fp.add_model(
lib / "3dshapes" / f"{part}.stp",
(4.6, 0, 0.5),
rotate=(0, 0, -90),
)
fp.add_rect((4.6 - 9.9, -a / 2), (4.6, a / 2), layer="F.Fab")
fp.write(lib)
else:
raise NotImplementedError
else:
raise NotImplementedError
if __name__ == "__main__": if __name__ == "__main__":
from multiprocessing import Pool from multiprocessing import Pool
pool = Pool(10) pool = Pool(10)
pool.map(download_step_molex, PARTS) # pool.map(download_step_molex, PARTS)
# for part in PARTS: for part in PARTS:
# download_step_molex(part) footprint(part)
pool.close() pool.close()

View File

@ -90,6 +90,10 @@ def download_step(part: str, headless: bool = True) -> None:
def footprint(part: str, lib: Optional[Union[Path, str]] = None) -> str: def footprint(part: str, lib: Optional[Union[Path, str]] = None) -> str:
if lib is None:
lib = dir_ / "samtec.pretty"
lib = Path(lib)
if any([part.startswith(s) for s in ["TSW-", "HTSW-"]]): if any([part.startswith(s) for s in ["TSW-", "HTSW-"]]):
# pinheader # pinheader
match = re.match( match = re.match(
@ -125,10 +129,6 @@ def footprint(part: str, lib: Optional[Union[Path, str]] = None) -> str:
center = [strobe[0] * (cols - 1) / 2, strobe[1] * (rows - 1) / 2] center = [strobe[0] * (cols - 1) / 2, strobe[1] * (rows - 1) / 2]
if lib is None:
lib = dir_ / "samtec.pretty"
lib = Path(lib)
fp = Footprint(fp_name, description=description, keywords=keywords) fp = Footprint(fp_name, description=description, keywords=keywords)
fp.add_text("reference", "REF**", center[0], -2.032, layer="F.SilkS") fp.add_text("reference", "REF**", center[0], -2.032, layer="F.SilkS")
fp.add_text("value", "VAL**", center[0] - 0.025 * INCH, center[1], rotation=90, layer="F.Fab") fp.add_text("value", "VAL**", center[0] - 0.025 * INCH, center[1], rotation=90, layer="F.Fab")
@ -150,7 +150,7 @@ def footprint(part: str, lib: Optional[Union[Path, str]] = None) -> str:
shape="rect" if pad == 0 else "circle", shape="rect" if pad == 0 else "circle",
) )
fp.add_model( fp.add_model(
f"/home/brendan/Documents/projects/kicad/samtec.pretty/3dshapes/{part}.stp", lib / "3dshapes" / f"{part}.stp",
(center[0], center[1], 0), (center[0], center[1], 0),
rotate=(-90, 0, 90), rotate=(-90, 0, 90),
) )