// ============================================================ // gopro_mount.scad — GoPro 3-Prong T-Slot Sensor Rail Mount // Issue: #195 Agent: sl-mechanical Date: 2026-03-02 // ============================================================ // // Universal GoPro camera mount for sensor_rail.scad (T-slot 2020). // // Top interface: Standard GoPro 3-prong (HERO 5+) // Prongs slide into standard GoPro accessories. // No additional clips or fasteners needed. // // Bottom clamp: T-slot 20×20 mm rail system (OpenBuilds compatible). // M3 thumbscrew retention + M5 index holes for 15° detents. // // Tilt mechanism: Rotating hinge bracket allows camera tilt 0°–90° from // horizontal, locked at 15° increments via index holes. // Rotation axis is perpendicular to rail (about Y-axis). // // Assembly: // 1. Print gopro_mount_base (single part, flat-side-down, no supports) // 2. Slide built-in T-nut into rail T-groove // 3. Clamp with M3 thumbscrew from outside rail face // 4. Rotate camera to desired tilt angle (0°, 15°, 30°, ... 90°) // 5. Insert M5 alignment pin to lock tilt // // RENDER options: // "mount" assembled mount view (default) // "base_stl" base clamp for slicing (print flat) // "camera_bracket" rotatable camera bracket for slicing // ============================================================ RENDER = "mount"; // ── GoPro 3-prong interface (top) ────────────────────────── // Standard GoPro HERO 5+ 3-prong attachment point. // Overall footprint ~43×25 mm, 3 prongs slide into camera mounting slot. GOPRO_WIDTH = 43.0; // front-to-back along camera face GOPRO_DEPTH = 25.0; // left-to-right width GOPRO_PRONG_H = 5.0; // height of prongs above base GOPRO_PRONG_D = 4.0; // diameter/thickness of each prong GOPRO_PRONG_SP = 14.0; // spacing between outer prongs (centre-to-centre) // Centre prong is at Y=0; outer prongs at Y±GOPRO_PRONG_SP/2 // Prongs extend upward (+Z direction) // ── T-slot clamp (bottom) ────────────────────────────────── // Matches sensor_rail.scad T-slot 2020 dimensions. RAIL_W = 20.0; // rail outer width/height SLOT_INNER_W = 10.2; // T-groove inner width SLOT_INNER_H = 5.8; // T-groove inner height (depth) SLOT_NECK_H = 3.2; // distance from outer face to T-groove TNUT_W = 9.8; // printable T-nut width (SLOT_INNER_W - 0.4) TNUT_H = 5.5; // printable T-nut height (SLOT_INNER_H - 0.3) TNUT_L = 12.0; // T-nut body length TNUT_BOLT_D = 3.3; // M3 clearance bore through T-nut THUMB_D = 16.0; // thumbwheel OD (visual only) THUMB_H = 8.0; // thumbwheel height // Index hole pitch for tilt detents INDEX_PITCH = 25.0; // 25 mm spacing on rail TILT_ANGLE_STEP = 15.0; // 15° tilt detents (0°, 15°, 30°, ... 90°) M5_INDEX_D = 5.3; // M5 clearance hole diameter // ── Rotation/tilt mechanism ─────────────────────────────── // Camera bracket rotates about Y-axis relative to base. // Rotation axis is at the rail clamp interface (Z=0, Y=0). // Tilt range: 0° to 90°. MAX_TILT_DEG = 90.0; // maximum tilt angle // Hinge pin: M5 bolt passes through base and camera bracket HINGE_PIN_D = 5.3; // M5 bolt clearance HINGE_PIN_L = 25.0; // pin length (accommodates rail width + brackets) // ── General ──────────────────────────────────────────────── $fn = 64; e = 0.01; // ───────────────────────────────────────────────────────────── // gopro_mount_base() // T-slot clamp bracket with integrated T-nut. // Mounted at bottom, rail clamp at Z=0 face. // Hinge pin axis at Y=0, rotates camera bracket ±X. // // Print: flat-side-down (rail face down), no supports needed. // ───────────────────────────────────────────────────────────── module gopro_mount_base() { clamp_h = RAIL_W + 8.0; // total clamp height clamp_w = TNUT_L + 8.0; // clamp width (along rail) clamp_d = 18.0; // clamp depth (front-to-back) difference() { union() { // Main clamp body translate([-clamp_w/2, -clamp_d/2, 0]) cube([clamp_w, clamp_d, clamp_h]); // T-nut integration: slot to hold T-nut at rail interface // T-nut sits in T-groove when rail is inserted from above translate([-TNUT_L/2, -TNUT_W/2, SLOT_NECK_H]) cube([TNUT_L, TNUT_W, TNUT_H]); // Hinge boss (supports rotation axis pin) translate([-HINGE_PIN_L/2 - 2, -8, clamp_h - 4]) cube([HINGE_PIN_L + 4, 4, 4]); } // Rail bore (25.4 mm) — matches stem adapter pattern // When rail is vertical, this bore slides onto rail extrusion translate([0, 0, -e]) cylinder(d=RAIL_W + 0.4, h=clamp_h + 2*e); // T-nut through-bolt (M3 thumbscrew hole) // Bolt comes from outside rail face, through T-nut, clamping it translate([0, 0, SLOT_NECK_H + TNUT_H/2]) rotate([90, 0, 0]) cylinder(d=TNUT_BOLT_D, h=clamp_d + 2*e); // Hinge pin (M5) passes through base to camera bracket translate([-HINGE_PIN_L/2, 0, clamp_h - 2]) rotate([0, 90, 0]) cylinder(d=HINGE_PIN_D, h=HINGE_PIN_L + 2*e); // Index hole pockets for tilt angle lock (M5) // One index hole on each side to lock camera tilt for (angle = [0 : TILT_ANGLE_STEP : MAX_TILT_DEG]) { // Holes are radially spaced around the hinge axis y_offset = (HINGE_PIN_L/2 - 2) * sin(angle); z_offset = clamp_h - 2 - (HINGE_PIN_L/2 - 2) * (1 - cos(angle)); translate([0, y_offset, z_offset]) cylinder(d=M5_INDEX_D, h=4, center=false); } // Vent slots (optional, aesthetic + weight reduction) for (dz = [4, 8, 12]) translate([-clamp_w/2 + 2, -clamp_d/2 - e, dz]) cube([clamp_w - 4, 2, 1.5]); } } // ───────────────────────────────────────────────────────────── // gopro_camera_bracket() // Rotatable bracket that holds GoPro camera via 3-prong mount. // Rotates about Y-axis (hinge pin), tilt 0°–90°. // // Hinge pin (M5 bolt) enters from base and locks bracket rotation. // Index hole on bracket aligns with base index holes at each 15° step. // // Print: flat-side-down (prong face down), no supports. // ───────────────────────────────────────────────────────────── module gopro_camera_bracket() { bracket_h = GOPRO_WIDTH + 8.0; // height when vertical bracket_w = GOPRO_DEPTH + 6.0; // width (left-right) bracket_t = 4.0; // bracket thickness difference() { union() { // Main bracket body translate([-bracket_w/2, -bracket_t/2, 0]) cube([bracket_w, bracket_t, bracket_h]); // Hinge pivot boss translate([-HINGE_PIN_L/2 - 2, 0, bracket_h - 4]) cube([HINGE_PIN_L + 4, bracket_t, 4]); // GoPro prong mounting boss translate([-GOPRO_DEPTH/2, 0, bracket_h - GOPRO_WIDTH/2]) cube([GOPRO_DEPTH, bracket_t + 2, GOPRO_WIDTH]); } // Hinge pin bore (M5) translate([-HINGE_PIN_L/2, 0, bracket_h - 2]) rotate([0, 90, 0]) cylinder(d=HINGE_PIN_D + 0.2, h=HINGE_PIN_L + 2*e); // Index hole (M5) for angle lock // Bracket has one index hole that aligns with base holes at tilt angles translate([GOPRO_DEPTH/2 + 1, 0, bracket_h - 4]) cylinder(d=M5_INDEX_D, h=bracket_t + 2*e); // GoPro prong socket (3 mounting prongs) // Centre prong at Y=0, outer prongs at Y±GOPRO_PRONG_SP/2 for (dy = [0, GOPRO_PRONG_SP/2, -GOPRO_PRONG_SP/2]) { translate([0, bracket_t + e, bracket_h - GOPRO_WIDTH/2 + 5 - dy]) rotate([90, 0, 0]) cylinder(d=GOPRO_PRONG_D + 0.4, h=4); } } } // ───────────────────────────────────────────────────────────── // gopro_prong_interface() // Visual representation of the 3 prongs that camera mounts to. // Not printed; shown during assembly view. // ───────────────────────────────────────────────────────────── module gopro_prong_interface() { bracket_h = GOPRO_WIDTH + 8.0; bracket_w = GOPRO_DEPTH + 6.0; // 3 cylindrical prongs for (dy = [0, GOPRO_PRONG_SP/2, -GOPRO_PRONG_SP/2]) { translate([0, bracket_w/2 + 0.5, bracket_h - GOPRO_WIDTH/2 + 5 - dy]) rotate([90, 0, 0]) cylinder(d=GOPRO_PRONG_D, h=GOPRO_PRONG_H, $fn=32); } } // ───────────────────────────────────────────────────────────── // Assembly view: base + rotatable camera bracket // ───────────────────────────────────────────────────────────── module gopro_mount_assembly() { // Base clamp (fixed) color("SteelBlue", 0.9) gopro_mount_base(); // Camera bracket (rotatable, at 45° tilt for visualization) color("CornflowerBlue", 0.85) rotate([0, 45, 0]) translate([0, 0, RAIL_W + 8]) gopro_camera_bracket(); // Visual GoPro prongs color("LightSteelBlue", 0.7) rotate([0, 45, 0]) translate([0, 0, RAIL_W + 8]) gopro_prong_interface(); // Phantom M5 hinge pin (visual reference) color("Silver", 0.5) translate([-HINGE_PIN_L/2, 0, RAIL_W + 8 - 2]) rotate([0, 90, 0]) cylinder(d=5, h=HINGE_PIN_L); } // ───────────────────────────────────────────────────────────── // Render selector // ───────────────────────────────────────────────────────────── if (RENDER == "mount") { gopro_mount_assembly(); } else if (RENDER == "base_stl") { // Flat print orientation: rail-facing side down rotate([180, 0, 0]) translate([0, 0, -RAIL_W - 8]) gopro_mount_base(); } else if (RENDER == "camera_bracket") { // Flat print orientation: prong-facing side down rotate([0, 0, 0]) translate([0, 0, GOPRO_WIDTH + 14]) rotate([180, 0, 0]) gopro_camera_bracket(); }