kicad/generate_molex.py

138 lines
4.9 KiB
Python
Raw Permalink Normal View History

import zipfile
from pathlib import Path
from tempfile import TemporaryDirectory
2022-09-23 19:17:09 -06:00
from typing import Optional, Union
2022-09-23 19:17:09 -06:00
import regex as re
import requests
from fp_generator import INCH, Footprint
dir_ = Path(__file__).parent
PARTS = [
2022-09-23 19:17:09 -06:00
# 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
# # Micro-Fit 3.0 Dual Row Headers
# *[f"43045-{i:02d}07" for i in range(2, 25, 2)], # 2 row, RA, press-fit retention clip
# *[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
2022-09-23 19:17:09 -06:00
# Eurostyle 5.08mm Headers
# "39531-0002",
# Eurostyle 5.08mm Plugs
# "39530-0002",
]
def download_step_molex(part: Union[str, int]) -> None:
# remove dash
part = f'{int(str(part).replace("-", "")):09d}'
print(part)
with TemporaryDirectory(prefix=str(dir_ / "tmp") + "/") as tmp:
tmp = Path(tmp)
for p in [part, part[:5] + "-" + part[5:]]:
try:
zipname = f"{part}_stp.zip"
# download
with open(tmp / zipname, "wb") as f:
f.write(requests.get(f"https://www.molex.com/pdm_docs/stp/{p}_stp.zip").content)
# unzip
with zipfile.ZipFile(tmp / zipname) as zip:
zip.extractall(path=str(tmp))
# move
filename = f"{part}.stp"
2022-10-29 21:25:03 -06:00
(Path(tmp) / filename).rename(dir_ / "molex.pretty" / "step" / filename)
return
except zipfile.BadZipFile:
print(f"zip does not exist for part {p}")
raise ValueError(f"Could not download .stp for part {part}")
2022-09-23 19:17:09 -06:00
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, lib=lib, description=f"connector, Micro-Fit 3.0, 1x{pins:02f}, RA, press-fit retention clip"
)
2022-09-23 19:17:09 -06:00
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(
2022-10-29 21:25:03 -06:00
lib / "step" / f"{part}.stp",
2022-09-23 19:17:09 -06:00
(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()
2022-09-23 19:17:09 -06:00
else:
raise NotImplementedError
else:
raise NotImplementedError
if __name__ == "__main__":
from multiprocessing import Pool
pool = Pool(10)
2022-09-23 19:17:09 -06:00
# pool.map(download_step_molex, PARTS)
for part in PARTS:
footprint(part)
pool.close()