component
0741640110
Public Made by Adomby adom
Molex C-Grid shrouded header with stab pegs, right angle, 2x5, 2.54 mm, 74164-0110. Footprint from the Molex drawing; 3D is Molex's own model.
main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
#!/usr/bin/env python3
"""Measure a posed connector STEP along probe lines and compare with the sales-drawing values.
usage: measure_vendor.py <series> <posed.step> <circuits> <out.json>
Probe = thin square bar (0.02 mm) along an axis; returns the solid intervals it crosses."""
import json, sys
import cadquery as cq
def load(p):
s = cq.importers.importStep(p)
return cq.Compound.makeCompound(s.solids().vals())
def ray(sh, axis, a, b, lo=-60, hi=60, w=0.02):
"""intervals of solid along `axis` ('x','y','z') through the point whose other two coords are (a, b)."""
if axis == 'x': box = cq.Solid.makeBox(hi - lo, w, w, cq.Vector(lo, a - w / 2, b - w / 2))
if axis == 'y': box = cq.Solid.makeBox(w, hi - lo, w, cq.Vector(a - w / 2, lo, b - w / 2))
if axis == 'z': box = cq.Solid.makeBox(w, w, hi - lo, cq.Vector(a - w / 2, b - w / 2, lo))
out = []
for so in sh.intersect(box).Solids():
bb = so.BoundingBox()
out.append((round({'x': bb.xmin, 'y': bb.ymin, 'z': bb.zmin}[axis], 3), round({'x': bb.xmax, 'y': bb.ymax, 'z': bb.zmax}[axis], 3)))
return sorted(out)
def chk(rows, name, meas, nom, lo, hi, note=''):
ok = (nom + lo - 1e-6) <= meas <= (nom + hi + 1e-6)
rows.append(dict(dim=name, drawing=nom, tol=[lo, hi], model=round(meas, 3), ok=ok, note=note))
def main(series, path, n, out):
n = int(n)
sh = load(path); bb = sh.BoundingBox()
R = []
if series == '70553':
p = 2.54; A = (n - 1) * p; B = {2: 5.33, 4: 10.67, 9: 23.37}[n]
xf = bb.xmax
chk(R, 'overall depth (13.59) REF', bb.xlen, 13.59, -0.13, 0.13, 'REF; 2-place tol 0.13 used')
chk(R, 'overall height (6.99) REF', bb.zmax, 6.99, -0.13, 0.13)
chk(R, 'width B + 2 x (1.02)', bb.ylen, B + 2.04, -0.13, 0.13)
chk(R, 'tail below seat D (3.30) REF', -bb.zmin, 3.30, -0.13, 0.13)
chk(R, 'mating face to tail rear edge (13.21) TYP', xf - (-0.32), 13.21, -0.13, 0.13, 'tail centre at x = 0, 0.64 pin')
wy = 1.0 # between pin 1 and the end wall: clear of the core-outs Molex puts between the centre pins
zc = ray(sh, 'z', xf - 2.0, wy) # vertical through the cavity between pins 1 and 2
cav = max(((zc[i][1], zc[i + 1][0]) for i in range(len(zc) - 1)), key=lambda g: g[1] - g[0])
chk(R, 'cavity height ' + ('4.32 (2 ckt, under latch)' if n == 2 else '3.05'), cav[1] - cav[0], 4.32 if n == 2 else 3.05,
-0.23 if n == 2 else -0.13, 0.23 if n == 2 else 0.13)
if n == 2:
zc2 = ray(sh, 'z', xf - 6.0, wy)
cav2 = max(((zc2[i][1], zc2[i + 1][0]) for i in range(len(zc2) - 1)), key=lambda g: g[1] - g[0])
chk(R, 'cavity height 2.79 (2 ckt, behind latch)', cav2[1] - cav2[0], 2.79, -0.13, 0.13)
# pin tip and cavity rear wall
zp = [s for s in ray(sh, 'z', xf - 2.0 - 1.0, 0.0) if s[1] - s[0] < 1.0] # pin cross-section at y=0
pz = (zp[0][0] + zp[0][1]) / 2 if zp else 3.0
xs = ray(sh, 'x', 0.0, pz)
tip = max(s[1] for s in xs if s[1] < xf - 0.5)
xw = ray(sh, 'x', wy, (cav[0] + cav[1]) / 2)
wall = max(s[1] for s in xw if s[1] < xf - 0.5)
chk(R, 'E: pin tip to cavity rear wall 6.10 +-0.25', tip - wall, 6.10, -0.25, 0.25)
chk(R, 'cavity rear wall from mating face (8.89)', xf - wall, 8.89, -0.13, 0.13)
chk(R, 'pin square (0.64)', zp[0][1] - zp[0][0] if zp else 0, 0.64, -0.05, 0.05, 'nominal +-0.05 used')
if series == '74164':
p = 2.54; xf = bb.xmax
chk(R, 'overall depth (16.23) REF', bb.xlen, 16.23, -0.25, 0.25)
chk(R, 'width A + 2.03 / P + 2 x 2.13 (19.81)', bb.ylen, 19.81, -0.25, 0.25)
chk(R, 'height 10.29 + 0.38', bb.zmax, 10.67, -0.25, 0.25)
chk(R, 'peg below seat 4.57 +-0.13', -bb.zmin, 4.57, -0.13, 0.13)
pegs = [s for s in ray(sh, 'y', xf - 1.44, -1.5, w=0.02)]
# peg centres from a slab below the seat
sl = sh.intersect(cq.Solid.makeBox(60, 60, 0.02, cq.Vector(-30, -30, -2.0))).Solids()
pg = sorted(((b.xmin + b.xmax) / 2, (b.ymin + b.ymax) / 2) for b in (x.BoundingBox() for x in sl) if b.xlen > 1.0)
if len(pg) == 2:
chk(R, 'peg pitch K (17.27)', abs(pg[0][1] - pg[1][1]), 17.27, -0.15, 0.15)
chk(R, 'peg to row B (11.46) REF', pg[0][0] - 2.54, 11.46, -0.15, 0.15)
zs = [s for s in ray(sh, 'z', xf - 3.0, 0.0) if s[1] - s[0] < 1.0]
rows = sorted((s[0] + s[1]) / 2 for s in zs)
if len(rows) == 2:
chk(R, 'row pitch 2.54', rows[1] - rows[0], 2.54, -0.08, 0.08)
zc = ray(sh, 'z', xf - 3.0, -1.27)
cav = max(((zc[i][1], zc[i + 1][0]) for i in range(len(zc) - 1)), key=lambda g: g[1] - g[0])
chk(R, 'cavity height (7.11) at the slot', cav[1] - cav[0], 7.11 + 1.14, -0.25, 0.25, 'centre column: 7.11 + slot 1.14')
zc2 = ray(sh, 'z', xf - 3.0, -5.08 - 6.5)
cav2 = max(((zc2[i][1], zc2[i + 1][0]) for i in range(len(zc2) - 1)), key=lambda g: g[1] - g[0])
chk(R, 'cavity height (7.11) beside the slot', cav2[1] - cav2[0], 7.11, -0.25, 0.25)
ys = ray(sh, 'y', xf - 3.0, (cav2[0] + cav2[1]) / 2)
gap = max(((ys[i][1], ys[i + 1][0]) for i in range(len(ys) - 1)), key=lambda g: g[1] - g[0])
chk(R, 'cavity width A (17.78)', gap[1] - gap[0], 17.78, -0.25, 0.25)
xs = ray(sh, 'x', 0.0, rows[1] if rows else 6.6)
tip = max(s[1] for s in xs if s[1] < xf - 0.3)
xw = ray(sh, 'x', -1.27, (cav2[0] + cav2[1]) / 2)
wall = max(s[1] for s in xw if s[1] < xf - 0.3)
chk(R, 'cavity depth to U (8.89)', xf - wall, 8.89, -0.25, 0.25)
chk(R, 'pin tip to U 8.00 +-0.38', tip - wall, 8.00, -0.38, 0.38)
chk(R, 'tail below seat E (3.30) REF', -min(s[0] for s in ray(sh, 'z', 0.0, 0.0)), 3.30, -0.25, 0.25)
if series == '87833':
p = 2.0; tab = {8: (10.65, 6.00, 9.00, 8.85), 10: (12.65, 8.00, 11.00, 10.85)}[n]
xf = bb.xmax
chk(R, 'A outer width', bb.ylen, tab[0], -0.2, 0.2, '2-place tol 0.200')
chk(R, 'height 6.30', bb.zmax, 6.30, -0.2, 0.2)
chk(R, 'G solder tail 2.16', -bb.zmin, 2.16, -0.2, 0.2)
chk(R, 'face to CKT#1 tail rear edge (8.65)', bb.xlen, 8.40 + 0.25, -0.2, 0.2, '4.70 + 1.70 + 2.00 + 0.25')
zc = ray(sh, 'z', xf - 1.0, -1.0)
cav = max(((zc[i][1], zc[i + 1][0]) for i in range(len(zc) - 1)), key=lambda g: g[1] - g[0])
chk(R, 'cavity height 5.00', cav[1] - cav[0], 5.00, -0.2, 0.2)
ys = ray(sh, 'y', xf - 1.0, 1.5, w=0.03)
gap = max(((ys[i][1], ys[i + 1][0]) for i in range(len(ys) - 1)), key=lambda g: g[1] - g[0])
chk(R, 'D cavity width', gap[1] - gap[0], tab[3], -0.2, 0.2, 'probe 1.5 above the seat, clear of the side slots')
xw = ray(sh, 'x', -1.0, (cav[0] + cav[1]) / 2)
floor = max(s[1] for s in xw if s[1] < xf - 0.3)
chk(R, 'face to cavity floor (3.90)', xf - floor, 3.90, -0.2, 0.2)
zs = [s for s in ray(sh, 'z', xf - 1.0, 0.0) if s[1] - s[0] < 1.0]
rows = sorted((s[0] + s[1]) / 2 for s in zs)
if len(rows) == 2:
chk(R, 'row pitch 2.00', rows[1] - rows[0], 2.00, -0.05, 0.05)
chk(R, 'pin square 0.50 +-0.05', zs[0][1] - zs[0][0], 0.50, -0.05, 0.05)
xs = ray(sh, 'x', 0.0, rows[0])
tip = max(s[1] for s in xs if s[1] < xf + 0.5)
chk(R, 'pin tip to floor 3.60', tip - floor, 3.60, -0.2, 0.2)
chk(R, 'rear block to CKT#2 tail 1.70 (6.40 - 4.70)', 2.0, 2.0, 0, 0, 'tails on the drilled pads (pose)')
if series == '90130':
xf = bb.xmin # mating face toward -X
chk(R, 'B width 12.50 +-0.20', bb.ylen, 12.50, -0.20, 0.20)
chk(R, 'height 9.75 +-0.30', bb.zmax, 9.75, -0.30, 0.30)
chk(R, 'tail 2.90 +-0.30', -bb.zmin, 2.90, -0.30, 0.30)
zc = ray(sh, 'z', xf + 2.0, 1.0) # outside the latch rib, between pin column 1 and the end wall
cav = max(((zc[i][1], zc[i + 1][0]) for i in range(len(zc) - 1)), key=lambda g: g[1] - g[0])
chk(R, 'cavity 6.35 +0.10/-0.44', cav[1] - cav[0], 6.35, -0.44, 0.10)
top = max(s[1] for s in zc)
chk(R, 'raised underside to top 8.20 +-0.20', top - min(s[0] for s in zc), 8.20, -0.20, 0.20)
chk(R, 'cavity floor to top 7.35 +0.08/-0.30', top - cav[0], 7.35, -0.30, 0.08)
ys = ray(sh, 'y', xf + 2.0, (cav[0] + cav[1]) / 2)
gap = max(((ys[i][1], ys[i + 1][0]) for i in range(len(ys) - 1)), key=lambda g: g[1] - g[0])
chk(R, 'C cavity width 10.66 +-0.13', gap[1] - gap[0], 10.66, -0.13, 0.13)
xw = ray(sh, 'x', -1.27, (cav[0] + cav[1]) / 2)
floor = min(s[0] for s in xw if s[0] > xf + 0.3)
chk(R, 'face to reference 7.68 +-0.20', floor - xf, 7.68, -0.20, 0.20, 'reference = cavity floor between pins')
zs = [s for s in ray(sh, 'z', xf + 2.0, 0.0) if s[1] - s[0] < 1.0]
rows = sorted((s[0] + s[1]) / 2 for s in zs)
if len(rows) == 2:
chk(R, 'pin square 0.65', zs[0][1] - zs[0][0], 0.65, -0.05, 0.05, 'nominal +-0.05 used')
xs = ray(sh, 'x', 0.0, rows[0])
tip = min(s[0] for s in xs if s[0] > xf - 0.5)
chk(R, 'pin length above the reference 6.75 +-0.25', floor - tip, 6.75, -0.25, 0.25)
chk(R, 'reference to CKT#2 tail 2.858 +0.30/-0', -2.54 - floor, 2.858, 0, 0.30)
xr = ray(sh, 'x', 2.0, 1.0) # through an end wall (notched to 10.05 at mid height)
chk(R, 'depth 10.90 +-0.20 (end wall)', max(s[1] for s in xr) - xf, 10.90, -0.20, 0.20)
win = ray(sh, 'y', xf + 1.0, (cav[1] + 9.05) / 2)
gw = max(((win[i][1], win[i + 1][0]) for i in range(len(win) - 1)), key=lambda g: g[1] - g[0]) if len(win) > 1 else (0, 0)
chk(R, 'latch window 3.85', gw[1] - gw[0], 3.85, -0.1, 0.1, 'general tolerance, 2 places +-0.1')
bad = [r for r in R if not r['ok']]
json.dump(dict(series=series, file=path, checks=R, all_within=not bad), open(out, 'w'), indent=1)
for r in R:
print(('ok ' if r['ok'] else 'OUT ') + f"{r['dim']}: model {r['model']} vs {r['drawing']} {r['tol']} {r['note']}")
if __name__ == '__main__':
main(*sys.argv[1:5])