// Arduino Uno R3 Snap-Fit Enclosure // Parametric two-part case with standoffs, connector ports, and snap joints /* [Board Dimensions] */ board_length = 68.6; // [60:0.1:80] board_width = 53.3; // [45:0.1:65] board_thickness = 1.6; // [1.0:0.1:3.0] component_height = 12.0; // [8:0.5:20] clearance = 1.5; // [0.5:0.1:3.0] /* [Enclosure Settings] */ wall_thickness = 2.0; // [1.2:0.1:4.0] standoff_height = 3.0; // [2.0:0.5:8.0] standoff_diameter = 6.0; // [4.0:0.5:8.0] pin_diameter = 2.8; // [2.0:0.1:3.5] pin_height = 2.5; // [1.5:0.5:4.0] corner_radius = 3.5; // [1.0:0.5:8.0] snap_depth = 0.5; // [0.3:0.1:1.0] /* [Port Dimensions] */ usb_width = 12.0; // [10.0:0.5:15.0] usb_height = 11.0; // [9.0:0.5:14.0] usb_offset_y = 31.5; // [25.0:0.5:40.0] barrel_width = 9.0; // [7.0:0.5:12.0] barrel_height = 11.0; // [8.0:0.5:14.0] barrel_offset_y = 3.2; // [0.0:0.5:10.0] /* [Display & Layout] */ print_spacing = 16.0; // [10:1:40] show_lid_openings = true; base_color = "#1565C0"; // Blue lid_color = "#1E88E5"; // Lighter Blue /* [Calculated Dimensions] */ inner_length = board_length + 2 * clearance; inner_width = board_width + 2 * clearance; total_inner_height = standoff_height + board_thickness + component_height + 1.5; outer_length = inner_length + 2 * wall_thickness; outer_width = inner_width + 2 * wall_thickness; base_height = standoff_height + board_thickness + 5.0; // 9.6mm lid_height = total_inner_height - base_height + wall_thickness + 2.0; // rest of height $fn = 40; // Rounded box helper (centered in XY or at origin) module rounded_box_2d(length, width, r) { hull() { translate([r, r]) circle(r=r); translate([length - r, r]) circle(r=r); translate([length - r, width - r]) circle(r=r); translate([r, width - r]) circle(r=r); } } module rounded_box_3d(length, width, height, r) { linear_extrude(height=height) rounded_box_2d(length, width, r); } // Uno mounting holes relative to board bottom-left // (14.0, 2.5), (15.2, 50.8), (66.0, 7.6), (66.0, 35.6) uno_hole_positions = [ [14.0, 2.5], [15.2, 50.8], [66.0, 7.6], [66.0, 35.6] ]; // ------------------------------------------------------------- // BASE COMPONENT // ------------------------------------------------------------- module enclosure_base() { lip_height = 2.5; lip_inset = wall_thickness / 2; difference() { union() { // Main outer shell rounded_box_3d(outer_length, outer_width, base_height, corner_radius); // Snap-fit rim / interlocking lip translate([wall_thickness + lip_inset/2, wall_thickness + lip_inset/2, base_height]) linear_extrude(height=lip_height) difference() { rounded_box_2d(inner_length + lip_inset, inner_width + lip_inset, max(1, corner_radius - lip_inset)); rounded_box_2d(inner_length - lip_inset, inner_width - lip_inset, max(0.5, corner_radius - lip_inset*2)); } // Snap locking beads on the lip sides for (offset_x = [outer_length * 0.35, outer_length * 0.65]) { // Front and Back snap ridges translate([offset_x, wall_thickness + lip_inset/4, base_height + lip_height*0.6]) rotate([0, 90, 0]) cylinder(r=snap_depth, h=8, center=true); translate([offset_x, outer_width - (wall_thickness + lip_inset/4), base_height + lip_height*0.6]) rotate([0, 90, 0]) cylinder(r=snap_depth, h=8, center=true); } } // Inner cavity hollow out translate([wall_thickness, wall_thickness, wall_thickness]) rounded_box_3d(inner_length, inner_width, base_height + lip_height + 2, max(0.5, corner_radius - wall_thickness)); // Short side port cutouts (Left side, X = 0) // USB-B Jack cutout translate([-1, wall_thickness + clearance + usb_offset_y, wall_thickness + standoff_height + board_thickness]) cube([wall_thickness + 2, usb_width, usb_height + 5]); // DC Barrel Jack cutout translate([-1, wall_thickness + clearance + barrel_offset_y, wall_thickness + standoff_height + board_thickness]) cube([wall_thickness + 2, barrel_width, barrel_height + 5]); // Base ventilation slots on bottom floor for (i = [0:5]) { translate([outer_length * 0.3 + i * 6.5, outer_width * 0.3, -1]) cube([3, outer_width * 0.4, wall_thickness + 2]); } } // Standoff pillars inside the base for (pos = uno_hole_positions) { px = wall_thickness + clearance + pos[0]; py = wall_thickness + clearance + pos[1]; translate([px, py, wall_thickness]) { // Support pillar cylinder(h=standoff_height, d=standoff_diameter); // Locating pin translate([0, 0, standoff_height]) cylinder(h=pin_height, d=pin_diameter); // Pin chamfer/taper for smooth seating translate([0, 0, standoff_height + pin_height]) cylinder(h=0.8, d1=pin_diameter, d2=pin_diameter * 0.6); } } // Corner reinforcement / resting tabs translate([wall_thickness, wall_thickness, wall_thickness]) cube([2.5, 2.5, standoff_height]); translate([outer_length - wall_thickness - 2.5, wall_thickness, wall_thickness]) cube([2.5, 2.5, standoff_height]); translate([outer_length - wall_thickness - 2.5, outer_width - wall_thickness - 2.5, wall_thickness]) cube([2.5, 2.5, standoff_height]); translate([wall_thickness, outer_width - wall_thickness - 2.5, wall_thickness]) cube([2.5, 2.5, standoff_height]); } // ------------------------------------------------------------- // LID COMPONENT (Printed top-side down for ideal 3D printing) // ------------------------------------------------------------- module enclosure_lid() { lip_height = 2.5; lip_inset = wall_thickness / 2; lid_depth = lid_height; difference() { // Main lid shell rounded_box_3d(outer_length, outer_width, lid_depth, corner_radius); // Hollow interior translate([wall_thickness, wall_thickness, wall_thickness]) rounded_box_3d(inner_length, inner_width, lid_depth + 1, max(0.5, corner_radius - wall_thickness)); // Internal mating shelf / rebate for base rim translate([wall_thickness + lip_inset/2 - 0.2, wall_thickness + lip_inset/2 - 0.2, lid_depth - lip_height - 0.2]) rounded_box_3d(inner_length + lip_inset + 0.4, inner_width + lip_inset + 0.4, lip_height + 1, max(1, corner_radius - lip_inset)); // Snap receiver grooves inside for (offset_x = [outer_length * 0.35, outer_length * 0.65]) { translate([offset_x, wall_thickness + lip_inset/4, lid_depth - lip_height*0.4]) rotate([0, 90, 0]) cylinder(r=snap_depth + 0.2, h=8.5, center=true); translate([offset_x, outer_width - (wall_thickness + lip_inset/4), lid_depth - lip_height*0.4]) rotate([0, 90, 0]) cylinder(r=snap_depth + 0.2, h=8.5, center=true); } // Matching port archways on lid to complete the openings translate([-1, wall_thickness + clearance + usb_offset_y - 0.3, lid_depth - 3.5]) cube([wall_thickness + 2, usb_width + 0.6, 4]); translate([-1, wall_thickness + clearance + barrel_offset_y - 0.3, lid_depth - 3.5]) cube([wall_thickness + 2, barrel_width + 0.6, 4]); // Optional header cutouts and reset button access on top of lid if (show_lid_openings) { // Digital pin header slot translate([wall_thickness + clearance + 27, wall_thickness + clearance + 49.5, -1]) cube([38, 3.2, wall_thickness + 2]); // Analog / Power pin header slot translate([wall_thickness + clearance + 34, wall_thickness + clearance + 1.2, -1]) cube([31, 3.2, wall_thickness + 2]); // Reset button hole translate([wall_thickness + clearance + 5.5, wall_thickness + clearance + 49.5, -1]) cylinder(d=5.0, h=wall_thickness + 2); // UNO embossed label / accent cooling fins for (i = [0:3]) { translate([wall_thickness + clearance + 18 + i*4, outer_width * 0.45, -0.5]) cube([2, outer_width * 0.25, wall_thickness]); } } } } // ------------------------------------------------------------- // ASSEMBLY / PRINT BED LAYOUT // ------------------------------------------------------------- // Base placed on the bed color(base_color) enclosure_base(); // Lid placed side-by-side on the bed (oriented flat for printing) color(lid_color) translate([0, outer_width + print_spacing, 0]) enclosure_lid();