component
LTC2945CMS#PBF - Wide Range I2C Power Monitor
Public Made by Adomby adom
Analog Devices (Linear Technology) LTC2945CMS#PBF: wide range I2C power monitor, 0 V to 80 V current and voltage sensing, 12-bit ADC, 24-bit power, min/max and alerts, split SDA for opto-isolation, 0 C to 70 C, MSOP-12. KiCad, Fusion and Altium libraries, 3D model and datasheet.
main
#!/usr/bin/env python3
"""Measure a SOIC-8 gull-wing STEP (KiCad frame: Z up, seated on z = 0, pins along +-x, pitch along y),
whether body and leads are separate solids or one fused solid, using plane sections:
body : section y = 0 (between leads) -> E1 (molded width, widest), A1 (standoff), A (overall height);
section x = 0 -> D (molded length)
leads : section y = lead centre -> tip-to-tip E, gauge-plane foot L (JEDEC: tip to where the lead's lower
outer surface crosses z = 0.25); section x = foot (tip + 0.15) -> lead width b (per lead), thickness c
usage: dims.py part.step [lead_y] (lead_y default -1.905)"""
import sys, json, cadquery as cq
from OCP.BRepAlgoAPI import BRepAlgoAPI_Section
from OCP.gp import gp_Pln, gp_Pnt, gp_Dir
def sec(shape, p, d):
s = BRepAlgoAPI_Section(shape.wrapped, gp_Pln(gp_Pnt(*p), gp_Dir(*d))); s.Build()
return cq.Shape.cast(s.Shape())
a = cq.importers.importStep(sys.argv[1]); shp = cq.Compound.makeCompound(a.solids().vals())
ly = float(sys.argv[2]) if len(sys.argv) > 2 else -1.905
GT = float(sys.argv[3]) if len(sys.argv) > 3 else 0.3
bb = shp.BoundingBox()
r = lambda v: round(v, 4)
o = {"file": sys.argv[1].split("/")[-1], "solids": len(a.solids().vals()),
"overall_bbox": [r(v) for v in (bb.xmin, bb.ymin, bb.zmin, bb.xmax, bb.ymax, bb.zmax)]}
b0 = sec(shp, (0, 0, 0), (0, 1, 0)).BoundingBox()
o["E1_body_width"] = r(b0.xlen); o["A1_standoff"] = r(b0.zmin); o["A_overall_height"] = r(b0.zmax)
o["A2_molded_thickness"] = r(b0.zmax - b0.zmin)
b1 = sec(shp, (0, 0, 0), (1, 0, 0)).BoundingBox(); o["D_body_length"] = r(b1.ylen)
prof = sec(shp, (0, ly, 0), (0, 1, 0)); pb = prof.BoundingBox()
o["E_tip_to_tip"] = r(pb.xlen)
g = sec(prof, (0, 0, 0.25), (0, 0, 1))
xs = sorted(v.X for v in g.Vertices() if v.X < 0)
o["gauge_crossings_x"] = [r(x) for x in xs]
o["L_gauge"] = r(xs[0] - pb.xmin) if xs else None
foot = sec(shp, (pb.xmin + 0.15, 0, 0), (1, 0, 0))
# group edges by y into leads
ys = sorted(set(r(v.Y) for v in foot.Vertices()))
groups = [];
for y in ys:
if groups and y - groups[-1][-1] < GT: groups[-1].append(y)
else: groups.append([y])
o["foot_leads_y"] = [[g_[0], g_[-1]] for g_ in groups]
o["b_lead_width"] = [r(g_[-1] - g_[0]) for g_ in groups]
o["pitch"] = [r((groups[i+1][0] + groups[i+1][-1]) / 2 - (groups[i][0] + groups[i][-1]) / 2) for i in range(len(groups) - 1)]
zs = [v.Z for v in foot.Vertices()]
o["c_lead_thickness"] = r(max(zs) - min(zs)) if zs else None
o["foot_z"] = [r(min(zs)), r(max(zs))] if zs else None
print(json.dumps(o, indent=1))