// Detail of the part $fn = 50; // Minimum thickness of anything min_thickness = 1.2; // Tolerance for inside gaps tol = 0.1; // Part to generate part = "m"; // [m: Main Body, t:Top] module hide_params() {} function inch(x) = x * 25.4; jr_upper_width = inch(1 + 3 / 4); jr_upper_depth = inch(2 + 3 / 8); jr_lower_width = inch(1 + 23 / 32); jr_lower_depth = inch(2 + 11 / 32); connector_hole_width = inch(7 / 64); connector_hole_depth = inch(15 / 32); connector_right_x_offset = inch(3 / 16); connector_bottom_y_offset = inch(1 / 8); jr_height = inch(3 / 4); rim_width = 2; rim_height = 2; chamfer_d = 2; top_interference = 1; latch_width = 1.8; latch_depth = 9 / 16 * 25.4; latch_lug_rim_height = 3; latch_lug_z_offset = 17; latch_cutout_width = latch_width + min_thickness; latch_cutout_depth = latch_depth + min_thickness * 2; latch_max_angle = 6; latch_gap = 1; sma_thread_d = inch(1/4) + 2 *tol; sma_thread_length = inch(7/16); sma_hex_small_d = inch(5/16) + 2 * tol; sma_hex_height = 3; sma_mount_thickness = 2; module copy_mirror(vec = [ 0, 1, 0 ]) { children(); mirror(vec) children(); } module chamfer_tool(d, flat_top = false, no_bottom = false) { if (no_bottom) { cylinder(d / 2, d / 2, 0, $fn = 4); } else { union() { cube_edge_length = sqrt(pow(d / 2, 2) * 2); if (flat_top) { rotate([ 0, 0, 45 ]) translate([ -cube_edge_length / 2, -cube_edge_length / 2, 0 ]) cube([ cube_edge_length, cube_edge_length, d / 2 ]); } copy_mirror([ 0, 0, 1 ]) rotate([ 180, 0, 0 ]) cylinder(d / 2, d / 2, 0, $fn = 4); } } } // uses child passed to it as chamfer tool module block(upper_width, lower_width, upper_depth, lower_depth, height, chamfer_d = 0) { function linear(x, y_1, y_2, h) = y_1 + x * (y_2 - y_1) / h; scale = [ upper_width / lower_width, upper_depth / lower_depth ]; if (chamfer_d == 0) { linear_extrude(height, scale = scale) square([ lower_width, lower_depth ], center = true); } else { base_width = linear(chamfer_d / 2, lower_width, upper_width, height) - chamfer_d; base_depth = linear(chamfer_d / 2, lower_depth, upper_depth, height) - chamfer_d; new_scale = (scale - [ 1, 1 ]) * ((height - chamfer_d) / height) + [ 1, 1 ]; translate([ 0, 0, chamfer_d / 2 ]) minkowski() { linear_extrude(height - chamfer_d, scale = new_scale) square([ base_width, base_depth ], center = true); children(); } } } module jr_module() { function dimension_at(height, lower, upper) = lower + (uper - lower) * (height - jr_height); difference() { // main body block(jr_upper_width, jr_lower_width, jr_upper_depth, jr_lower_depth, jr_height, chamfer_d) { chamfer_tool(chamfer_d); }; // connector cutout translate([ jr_lower_width / 2 - connector_hole_width - connector_right_x_offset, -jr_lower_depth / 2 + connector_bottom_y_offset, 0 ]) cube([ connector_hole_width, connector_hole_depth, jr_height + rim_height ]); } } module latch(base_support = false, angle = 0) { base_support_d = latch_gap / 2; start_height = chamfer_d; latch_height = jr_height + rim_height; translate([ -latch_width, latch_depth / 2, +start_height ]) rotate([ 0, -angle, 0 ]) translate([ 0, 0, -start_height ]) rotate([ 90, 0, 0 ]) union() { ramp_points = [ [ 0, start_height ], [ 0, 7.5 ], [ 0.5, latch_lug_z_offset - 2.5 ], [ 1.25, latch_lug_z_offset ], [ 0, latch_lug_z_offset ], [ 0, latch_lug_z_offset + latch_lug_rim_height + 2 * tol ], [ min_thickness, latch_lug_z_offset + latch_lug_rim_height + 2 * tol ], [ min_thickness, latch_height ], ]; linear_extrude(latch_depth) polygon(concat( [ [ 0, latch_height], [ 0, start_height ], ], [for (p = ramp_points)[latch_width + p[0], p[1]]])); if (base_support) { translate([ -base_support_d, start_height, ]) linear_extrude(latch_depth) polygon( [[latch_width + base_support_d, base_support_d], [base_support_d, base_support_d], [0, 0], [0, -start_height], [latch_width + base_support_d - chamfer_d / 2, -start_height], [latch_width + base_support_d, -start_height + chamfer_d / 2]]); } } } module latch_cutout() { module custom_chamfer_tool() { hull() { translate([ 0, 0, latch_gap / 2 + tol ]) chamfer_tool(d = latch_gap); translate([ 0, 0, latch_gap / 2 + tol + jr_height ]) chamfer_tool(d = latch_gap); } } copy_mirror([ 1, 0, 0 ]) translate([ jr_lower_width / 2, 0, 0 ]) hull() { minkowski() { latch(base_support = false, angle = -latch_max_angle); custom_chamfer_tool(); }; minkowski() { latch(base_support = false, angle = latch_max_angle); custom_chamfer_tool(); }; } } module sma_mount(cut_tool=false){ sma_hex_big_d = sma_hex_small_d * (2/sqrt(3)); // length of the flexible tail of the SMA sma_tail_length = 20; sma_pocket_height = 3; angle = 22.5; horizontal_hex_length = cut_tool ? sma_hex_height : sma_hex_height + sma_mount_thickness; difference(){ union(){ tmp = sma_hex_height+sma_tail_length; // straight part rotate([90,30,0]){ translate([0, 0, -horizontal_hex_length+sma_hex_height]) cylinder($fn=6, d=sma_hex_big_d, h=horizontal_hex_length); if (cut_tool){ rotate([0, 180, 0]) cylinder(d=sma_thread_d, h=sma_thread_length); } }; // bent part translate([0, -sma_hex_height, -sma_hex_big_d/2]) rotate([0, -90, 180]) rotate_extrude(angle=angle){ translate([sma_hex_big_d/2, 0]) circle($fn=6, d = sma_hex_big_d); }; // angeled part hull(){ translate([0, -sma_hex_height + 1e-5, -sma_hex_big_d/2]) // TODO this is an ugly hack rotate([angle, 0, 0]) translate([0, 0, sma_hex_big_d/2]) rotate([90,30, 0]) cylinder($fn=6, d=sma_hex_big_d, h=sma_tail_length); rotate([0, 0, 180]) translate([-sma_hex_small_d/2, sma_hex_height, -sma_hex_big_d/2-sma_pocket_height]) cube([sma_hex_small_d, sma_tail_length, tol]); } } let ( height = 100, depth = sma_tail_length+sma_mount_thickness + sma_hex_height ) // TODO adjust dimensions { translate([0, -depth/2, -sma_hex_big_d/2-sma_pocket_height -height/2]) cube([sma_hex_small_d , depth , height], center = true); } } } module inside_pocket(height = 13) { mid_width = 33.8 + 2 * tol; upper_lower_width = 40.6 + 3 * tol; mid_depth = 21 - 2 * tol; total_depth = 54.6 + 2 * tol; floor_height = min_thickness; saddle_height = 3; difference() { // main body union() { translate([ -mid_width / 2, -mid_depth / 2, floor_height ]) cube([ mid_width, mid_depth, height ]); copy_mirror([ 0, 1, 0 ]) translate( [ -upper_lower_width / 2, mid_depth / 2, floor_height ]) cube([ upper_lower_width, (total_depth - mid_depth) / 2, height ]); // button hole translate([ -upper_lower_width / 2, -total_depth / 2 ]) { translate([ 13 / 16 * 25.4, 9, floor_height + saddle_height ]) cylinder(d = 6.5 + 2 * tol, h = 19); // rotary hole translate([ 8.5, 9, floor_height + saddle_height ]) cylinder(d = 9, h = 15.5); } // led hole copy_mirror([ 1, 0, 0 ]) translate( [ 5 / 2, -total_depth / 2 + 18, floor_height + saddle_height ]) cylinder(d = 3, h = 12); } // saddle cuts translate([ 0, 0, floor_height ]) linear_extrude(saddle_height) { // lower left translate([ -upper_lower_width / 2, -total_depth / 2 ]) square([ 5, 10 ]); // lower right translate([ upper_lower_width / 2 - 15, -total_depth / 2 ]) square([ 6, 4 ]); // lower mid translate([ -upper_lower_width / 2 + 9, -total_depth / 2 ]) square([ 3, 10 ]); // mid left translate([ -mid_width / 2, -mid_depth / 2 ]) square([ 3, 15 ]); // mid right translate([ mid_width / 2 - 7.5, -mid_depth / 2 ]) square([ 7.5, 10 ]); // mid both copy_mirror([ 1, 0, 0 ]) translate([ -mid_width / 2, -mid_depth / 2 ]) square([ 2, mid_depth ]); // top translate([ -upper_lower_width / 2, total_depth / 2 - 6 ]) square([ upper_lower_width, 6 ]); } } } module top_plate() { width = jr_upper_width + 2 * rim_width; depth = jr_upper_depth + 2 * rim_width; height = rim_height; vertical_offset = jr_height + rim_height / 2; sma_hex_big_d = sma_hex_small_d * (2/sqrt(3)); // length of the flexible tail of the SMA sma_tail_length = 20; sma_pocket_height = 3; sma_offset = [0,2*min_thickness + jr_upper_depth/2 - sma_hex_height - min_thickness, vertical_offset + sma_hex_big_d/2]; assert(rim_height >= chamfer_d); difference() { union(){ // actual top plate hull() copy_mirror([ 1, 0, 0 ]) copy_mirror([ 0, 1, 0 ]) translate([ jr_upper_width / 2 + rim_width - chamfer_d / 2, jr_upper_depth / 2 + rim_width - chamfer_d / 2, vertical_offset ]) chamfer_tool(chamfer_d); // sma mount minkowski(){ translate(sma_offset) sma_mount(false); chamfer_tool(d=min_thickness * 2); } /* translate(sma_offset) rotate([0, 0, 180]) { width = sma_hex_small_d + 2 * min_thickness - chamfer_d; height = sma_hex_big_d + 2 * min_thickness- chamfer_d; minkowski(){ translate([-width/2, -min_thickness, -height/2]) cube([width, sma_tail_length + sma_hex_height + 2 * min_thickness, height ]); chamfer_tool(chamfer_d, no_bottom = true); } }; } */ /* difference(){ union(){ translate([0, 13, 0]) cube([15, 30, 10], center = true); }; rotate([90,0,0]){ translate([0, 0, -sma_hex_height]) cylinder($fn=6, d=sma_hex_big_d, h=sma_hex_height); cylinder(d=sma_thread_d, h=sma_thread_length); } translate([0, sma_hex_height, -sma_hex_small_d/2]) rotate([0, -90, 0]) rotate_extrude($fn=100, angle=45) translate([sma_hex_small_d/2, 0, 0]) rotate([0, 0, 30]) circle($fn=6, d=sma_hex_big_d); translate([0, sma_hex_height, -sma_hex_small_d/2]) rotate([-45, 0, 0]) translate([0, 0, sma_hex_small_d/2]) rotate([-90, 0, 0]) cylinder($fn=6, d=sma_hex_big_d, h=20);// TODO fix ugly value } */ } translate(sma_offset) sma_mount(true); /* // cut tool for SMA tmp = sma_hex_height+sma_tail_length; translate(sma_offset) rotate([0,0,180]){ rotate([90,30,0]){ translate([0, 0, -tmp]) cylinder($fn=6, d=sma_hex_big_d, h=tmp); cylinder(d=sma_thread_d, h=sma_thread_length); } translate([-sma_hex_small_d/2, sma_hex_height, -sma_hex_big_d/2-sma_pocket_height]) cube([sma_hex_small_d, sma_tail_length, sma_hex_big_d/2 + sma_pocket_height]); } */ // main body notch minkowski() { #difference(){ jr_module(); linear_extrude(jr_height) projection() inside_pocket(); } cube(2 * tol, center = true); } latch_cutout(); inside_pocket(); } } if (part == "m") { union() { difference() { jr_module(); latch_cutout(); inside_pocket(height = 20); } copy_mirror([ 1, 0, 0 ]) translate([ jr_lower_width / 2, 0, 0 ]) latch(base_support = true); } } else if (part == "t") { top_plate(); }