From 48717f0d28ca021d468bd3945c56fe556d8a484d Mon Sep 17 00:00:00 2001 From: Brendan Haines Date: Fri, 23 Sep 2022 19:17:09 -0600 Subject: [PATCH] working molex footprint generator --- fp_generator.py | 16 ++++----- generate_molex.py | 82 +++++++++++++++++++++++++++++++++++++++++----- generate_samtec.py | 10 +++--- 3 files changed, 87 insertions(+), 21 deletions(-) diff --git a/fp_generator.py b/fp_generator.py index 0a6b44d..d6620a6 100644 --- a/fp_generator.py +++ b/fp_generator.py @@ -54,7 +54,7 @@ class Footprint: ): try: size = (float(size), float(size)) - except ValueError: + except TypeError: size = tuple(size) 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 += ( - f' (pad "{id}" thru_hole {shape} ' - f"(at {x} {y}) " - f"(size {size[0]} {size[1]}) " - f"(drill {hole}) " - "(layers *.Cu *.Mask)" - ")\n" + f' (pad "{id}" {"thru_hole" if hole is not None else "smd"} {shape} ' + + f"(at {x} {y}) " + + f"(size {size[0]} {size[1]}) " + + (f"(drill {hole}) " if hole is not None else "") + + ("(layers *.Cu *.Mask)" if hole is not None else '(layers "F.Cu" "F.Paste" "F.Mask")') + + ")\n" ) def add_model( @@ -80,7 +80,7 @@ class Footprint: scale: Tuple[float] = (1, 1, 1), ): self._contents += ( - f' (model "{str(path)}" ' + f' (model "{str(Path(path).resolve())}" ' f"(offset (xyz {offset[0]} {offset[1]} {offset[2]})) " f"(scale (xyz {scale[0]} {scale[1]} {scale[2]})) " f"(rotate (xyz {rotate[0]} {rotate[1]} {rotate[2]})) " diff --git a/generate_molex.py b/generate_molex.py index a09d97c..1b5e22d 100644 --- a/generate_molex.py +++ b/generate_molex.py @@ -1,8 +1,9 @@ import zipfile from pathlib import Path from tempfile import TemporaryDirectory -from typing import Union +from typing import Optional, Union +import regex as re import requests from fp_generator import INCH, Footprint @@ -10,8 +11,8 @@ from fp_generator import INCH, Footprint dir_ = Path(__file__).parent PARTS = [ - # # 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 + # 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}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}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}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 - # # Eurostyle 5.08mm Headers - "39531-0002", + # Eurostyle 5.08mm Headers + # "39531-0002", # Eurostyle 5.08mm Plugs # "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}") +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__": from multiprocessing import Pool pool = Pool(10) - pool.map(download_step_molex, PARTS) - # for part in PARTS: - # download_step_molex(part) + # pool.map(download_step_molex, PARTS) + for part in PARTS: + footprint(part) pool.close() diff --git a/generate_samtec.py b/generate_samtec.py index 10a515e..522c258 100644 --- a/generate_samtec.py +++ b/generate_samtec.py @@ -90,6 +90,10 @@ def download_step(part: str, headless: bool = True) -> None: 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-"]]): # pinheader 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] - if lib is None: - lib = dir_ / "samtec.pretty" - lib = Path(lib) - fp = Footprint(fp_name, description=description, keywords=keywords) 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") @@ -150,7 +150,7 @@ def footprint(part: str, lib: Optional[Union[Path, str]] = None) -> str: shape="rect" if pad == 0 else "circle", ) fp.add_model( - f"/home/brendan/Documents/projects/kicad/samtec.pretty/3dshapes/{part}.stp", + lib / "3dshapes" / f"{part}.stp", (center[0], center[1], 0), rotate=(-90, 0, 90), )