"""PCB terminal block with push-in spring connection, Phoenix Contact SPT 1,5 (3.5 mm), SPT 2,5 (5.0 mm) and SPT 5 (7.5 mm) types, horizontal (wire entries at the front) or vertical (wire entries on top). Pin 1 (its back pin) is at the origin, the row along +X, the housing on the XY plane with its front facing -Y, the solder pins down through the board. Dimensions from Phoenix Contact's data sheets in the README.""" from steve import Model series = "SPT 2,5" # Series style = "horizontal" # horizontal: wires enter at the front (-H-); vertical: from the top (-V-) positions = 2 # Positions pins = "double" # double: two solder pins per position; zigzag: one per position, alternating rows (SPT 5 ...-ZB) approval = "standard" # standard, or EX: the Ex eb version of SPT 2,5 (...-EX), the same housing and pins # series: (pitch, pin 1 from the left end, width past dimension a (a = pitch x (positions - 1)), solder pin across the row, along it, # solder pin length, positions offered) # SPT 1,5: data sheet SPT 1,5/ 3-H-3,5 (1990740, 07/26/2021), Dimensions p. 2, drilling diagram p. 5 and dimensional drawing p. 6: # width a + 4.9, pin 1 1.3 from the left end, pins 0.8 x 0.8, 2.5 long. # SPT 2,5: data sheets SPT 2,5/ 2-H-5,0 (1990973, 01/17/2021) p. 3 and drawings p. 5, and SPT 2,5/ 2-H-5,0-EX (1732386, 03/27/2014) # drawings p. 2: width a + 6.4 (11.4 for 2 positions), pin 1 2.3 from the left end, pins 0.8 x 0.8, 2.5 long. # SPT 5: data sheet SPT 5/ 4-H-7,5-ZB (1719215, Feb 17, 2010) p. 1 and drawings pp. 3-4: pin 1 6.55 from the left end (drilling plan), # width a + 7.5 plus a 1.8 end plate (a + 9.3), pins 1.7 x 0.8 (1.7 across the row, as the front view draws them), 4.6 long. # Positions offered are the old catalogue's range for each series; the drawings give the width for any count. SERIES = { "SPT 1,5": (3.5, 1.3, 4.9, 0.8, 0.8, 2.5, 2, 12), "SPT 2,5": (5.0, 2.3, 6.4, 0.8, 0.8, 2.5, 1, 12), "SPT 5": (7.5, 6.55, 9.3, 1.7, 0.8, 4.6, 1, 12), } # series and style: (length front to back, height above the board, back pin row from the back face, front pin row behind the back row) # SPT 1,5 horizontal: 1990740 p. 2 and p. 6: length 14.4, height 13.5 without the solder pins, rows 8.2 apart, the back row 2.53 from the back. # SPT 2,5 horizontal: 1990973 p. 3 and p. 5, 1732386 p. 2: length 14.4, height 13.5, rows 8.2 apart, the back row 2.53 from the back. # SPT 2,5 vertical: SPT 2,5/ 2-V-5,0-EX (1732496, Mar 27, 2024) Dimensions p. 3 and drilling plan p. 5: length 13.5, installed height 14.4, # rows 8.2 apart, the back row 2.75 from the back; SPT 2,5/ 3-V-5,0 (1991105) dimensional drawing p. 6 draws the same housing. # SPT 5 horizontal: 1719215 pp. 3-4: length 24.15, height 19.6, rows 13.2 apart, the back row 1.9 from the back. # SPT 5 vertical: SPT 5/ 1-V-7,5 (1719309, 13/02/2015) p. 1 and p. 5, and SPT 5/ 3-V-7,5-ZB (1719325, 10.10.2012) p. 5: length 18.5, # height 24.15, rows 14 apart, the back row 2.58 from the back. BODY = { "SPT 1,5 horizontal": (14.4, 13.5, 2.53, 8.2), "SPT 2,5 horizontal": (14.4, 13.5, 2.53, 8.2), "SPT 2,5 vertical": (13.5, 14.4, 2.75, 8.2), "SPT 5 horizontal": (24.15, 19.6, 1.9, 13.2), "SPT 5 vertical": (18.5, 24.15, 2.58, 14.0), } # Pin layouts: SPT 1,5 and SPT 2,5 have two pins per position (linear double pinning; drilling diagrams). SPT 5 ...-ZB: one pin per # position, odd positions in the back row and even ones in the front row (drilling plans of 1719215 and 1719325); SPT 5/ 1-V-7,5 # (1719309): two per position. The double-pinned SPT 5 horizontal block's drawing hasn't been read. DOUBLE = {"SPT 1,5 horizontal", "SPT 2,5 horizontal", "SPT 2,5 vertical", "SPT 5 vertical"} ZIGZAG = {"SPT 5 horizontal", "SPT 5 vertical"} key = f"{series} {style}" if series not in SERIES or key not in BODY: raise ValueError(f"no {style} {series} here: {', '.join(BODY)}") pitch, LEFT, WIDTH_ADD, PIN_W, PIN_D, PIN_LENGTH, low, high = SERIES[series] LENGTH, HEIGHT, BACK, ROWS = BODY[key] if pins == "double" and key not in DOUBLE: raise ValueError(f"{key}: only the zigzag (...-ZB) pin layout has been read") if pins == "zigzag" and key not in ZIGZAG: raise ValueError(f"{key} has two pins per position") if pins == "zigzag": low = 2 if not low <= positions <= high: raise ValueError(f"{key} comes with {low} to {high} positions") if approval == "EX" and series != "SPT 2,5": raise ValueError("the EX version is SPT 2,5") width = (positions - 1) * pitch + WIDTH_ADD x0 = -LEFT front = BACK - LENGTH # Proportions, for looks only (the drawings don't dimension them): the chamfers on the housing's top edges, the wire entry, the release # slot above (horizontal) or in front of (vertical) it, and how deep they go. CHAMFER = 0.06 * HEIGHT ENTRY = 0.62 * pitch SLOT_W = 0.5 * pitch SLOT_H = 0.16 * HEIGHT ENTRY_DEPTH = 0.55 * LENGTH SLOT_DEPTH = 0.3 * LENGTH model = Model() # The housing: its side outline in the YZ plane, extruded along +X. profile = [(front, 0), (BACK, 0), (BACK, HEIGHT - CHAMFER), (BACK - CHAMFER, HEIGHT), (front + CHAMFER, HEIGHT), (front, HEIGHT - CHAMFER)] model.plane("side_plane", on="YZ", offset=x0, name="Side") with model.sketch("body_sketch", on="side_plane", name="Housing") as sk: sk.polyline("body_outline", profile, closed=True) model.extrude("body", "body_sketch", distance=width, op="new", body="housing_body", name="Housing") if style == "horizontal": # The XZ plane's normal is -Y: offset -front puts the plane on the front face, and a negative distance cuts towards +Y. entry_z = 0.38 * HEIGHT slot_z = 0.72 * HEIGHT model.plane("front_plane", on="XZ", offset=-front, name="Front") with model.sketch("entries_sketch", on="front_plane", name="Wire entries") as sk: for i in range(positions): if series == "SPT 5": sk.rect(f"entry_{i}", (i * pitch - ENTRY / 2, entry_z - ENTRY / 2), (i * pitch + ENTRY / 2, entry_z + ENTRY / 2)) else: sk.circle(f"entry_{i}", (i * pitch, entry_z), ENTRY / 2) model.extrude("entries", "entries_sketch", distance=-ENTRY_DEPTH, op="cut", body="housing_body", name="Wire entries") with model.sketch("slots_sketch", on="front_plane", name="Release slots") as sk: for i in range(positions): sk.rect(f"slot_{i}", (i * pitch - SLOT_W / 2, slot_z - SLOT_H / 2), (i * pitch + SLOT_W / 2, slot_z + SLOT_H / 2)) model.extrude("slots", "slots_sketch", distance=-SLOT_DEPTH, op="cut", body="housing_body", name="Release slots") else: entry_y = BACK - 0.33 * LENGTH slot_y = front + 0.25 * LENGTH model.plane("top_plane", on="XY", offset=HEIGHT, name="Top") with model.sketch("entries_sketch", on="top_plane", name="Wire entries") as sk: for i in range(positions): if series == "SPT 5": sk.rect(f"entry_{i}", (i * pitch - ENTRY / 2, entry_y - ENTRY / 2), (i * pitch + ENTRY / 2, entry_y + ENTRY / 2)) else: sk.circle(f"entry_{i}", (i * pitch, entry_y), ENTRY / 2) model.extrude("entries", "entries_sketch", distance=-0.55 * HEIGHT, op="cut", body="housing_body", name="Wire entries") with model.sketch("slots_sketch", on="top_plane", name="Release slots") as sk: for i in range(positions): sk.rect(f"slot_{i}", (i * pitch - SLOT_W / 2, slot_y - 0.16 * LENGTH / 2), (i * pitch + SLOT_W / 2, slot_y + 0.16 * LENGTH / 2)) model.extrude("slots", "slots_sketch", distance=-0.3 * HEIGHT, op="cut", body="housing_body", name="Release slots") # Contacts: each position's solder pins and the bar joining them inside the housing's floor are one solid. The bar is a proportion # (BAR_W x BAR_T, from the back pin to the front pin's row), standing for the current bar and spring the sections draw, so that the # mass comes out near the data sheets' weights. BAR_W = 0.5 * pitch BAR_T = 1.0 bar_y = (-ROWS - PIN_D / 2, PIN_D / 2) with model.sketch("bars_sketch", on="XY", name="Contact bars") as sk: for i in range(positions): sk.rect(f"bar_cut_{i}", (i * pitch - BAR_W / 2, bar_y[0]), (i * pitch + BAR_W / 2, bar_y[1])) model.extrude("bar_room", "bars_sketch", distance=BAR_T, op="cut", body="housing_body", name="Room for the contacts") model.plane("pin_plane", on="XY", offset=-PIN_LENGTH, name="Solder pins") contacts = [] for i in range(positions): rows = [0.0, -ROWS] if pins == "double" else [0.0 if i % 2 == 0 else -ROWS] with model.sketch(f"pins_{i}_sketch", on="pin_plane", name=f"Solder pins {i + 1}") as sk: for j, y in enumerate(rows): sk.rect(f"pin_{i}_{j}", (i * pitch - PIN_W / 2, y - PIN_D / 2), (i * pitch + PIN_W / 2, y + PIN_D / 2)) model.extrude(f"pins_{i}", f"pins_{i}_sketch", distance=PIN_LENGTH + BAR_T / 2, op="new", body=f"contact_{i}_body", name=f"Solder pins {i + 1}") model.box(f"bar_{i}", BAR_W, bar_y[1] - bar_y[0], BAR_T, at=(i * pitch, (bar_y[0] + bar_y[1]) / 2, BAR_T / 2), op="join", body=f"contact_{i}_body", name=f"Contact bar {i + 1}") contacts.append(f"contact_{i}_body") # Materials: the housing is PA, green RAL 6021 (data sheets); the contacts copper alloy, tin plated. model.material("pa6", bodies=["housing_body"], color="#89ac76") model.material("copper", bodies=contacts, color="#c9cbc8") result = model.result()