// ============================================================ // vesc_mount.scad — FSESC 6.7 Pro Mini Dual ESC Mount Cradle // Issue #699 / sl-mechanical 2026-03-17 // ============================================================ // Open-top tray for Flipsky FSESC 6.7 Pro Mini Dual (~100 × 68 × 28 mm). // Attaches to 2020 aluminium T-slot rail via 4× M5 T-nuts // (2× per rail, two parallel rails, 60 mm bolt spacing in X, // 20 mm bolt spacing in Y matching 2020 slot pitch). // // Connector access: // XT60 battery inputs — X− end wall cutouts (2 connectors, side-by-side) // XT30 motor outputs — Y+ and Y− side wall cutouts (2 per side wall) // CAN/UART terminal — X+ end wall cutout (screw terminal, wire exit) // // Ventilation: // Open top face — heatsink fins fully exposed // Floor grille slots — under-board airflow // Side vent louvres — 4 slots on each Y± wall at heatsink height // // Retention: 4× M3 heat-set insert boss in floor — board screws down through // ESC mounting holes via M3×8 FHCS. Board sits on 4 mm raised posts for // under-board airflow. // // ⚠ VERIFY WITH CALIPERS BEFORE PRINTING: // PCB_L, PCB_W board outline // XT60_W, XT60_H XT60 shell at X− edge // XT30_W, XT30_H XT30 shells at Y± edges // TERM_W, TERM_H CAN screw terminal at X+ edge // MOUNT_X1/X2, MOUNT_Y1/Y2 ESC board mounting hole pattern // // Print settings (PETG): // 3 perimeters, 40 % gyroid infill, no supports, 0.2 mm layer // Print orientation: open face UP (as modelled) // // BOM: // 4 × M5×10 BHCS + 4 × M5 slide-in T-nut (2020 rail) // 4 × M3 heat-set insert (Voron-style, OD 4.5 mm × 4 mm deep) // 4 × M3×8 FHCS (board retention) // // Export commands: // openscad -D 'RENDER="mount"' -o vesc_mount.stl vesc_mount.scad // openscad -D 'RENDER="assembly"' -o vesc_assembly.png vesc_mount.scad // ============================================================ RENDER = "assembly"; // mount | assembly $fn = 48; EPS = 0.01; // ── ⚠ Verify before printing ───────────────────────────────── // FSESC 6.7 Pro Mini Dual PCB PCB_L = 100.0; // board length (X: XT60 end → CAN terminal end) PCB_W = 68.0; // board width (Y) PCB_T = 2.0; // board thickness (incl. bottom-side components) COMP_H = 26.0; // tallest component above board top face (heatsink ~26 mm) // XT60 battery connectors at X− end (2 connectors, side-by-side) XT60_W = 16.0; // each XT60 shell width (Y) XT60_H = 16.0; // each XT60 shell height (Z) above board surface XT60_Z0 = 0.0; // connector bottom offset above board surface // Y centres of each XT60 measured from PCB Y− edge XT60_Y1 = 16.0; XT60_Y2 = 52.0; // XT30 motor output connectors at Y± sides (2 per side) XT30_W = 10.5; // each XT30 shell width (X span) XT30_H = 12.0; // each XT30 shell height (Z) above board surface XT30_Z0 = 0.5; // connector bottom offset above board surface // X centres measured from PCB X− edge (same layout both Y− and Y+ sides) XT30_X1 = 22.0; XT30_X2 = 78.0; // CAN / UART screw terminal block at X+ end (3-pos 3.5 mm pitch) TERM_W = 14.0; // terminal block Y span TERM_H = 10.0; // terminal block height above board surface TERM_Z0 = 0.5; // terminal bottom offset above board surface TERM_Y_CTR = PCB_W / 2; // ── ESC board mounting hole pattern ────────────────────────── // 4 corner holes, 4 mm inset from each PCB edge MOUNT_INSET = 4.0; MOUNT_X1 = MOUNT_INSET; MOUNT_X2 = PCB_L - MOUNT_INSET; MOUNT_Y1 = MOUNT_INSET; MOUNT_Y2 = PCB_W - MOUNT_INSET; M3_INSERT_OD = 4.6; // Voron M3 heat-set insert press-fit OD M3_INSERT_H = 4.0; // insert depth M3_CLEAR_D = 3.4; // M3 clearance bore below insert // ── Cradle geometry ────────────────────────────────────────── WALL_T = 2.8; // side / end wall thickness FLOOR_T = 4.5; // floor plate thickness (fits M5 BHCS head pocket) POST_H = 4.0; // standoff post height (board lifts off floor for airflow) CL_SIDE = 0.35; // Y clearance per side CL_END = 0.40; // X clearance per end INN_W = PCB_W + 2*CL_SIDE; INN_L = PCB_L + 2*CL_END; INN_H = POST_H + PCB_T + COMP_H + 1.5; OTR_W = INN_W + 2*WALL_T; OTR_L = INN_L + 2*WALL_T; OTR_H = FLOOR_T + INN_H; PCB_X0 = WALL_T + CL_END; PCB_Y0 = WALL_T + CL_SIDE; PCB_Z0 = FLOOR_T + POST_H; // ── M5 T-nut mount (2020 rail) ──────────────────────────────── // 4 bolts: 2 columns (X) × 2 rows (Y), centred on body M5_D = 5.3; M5_HEAD_D = 9.5; M5_HEAD_H = 3.0; M5_SPAC_X = 60.0; // X bolt spacing M5_SPAC_Y = 20.0; // Y bolt spacing (2020 T-slot pitch) // ── Floor ventilation grille ────────────────────────────────── GRILLE_SLOT_W = 4.0; GRILLE_SLOT_T = FLOOR_T - 1.5; GRILLE_PITCH = 10.0; GRILLE_X0 = WALL_T + 14; GRILLE_X_LEN = OTR_L - 2*WALL_T - 28; GRILLE_N = floor((INN_W - 10) / GRILLE_PITCH); // ── Side vent louvres on Y± walls ──────────────────────────── LOUV_H = 5.0; LOUV_W = 12.0; LOUV_Z = FLOOR_T + POST_H + PCB_T + 4.0; // mid-heatsink height LOUV_N = 4; LOUV_PITCH = (OTR_L - 2*WALL_T - 20) / max(LOUV_N - 1, 1); // ── CAN wire strain relief bosses (X+ end) ─────────────────── SR_BOSS_OD = 7.0; SR_BOSS_H = 6.0; SR_SLOT_W = 3.5; SR_SLOT_T = 2.2; SR_Y1 = WALL_T + INN_W * 0.25; SR_Y2 = WALL_T + INN_W * 0.75; SR_X = OTR_L - WALL_T - SR_BOSS_OD/2 - 2.5; // ───────────────────────────────────────────────────────────── module m3_insert_boss() { // Solid post with heat-set insert bore from top post_h = FLOOR_T + POST_H; difference() { cylinder(d = M3_INSERT_OD + 3.2, h = post_h); // Insert bore from top translate([0, 0, post_h - M3_INSERT_H]) cylinder(d = M3_INSERT_OD, h = M3_INSERT_H + EPS); // Clearance bore from bottom translate([0, 0, -EPS]) cylinder(d = M3_CLEAR_D, h = post_h - M3_INSERT_H + EPS); } } module vesc_mount() { difference() { union() { // Main body cube([OTR_L, OTR_W, OTR_H]); // M3 insert bosses at board mounting corners for (mx = [MOUNT_X1, MOUNT_X2]) for (my = [MOUNT_Y1, MOUNT_Y2]) translate([PCB_X0 + mx, PCB_Y0 + my, 0]) m3_insert_boss(); // CAN strain relief bosses on X+ end for (sy = [SR_Y1, SR_Y2]) translate([SR_X, sy, 0]) cylinder(d = SR_BOSS_OD, h = SR_BOSS_H); } // ── Interior cavity (open top) ───────────────────────── translate([WALL_T, WALL_T, FLOOR_T]) cube([INN_L, INN_W, INN_H + EPS]); // ── XT60 cutouts at X− end (2 connectors) ────────────── for (yc = [XT60_Y1, XT60_Y2]) translate([-EPS, PCB_Y0 + yc - (XT60_W + 2.0)/2, PCB_Z0 + XT60_Z0 - 0.5]) cube([WALL_T + 2*EPS, XT60_W + 2.0, XT60_H + 3.0]); // ── XT30 cutouts at Y− side (2 connectors) ───────────── for (xc = [XT30_X1, XT30_X2]) translate([PCB_X0 + xc - (XT30_W + 2.0)/2, -EPS, PCB_Z0 + XT30_Z0 - 0.5]) cube([XT30_W + 2.0, WALL_T + 2*EPS, XT30_H + 3.0]); // ── XT30 cutouts at Y+ side (2 connectors) ───────────── for (xc = [XT30_X1, XT30_X2]) translate([PCB_X0 + xc - (XT30_W + 2.0)/2, OTR_W - WALL_T - EPS, PCB_Z0 + XT30_Z0 - 0.5]) cube([XT30_W + 2.0, WALL_T + 2*EPS, XT30_H + 3.0]); // ── CAN terminal cutout at X+ end ────────────────────── translate([OTR_L - WALL_T - EPS, PCB_Y0 + TERM_Y_CTR - (TERM_W + 3.0)/2, PCB_Z0 + TERM_Z0 - 0.5]) cube([WALL_T + 2*EPS, TERM_W + 3.0, TERM_H + 5.0]); // ── Floor ventilation grille ─────────────────────────── for (i = [0 : GRILLE_N - 1]) { sy = WALL_T + 5 + i * GRILLE_PITCH; translate([GRILLE_X0, sy, -EPS]) cube([GRILLE_X_LEN, GRILLE_SLOT_W, GRILLE_SLOT_T + EPS]); } // ── Side vent louvres — Y− wall ──────────────────────── for (i = [0 : LOUV_N - 1]) { lx = WALL_T + 10 + i * LOUV_PITCH; translate([lx, -EPS, LOUV_Z]) cube([LOUV_W, WALL_T + 2*EPS, LOUV_H]); } // ── Side vent louvres — Y+ wall ──────────────────────── for (i = [0 : LOUV_N - 1]) { lx = WALL_T + 10 + i * LOUV_PITCH; translate([lx, OTR_W - WALL_T - EPS, LOUV_Z]) cube([LOUV_W, WALL_T + 2*EPS, LOUV_H]); } // ── M5 BHCS head pockets (4 bolts, bottom face) ──────── for (mx = [OTR_L/2 - M5_SPAC_X/2, OTR_L/2 + M5_SPAC_X/2]) for (my = [OTR_W/2 - M5_SPAC_Y/2, OTR_W/2 + M5_SPAC_Y/2]) translate([mx, my, -EPS]) { cylinder(d = M5_D, h = FLOOR_T + 2*EPS); cylinder(d = M5_HEAD_D, h = M5_HEAD_H + EPS); } // ── Zip-tie slots through CAN strain relief bosses ───── for (sy = [SR_Y1, SR_Y2]) translate([SR_X, sy, SR_BOSS_H/2 - SR_SLOT_T/2]) rotate([0, 90, 0]) cube([SR_SLOT_T, SR_SLOT_W, SR_BOSS_OD + 2*EPS], center = true); // ── Weight-relief pocket in floor underside ───────────── translate([WALL_T + 16, WALL_T + 6, -EPS]) cube([OTR_L - 2*WALL_T - 32, OTR_W - 2*WALL_T - 12, FLOOR_T - 2.0 + EPS]); } } // ── Assembly preview ───────────────────────────────────────── if (RENDER == "assembly") { color("DimGray", 0.93) vesc_mount(); // Phantom PCB color("ForestGreen", 0.30) translate([PCB_X0, PCB_Y0, PCB_Z0]) cube([PCB_L, PCB_W, PCB_T]); // Phantom heatsink / component block color("SlateGray", 0.22) translate([PCB_X0, PCB_Y0, PCB_Z0 + PCB_T]) cube([PCB_L, PCB_W, COMP_H]); // XT60 connector highlights (X− end) for (yc = [XT60_Y1, XT60_Y2]) color("Gold", 0.85) translate([-2, PCB_Y0 + yc - XT60_W/2, PCB_Z0 + XT60_Z0]) cube([WALL_T + 3, XT60_W, XT60_H]); // XT30 connector highlights — Y− side for (xc = [XT30_X1, XT30_X2]) color("OrangeRed", 0.80) translate([PCB_X0 + xc - XT30_W/2, -2, PCB_Z0 + XT30_Z0]) cube([XT30_W, WALL_T + 3, XT30_H]); // XT30 connector highlights — Y+ side for (xc = [XT30_X1, XT30_X2]) color("OrangeRed", 0.80) translate([PCB_X0 + xc - XT30_W/2, OTR_W - WALL_T - 1, PCB_Z0 + XT30_Z0]) cube([XT30_W, WALL_T + 3, XT30_H]); // CAN terminal highlight color("Tomato", 0.75) translate([OTR_L - WALL_T - 1, PCB_Y0 + TERM_Y_CTR - TERM_W/2, PCB_Z0 + TERM_Z0]) cube([WALL_T + 3, TERM_W, TERM_H]); } else { vesc_mount(); }