// Arduino Uno R3 Snap-Fit Enclosure // Designed for board: 68.6 x 53.3 mm, 1.6 mm thick, 12 mm max component height /* [Enclosure Dimensions] */ board_length = 68.6; // [50:0.1:100] board_width = 53.3; // [40:0.1:80] board_thickness = 1.6; // [1:0.1:3] tallest_component = 12.0; // [8:0.5:20] wall_thickness = 2.0; // [1.2:0.1:4] board_clearance = 1.5; // [0.5:0.1:3] standoff_height = 3.0; // [2:0.5:10] corner_radius = 4.0; // [1:0.5:8] /* [Port Openings] */ usb_width = 12.0; // [8:0.5:16] usb_height = 11.0; // [8:0.5:16] // Distance from board bottom edge to USB connector usb_offset_y = 31.8; // [25:0.5:40] barrel_width = 9.0; // [6:0.5:14] barrel_height = 11.0; // [8:0.5:16] // Distance from board bottom edge to barrel jack barrel_offset_y = 3.2; // [0:0.5:10] /* [Display & Layout] */ view_mode = "side_by_side"; // [side_by_side, assembled, exploded, base_only, lid_only] part_spacing = 15; // [10:1:50] base_color = "#1f5f8b"; lid_color = "#2d7db5"; /* [Hidden] */ $fn = 48; // Internal dimensions (cavity) inner_x = board_length + 2 * board_clearance; inner_y = board_width + 2 * board_clearance; total_inner_z = standoff_height + board_thickness + tallest_component + 1.4; // Exterior dimensions outer_x = inner_x + 2 * wall_thickness; outer_y = inner_y + 2 * wall_thickness; // Height split: parting line passes through port cutouts so board drops in vertically base_inner_z = 9.5; lid_inner_z = total_inner_z - base_inner_z; base_outer_z = base_inner_z + wall_thickness; lid_outer_z = lid_inner_z + wall_thickness; // Snap fit parameters lip_height = 3.2; lip_thickness = 1.2; snap_clearance = 0.25; snap_bump_r = 0.55; // Port Z references // Bottom of board inside base is at Z = standoff_height // Top of board (port base) is at Z = standoff_height + board_thickness port_base_z = standoff_height + board_thickness; // Layout rendering if (view_mode == "side_by_side") { color(base_color) translate([0, 0, 0]) enclosure_base(); color(lid_color) // Lid laid flat upside down for 3D printing translate([outer_x + part_spacing, outer_y, lid_outer_z]) rotate([180, 0, 0]) enclosure_lid(); } else if (view_mode == "assembled") { color(base_color) enclosure_base(); color(lid_color) translate([0, 0, base_outer_z + lid_outer_z]) rotate([180, 0, 0]) translate([0, -outer_y, 0]) enclosure_lid(); } else if (view_mode == "exploded") { color(base_color) enclosure_base(); color(lid_color) translate([0, -outer_y, base_outer_z + lid_outer_z + 20]) rotate([180, 0, 0]) enclosure_lid(); } else if (view_mode == "base_only") { color(base_color) enclosure_base(); } else if (view_mode == "lid_only") { color(lid_color) translate([0, outer_y, lid_outer_z]) rotate([180, 0, 0]) enclosure_lid(); } // 2D Rounded rectangle helper module rounded_rect(w, d, r) { x1 = r; x2 = w - r; y1 = r; y2 = d - r; hull() { translate([x1, y1]) circle(r=r); translate([x2, y1]) circle(r=r); translate([x1, y2]) circle(r=r); translate([x2, y2]) circle(r=r); } } // 3D Rounded box helper module rounded_box(w, d, h, r) { linear_extrude(height=h) rounded_rect(w, d, r); } // BASE MODULE module enclosure_base() { difference() { union() { // Main outer shell rounded_box(outer_x, outer_y, base_outer_z, corner_radius); // Snap-fit rim (lip) extending up from the inner edge translate([wall_thickness, wall_thickness, base_outer_z]) difference() { // Outer perimeter of lip linear_extrude(height=lip_height) rounded_rect(inner_x, inner_y, max(1.0, corner_radius - wall_thickness)); // Hollow out lip translate([lip_thickness, lip_thickness, -0.1]) linear_extrude(height=lip_height + 0.2) rounded_rect(inner_x - 2 * lip_thickness, inner_y - 2 * lip_thickness, max(0.5, corner_radius - wall_thickness - lip_thickness)); // Cut out lip at port side (left X=0 side) so it doesn't obstruct connector insertion translate([-0.5, -0.5, -0.1]) cube([lip_thickness + 1.0, inner_y + 1.0, lip_height + 0.2]); } // Snap bumps on the outside of the lip (front and back walls) // Front side snap bumps translate([outer_x * 0.35, wall_thickness, base_outer_z + lip_height * 0.55]) rotate([0, 90, 0]) cylinder(r=snap_bump_r, h=outer_x * 0.3, center=true); // Back side snap bumps translate([outer_x * 0.35, outer_y - wall_thickness, base_outer_z + lip_height * 0.55]) rotate([0, 90, 0]) cylinder(r=snap_bump_r, h=outer_x * 0.3, center=true); // Right side snap bump translate([outer_x - wall_thickness, outer_y / 2, base_outer_z + lip_height * 0.55]) rotate([90, 0, 0]) cylinder(r=snap_bump_r, h=16, center=true); } // Hollow interior cavity translate([wall_thickness, wall_thickness, wall_thickness]) rounded_box(inner_x, inner_y, base_inner_z + lip_height + 1, max(1.0, corner_radius - wall_thickness)); // PORT CUTOUTS (Lower half in base, U-notches reaching base rim) // Barrel Jack cutout in base translate([-1, wall_thickness + board_clearance + barrel_offset_y, wall_thickness + port_base_z]) cube([wall_thickness + 2, barrel_width, base_outer_z - (wall_thickness + port_base_z) + 0.1]); // USB-B Jack cutout in base translate([-1, wall_thickness + board_clearance + usb_offset_y, wall_thickness + port_base_z]) cube([wall_thickness + 2, usb_width, base_outer_z - (wall_thickness + port_base_z) + 0.1]); // Fingernail pry slot on right wall seam translate([outer_x - wall_thickness - 0.5, outer_y / 2 - 6, base_outer_z - 1.2]) cube([wall_thickness + 1, 12, 1.3]); } // Corner Standoffs (3 mm high off the floor) standoff_w = 6.0; standoff_d = 6.0; // Corner 1: Bottom-Left (near [wall_thickness, wall_thickness]) corner_standoff( wall_thickness, wall_thickness, standoff_w, standoff_d, standoff_height, [1, 1] ); // Corner 2: Top-Left corner_standoff( wall_thickness, outer_y - wall_thickness - standoff_d, standoff_w, standoff_d, standoff_height, [1, -1] ); // Corner 3: Top-Right corner_standoff( outer_x - wall_thickness - standoff_w, outer_y - wall_thickness - standoff_d, standoff_w, standoff_d, standoff_height, [-1, -1] ); // Corner 4: Bottom-Right corner_standoff( outer_x - wall_thickness - standoff_w, wall_thickness, standoff_w, standoff_d, standoff_height, [-1, 1] ); } // Module for corner standoff with locating step module corner_standoff(x, y, w, d, h, dir) { translate([x, y, wall_thickness]) { // Main support pad (3 mm tall) cube([w, d, h]); // Corner alignment guide lip (steps up around the PCB edge) guide_t = 1.3; guide_h = board_thickness + 0.5; gx = dir[0] == 1 ? 0 : w - guide_t; gy = dir[1] == 1 ? 0 : d - guide_t; translate([gx, 0, h]) cube([guide_t, d, guide_h]); translate([0, gy, h]) cube([w, guide_t, guide_h]); } } // LID MODULE module enclosure_lid() { difference() { union() { // Main outer shell of lid rounded_box(outer_x, outer_y, lid_outer_z, corner_radius); } // Main inner cavity of lid translate([wall_thickness, wall_thickness, wall_thickness]) rounded_box(inner_x, inner_y, lid_inner_z + 1, max(1.0, corner_radius - wall_thickness)); // Rebate / pocket to receive the base lip translate([wall_thickness - snap_clearance, wall_thickness - snap_clearance, lid_outer_z - lip_height]) rounded_box( inner_x + 2 * snap_clearance, inner_y + 2 * snap_clearance, lip_height + 0.1, max(1.0, corner_radius - wall_thickness + snap_clearance) ); // Snap grooves in long walls (front and back) groove_z = lid_outer_z - (lip_height * 0.45); // Front groove translate([outer_x * 0.35, wall_thickness - snap_clearance, groove_z]) rotate([0, 90, 0]) cylinder(r=snap_bump_r + 0.15, h=outer_x * 0.32, center=true); // Back groove translate([outer_x * 0.35, outer_y - wall_thickness + snap_clearance, groove_z]) rotate([0, 90, 0]) cylinder(r=snap_bump_r + 0.15, h=outer_x * 0.32, center=true); // Right side groove translate([outer_x - wall_thickness + snap_clearance, outer_y / 2, groove_z]) rotate([90, 0, 0]) cylinder(r=snap_bump_r + 0.15, h=17, center=true); // PORT CUTOUTS (Upper half in lid) // In assembled state: // Cutout total height is 11 mm. // Base cutout height = base_outer_z - (wall_thickness + port_base_z) = 11.5 - (2 + 4.6) = 4.9 mm. // Remaining lid cutout height = 11.0 - 4.9 = 6.1 mm. // When lid is oriented with rim facing up (Z = lid_outer_z): // Cutout cuts down from rim: barrel_lid_cut_depth = barrel_height - (base_outer_z - (wall_thickness + port_base_z)); usb_lid_cut_depth = usb_height - (base_outer_z - (wall_thickness + port_base_z)); // Barrel jack lid cutout translate([-1, wall_thickness + board_clearance + barrel_offset_y, lid_outer_z - barrel_lid_cut_depth]) cube([wall_thickness + 2, barrel_width, barrel_lid_cut_depth + 0.1]); // USB-B lid cutout translate([-1, wall_thickness + board_clearance + usb_offset_y, lid_outer_z - usb_lid_cut_depth]) cube([wall_thickness + 2, usb_width, usb_lid_cut_depth + 0.1]); // Fingernail pry recess on lid matching base translate([outer_x - wall_thickness - 0.5, outer_y / 2 - 6, lid_outer_z - 1.2]) cube([wall_thickness + 1, 12, 1.3]); // Decorative embossed text on top of lid translate([outer_x / 2 + 3, outer_y / 2, -0.1]) rotate([0, 180, 0]) linear_extrude(height=0.6) { text("UNO R3", size=7, font="Liberation Sans:style=Bold", halign="center", valign="center"); } } // Hold-down bosses in lid corners to retain board securely boss_w = 4.5; boss_d = 4.5; boss_h = lid_inner_z - (tallest_component - (port_base_z - standoff_height)); // keeps clearance // Corner hold-downs (standoff pillars from ceiling down to corners of PCB) lid_hold_down(wall_thickness + 1.5, wall_thickness + 1.5, boss_w, boss_d, lid_inner_z - 1.5); lid_hold_down(wall_thickness + 1.5, outer_y - wall_thickness - boss_d - 1.5, boss_w, boss_d, lid_inner_z - 1.5); lid_hold_down(outer_x - wall_thickness - boss_w - 1.5, outer_y - wall_thickness - boss_d - 1.5, boss_w, boss_d, lid_inner_z - 1.5); lid_hold_down(outer_x - wall_thickness - boss_w - 1.5, wall_thickness + 1.5, boss_w, boss_d, lid_inner_z - 1.5); } module lid_hold_down(x, y, w, d, h) { translate([x, y, wall_thickness]) cube([w, d, max(0.5, h)]); }