// ============================================================ // antenna_mount.scad — LTE + GNSS Antenna Brackets Rev A // 2026-03-01 sl-mechanical // ============================================================ // Stem-mounted brackets for the SIM7600X cellular/GPS system. // // lte_bracket() 25 mm stem clamp + arm with 2× SMA // bulkhead holes (LTE main + diversity). // Antennas point skyward. // // gnss_platform() 25 mm stem clamp + upward-facing tray // for active GNSS patch antenna (≤40×40 mm). // // Recommended stem positions (above base plate): // LTE bracket 500–600 mm (above battery carousel) // GNSS platform 750–800 mm (below sensor head, clear sky) // // Both use the same split-collar design: // M4 clamping bolts + M4 set screw (height lock). // Cable-tie slot on rear half for u.FL pigtail management. // // u.FL → SMA pigtail cables route down stem to SIM7600X HAT. // // ⚠ VERIFY: MAWB_HOLE_X / MAWB_HOLE_Y for any M2.5 pattern // SMA_D for your SMA bulkhead thread OD // // RENDER options: // "lte_assembly" LTE bracket view (default) // "lte_front" LTE collar front half for slicing // "lte_rear" LTE collar rear half // "lte_arm" LTE SMA arm for slicing (print flat) // "gnss_assembly" GNSS platform view // "gnss_front" GNSS collar front half // "gnss_rear" GNSS collar rear half // "gnss_tray" GNSS patch-antenna tray for slicing // "full_stem" both brackets on 400 mm stem stub // ============================================================ RENDER = "lte_assembly"; // ── Stem ───────────────────────────────────────────────────── STEM_OD = 25.0; STEM_BORE = 25.4; // +0.4 clearance // ── Collar (shared) ────────────────────────────────────────── COL_OD = 52.0; COL_H = 28.0; COL_BOLT_X = 19.0; // M4 clamping bolt CL from stem axis COL_BOLT_D = 4.5; // M4 clearance hole COL_NUT_W = 7.0; // M4 hex nut A/F COL_NUT_H = 3.4; // Cable-tie slot on rear half outer face (for pigtail routing) TIE_W = 5.0; TIE_D = 3.0; TIE_Z1 = COL_H * 0.35; TIE_Z2 = COL_H * 0.70; // ── LTE SMA arm ────────────────────────────────────────────── // 2× SMA bulkhead connectors pointing skyward SMA_D = 6.6; // SMA bulkhead clearance hole (6.35 mm thread) SMA_NUT_AF = 10.2; // SMA hex-nut capture across-flats SMA_NUT_H = 4.5; // hex-nut pocket depth (bottom of arm) SMA_SPACING = 22.0; // centre-to-centre between 2 SMA positions LTE_ARM_L = 40.0; // arm length (from collar OD to SMA CL) LTE_ARM_W = SMA_SPACING + 18.0; // arm width LTE_ARM_H = 9.0; // arm thickness LTE_SMA_Y = LTE_ARM_L * 0.65; // SMA position along arm // Pigtail cable relief (semi-circular groove on arm underside) PIGTAIL_D = 4.5; // M3 attachment bolts (arm → collar boss) M3_D = 3.3; // ── GNSS patch-antenna tray ─────────────────────────────────── GNSS_PATCH = 40.0; // maximum patch antenna side (fits 25, 35, 40 mm) GNSS_LIP_T = 2.2; // lip wall thickness GNSS_LIP_H = 3.0; // lip height above tray surface GNSS_TRAY_T = 3.0; // tray base thickness // Optional M2 bolt-down pattern for larger patch antennas GNSS_M2_SP = 30.0; // M2 spacing (verify with your patch antenna) M2_D = 2.2; // Coax cable slot (centre of tray, through base) GNSS_COAX_W = 5.5; // Arm connecting tray to collar GNSS_ARM_L = 28.0; GNSS_ARM_W = 22.0; GNSS_ARM_H = 7.0; // Spacing between LTE and GNSS collars on stem STEM_SPACING = 80.0; $fn = 64; e = 0.01; // ───────────────────────────────────────────────────────────── // collar_half(side, arm_type) // arm_type: "lte" | "gnss" | "none" // Print flat-face-down. // ───────────────────────────────────────────────────────────── module collar_half(side="front", arm_type="lte") { y_front = (side == "front"); has_arm = y_front && (arm_type != "none"); arm_w = (arm_type == "lte") ? LTE_ARM_W : GNSS_ARM_W; arm_l = (arm_type == "lte") ? LTE_ARM_L : GNSS_ARM_L; arm_h = (arm_type == "lte") ? LTE_ARM_H : GNSS_ARM_H; arm_z = COL_H/2 - arm_h/2; difference() { union() { // D-shaped collar half intersection() { cylinder(d=COL_OD, h=COL_H); translate([-COL_OD/2, y_front ? 0 : -COL_OD/2, 0]) cube([COL_OD, COL_OD/2, COL_H]); } // Arm boss integrated into front half if (has_arm) translate([-arm_w/2, COL_OD/2, arm_z]) cube([arm_w, arm_l, arm_h]); } // Stem bore translate([0, 0, -e]) cylinder(d=STEM_BORE, h=COL_H + 2*e); // M4 clamping bolt holes (Y direction) for (bx=[-COL_BOLT_X, COL_BOLT_X]) translate([bx, y_front ? COL_OD/2 : 0, COL_H/2]) rotate([90,0,0]) cylinder(d=COL_BOLT_D, h=COL_OD/2 + e); // M4 hex nut pockets (rear half only) if (!y_front) for (bx=[-COL_BOLT_X, COL_BOLT_X]) translate([bx, -(COL_OD/4 + e), COL_H/2]) rotate([90,0,0]) cylinder(d=COL_NUT_W/cos(30), h=COL_NUT_H+e, $fn=6); // M4 set screw (height lock, front half outer face) if (y_front) translate([0, COL_OD/2, COL_H * 0.75]) rotate([90,0,0]) cylinder(d=COL_BOLT_D, h=COL_OD/2 - STEM_BORE/2 + e); // Cable-tie grooves on rear half outer surface (2×) if (!y_front) for (tz=[TIE_Z1, TIE_Z2]) translate([-COL_OD/2 - e, -TIE_W/2, tz]) cube([TIE_D + e, TIE_W, TIE_W]); // M3 attachment holes through arm boss (2×) if (has_arm) for (dx=[-arm_w/4, arm_w/4]) translate([dx, COL_OD/2 + arm_l * 0.45, arm_z - e]) cylinder(d=M3_D, h=arm_h + 2*e); } } // ───────────────────────────────────────────────────────────── // lte_sma_arm() // Separate arm piece bolts to collar front boss. // 2× SMA bulkheads point upward. Pigtail grooves on underside. // Print: lay flat on bottom face. // ───────────────────────────────────────────────────────────── module lte_sma_arm() { difference() { translate([-LTE_ARM_W/2, 0, 0]) cube([LTE_ARM_W, LTE_ARM_L, LTE_ARM_H]); // 2× SMA bulkhead through-holes (vertical) for (dx=[-SMA_SPACING/2, SMA_SPACING/2]) { translate([dx, LTE_SMA_Y, -e]) cylinder(d=SMA_D, h=LTE_ARM_H + 2*e); // Hex-nut pocket from bottom face translate([dx, LTE_SMA_Y, -e]) cylinder(d=SMA_NUT_AF/cos(30), h=SMA_NUT_H + e, $fn=6); } // u.FL pigtail relief grooves on underside for (dx=[-SMA_SPACING/2, SMA_SPACING/2]) translate([dx, 0, -e]) rotate([0, 0, 0]) linear_extrude(PIGTAIL_D/2 + e) translate([0, LTE_ARM_L/2]) circle(d=PIGTAIL_D); // M3 attachment holes (collar boss) for (dx=[-LTE_ARM_W/4, LTE_ARM_W/4]) translate([dx, LTE_ARM_L * 0.45, -e]) cylinder(d=M3_D, h=LTE_ARM_H + 2*e); } } // ───────────────────────────────────────────────────────────── // gnss_tray() // Horizontal tray faces skyward. Retention lip on all 4 sides. // Central coax slot + optional M2 bolt holes. // Print: top face on bed (tray upside-down → no supports needed). // ───────────────────────────────────────────────────────────── module gnss_tray() { outer = GNSS_PATCH + 2 * GNSS_LIP_T; difference() { union() { // Base plate translate([-outer/2, 0, 0]) cube([outer, outer, GNSS_TRAY_T]); // Retention lip (4 walls) translate([-outer/2, 0, GNSS_TRAY_T]) difference() { cube([outer, outer, GNSS_LIP_H]); translate([GNSS_LIP_T, GNSS_LIP_T, -e]) cube([GNSS_PATCH, GNSS_PATCH, GNSS_LIP_H + 2*e]); } // Arm connecting to collar translate([-GNSS_ARM_W/2, -GNSS_ARM_L, 0]) cube([GNSS_ARM_W, GNSS_ARM_L, GNSS_ARM_H]); } // GNSS coax cable slot (centre, through base) translate([-GNSS_COAX_W/2, outer/2 - GNSS_COAX_W/2, -e]) cube([GNSS_COAX_W, GNSS_COAX_W, GNSS_TRAY_T + 2*e]); // M2 bolt-down holes (30×30 mm pattern, centred in tray) tray_cx = 0; tray_cy = outer/2; for (dx=[-GNSS_M2_SP/2, GNSS_M2_SP/2]) for (dy=[-GNSS_M2_SP/2, GNSS_M2_SP/2]) translate([tray_cx + dx, tray_cy + dy, -e]) cylinder(d=M2_D, h=GNSS_TRAY_T + 2*e); // M3 bolt holes (arm → collar) for (dx=[-GNSS_ARM_W/4, GNSS_ARM_W/4]) translate([dx, -GNSS_ARM_L * 0.45, -e]) cylinder(d=M3_D, h=GNSS_ARM_H + 2*e); } } // ───────────────────────────────────────────────────────────── // lte_bracket_assembly() / gnss_bracket_assembly() // ───────────────────────────────────────────────────────────── module lte_bracket_assembly() { color("SteelBlue", 0.9) collar_half("front", "lte"); color("CornflowerBlue", 0.9) mirror([0,1,0]) collar_half("rear", "none"); color("LightSteelBlue", 0.85) translate([0, COL_OD/2, COL_H/2 - LTE_ARM_H/2]) lte_sma_arm(); // Phantom SMA stub antennas for (dx=[-SMA_SPACING/2, SMA_SPACING/2]) color("DimGray", 0.5) translate([dx, COL_OD/2 + LTE_SMA_Y, COL_H/2 + LTE_ARM_H/2]) cylinder(d=7, h=60); } module gnss_bracket_assembly() { color("Teal", 0.9) collar_half("front", "gnss"); color("DarkCyan", 0.9) mirror([0,1,0]) collar_half("rear", "none"); // Tray: arm at Y−, tray faces +Z color("LightCyan", 0.85) translate([0, COL_OD/2 + GNSS_ARM_L, COL_H/2 - GNSS_ARM_H/2]) rotate([90, 0, 0]) gnss_tray(); // Phantom GNSS patch color("Gold", 0.35) translate([-GNSS_PATCH/2, COL_OD/2 + GNSS_ARM_L + GNSS_LIP_T, COL_H/2 + GNSS_ARM_H/2 + GNSS_TRAY_T]) cube([GNSS_PATCH, GNSS_PATCH, 8]); } // ───────────────────────────────────────────────────────────── // Render selector // ───────────────────────────────────────────────────────────── if (RENDER == "lte_assembly") { lte_bracket_assembly(); } else if (RENDER == "lte_front") { collar_half("front", "lte"); } else if (RENDER == "lte_rear") { collar_half("rear", "none"); } else if (RENDER == "lte_arm") { translate([0, 0, LTE_ARM_H]) rotate([180,0,0]) lte_sma_arm(); } else if (RENDER == "gnss_assembly") { gnss_bracket_assembly(); } else if (RENDER == "gnss_front") { collar_half("front", "gnss"); } else if (RENDER == "gnss_rear") { collar_half("rear", "none"); } else if (RENDER == "gnss_tray") { gnss_tray(); } else if (RENDER == "full_stem") { color("Silver", 0.2) translate([0,0,-40]) cylinder(d=STEM_OD, h=STEM_SPACING + COL_H + 80); lte_bracket_assembly(); translate([0, 0, STEM_SPACING]) gnss_bracket_assembly(); }