// PCB Enclosure with Lid // Designed for 100 x 60 x 1.6 mm PCB with components up to 15 mm tall /* [PCB Dimensions] */ pcb_length = 100.0; // [50:1:200] pcb_width = 60.0; // [30:1:150] pcb_thickness = 1.6; // [0.8:0.1:3.2] component_height = 15.0; // [5:1:40] bottom_clearance = 4.0; // [2:0.5:10] pcb_xy_clearance = 1.5; // [0.5:0.1:4.0] lid_top_clearance = 2.0; // [0.5:0.5:10.0] /* [Enclosure Settings] */ wall_thickness = 2.4; // [1.5:0.1:5.0] floor_thickness = 2.4; // [1.5:0.1:5.0] lid_thickness = 2.4; // [1.5:0.1:5.0] corner_radius = 4.0; // [1.0:0.5:10.0] /* [PCB Standoffs] */ pcb_hole_inset = 4.0; // [2:0.5:10] standoff_od = 6.5; // [5.0:0.5:10.0] // M3 heat-set insert hole diameter (typically ~4.0 - 4.2mm for M3 brass insert) insert_hole_diameter = 4.2; // [3.0:0.1:5.0] insert_depth = 4.5; // [3.0:0.5:8.0] /* [Lid Fasteners] */ lid_screw_od = 8.5; // [6.0:0.5:12.0] lid_insert_hole_dia = 4.2; // [3.0:0.1:5.0] lid_insert_depth = 6.0; // [4.0:0.5:10.0] m3_screw_head_dia = 6.2; // [5.0:0.1:8.0] m3_screw_hole_dia = 3.4; // [3.0:0.1:4.5] countersink_angle = 90; /* [Cutouts & Vents] */ num_vents = 6; // [2:1:12] vent_slot_width = 2.0; // [1.0:0.5:5.0] vent_slot_length = 20.0; // [10.0:1.0:40.0] vent_spacing = 6.0; // [3.0:0.5:12.0] usbc_width = 10.0; // [8.0:0.5:14.0] usbc_height = 4.0; // [3.0:0.5:8.0] usbc_above_board = 3.0; // [0.0:0.5:10.0] /* [Display & Colors] */ part_spacing = 20.0; // [10:5:60] base_color = "#2E5A88"; // Base enclosure color lid_color = "#4682B4"; // Lid color accent_color = "#D4AF37"; // Brass insert accents $fn = 48; // Derived Dimensions inner_l = pcb_length + 2 * pcb_xy_clearance; inner_w = pcb_width + 2 * pcb_xy_clearance; inner_h = bottom_clearance + pcb_thickness + component_height + lid_top_clearance; outer_l = inner_l + 2 * wall_thickness; outer_w = inner_w + 2 * wall_thickness; base_h = floor_thickness + inner_h; // PCB top Z coordinate relative to bottom of base pcb_top_z = floor_thickness + bottom_clearance + pcb_thickness; // Helper: Rounded Rectangle 2D module rounded_rect(w, l, r) { hull() { translate([-w/2 + r, -l/2 + r]) circle(r=r); translate([ w/2 - r, -l/2 + r]) circle(r=r); translate([-w/2 + r, l/2 - r]) circle(r=r); translate([ w/2 - r, l/2 - r]) circle(r=r); } } // Base Enclosure module enclosure_base() { difference() { union() { // Main outer body linear_extrude(height = base_h) rounded_rect(outer_w, outer_l, corner_radius); } // Main inner cavity translate([0, 0, floor_thickness]) linear_extrude(height = inner_h + 1) rounded_rect(inner_w, inner_l, max(0.5, corner_radius - wall_thickness)); // USB-C Cutout centered on short side (front: -Y) // Positioned usbc_above_board mm above PCB top translate([0, -outer_l/2, pcb_top_z + usbc_above_board]) rotate([-90, 0, 0]) hull() { translate([-(usbc_width - usbc_height)/2, 0, -1]) cylinder(r = usbc_height/2, h = wall_thickness + 2); translate([ (usbc_width - usbc_height)/2, 0, -1]) cylinder(r = usbc_height/2, h = wall_thickness + 2); } // Vent slots on left (+X) and right (-X) long sides vent_start_y = -((num_vents - 1) * vent_spacing) / 2; for (side = [-1, 1]) { for (i = [0 : num_vents - 1]) { y_pos = vent_start_y + i * vent_spacing; // Vents centered in the upper clearance zone vent_z = floor_thickness + bottom_clearance + pcb_thickness + component_height / 2; translate([side * outer_w / 2, y_pos, vent_z]) rotate([0, side * 90, 0]) hull() { translate([0, -vent_slot_length/2 + vent_slot_width/2, -wall_thickness - 1]) cylinder(r = vent_slot_width/2, h = 2 * wall_thickness + 2); translate([0, vent_slot_length/2 - vent_slot_width/2, -wall_thickness - 1]) cylinder(r = vent_slot_width/2, h = 2 * wall_thickness + 2); } } } // Corner screw bosses holes (for M3 heat-set inserts to screw down lid) for (sx = [-1, 1]) { for (sy = [-1, 1]) { bx = sx * (inner_w/2 - lid_screw_od/2 + 0.5); by = sy * (inner_l/2 - lid_screw_od/2 + 0.5); translate([bx, by, base_h - lid_insert_depth]) cylinder(d = lid_insert_hole_dia, h = lid_insert_depth + 1); } } // PCB Standoff insert holes for (sx = [-1, 1]) { for (sy = [-1, 1]) { px = sx * (pcb_width / 2 - pcb_hole_inset); py = sy * (pcb_length / 2 - pcb_hole_inset); translate([px, py, floor_thickness + bottom_clearance - insert_depth]) cylinder(d = insert_hole_diameter, h = insert_depth + 1); } } } // Interior additions: Corner bosses for lid screws & PCB standoffs difference() { union() { // Lid screw corner bosses for (sx = [-1, 1]) { for (sy = [-1, 1]) { bx = sx * (inner_w/2 - lid_screw_od/2 + 0.5); by = sy * (inner_l/2 - lid_screw_od/2 + 0.5); translate([bx, by, floor_thickness]) cylinder(d = lid_screw_od, h = inner_h); } } // PCB Standoff pillars for (sx = [-1, 1]) { for (sy = [-1, 1]) { px = sx * (pcb_width / 2 - pcb_hole_inset); py = sy * (pcb_length / 2 - pcb_hole_inset); translate([px, py, floor_thickness]) cylinder(d = standoff_od, h = bottom_clearance); } } } // Re-cut holes in the newly added bosses for (sx = [-1, 1]) { for (sy = [-1, 1]) { bx = sx * (inner_w/2 - lid_screw_od/2 + 0.5); by = sy * (inner_l/2 - lid_screw_od/2 + 0.5); translate([bx, by, base_h - lid_insert_depth]) cylinder(d = lid_insert_hole_dia, h = lid_insert_depth + 1); } } for (sx = [-1, 1]) { for (sy = [-1, 1]) { px = sx * (pcb_width / 2 - pcb_hole_inset); py = sy * (pcb_length / 2 - pcb_hole_inset); translate([px, py, floor_thickness + bottom_clearance - insert_depth]) cylinder(d = insert_hole_diameter, h = insert_depth + 1); } } } } // Lid with countersunk screw holes and interlocking alignment lip module enclosure_lid() { lip_height = 1.8; lip_clearance = 0.3; // gap for snug fit difference() { union() { // Main lid plate linear_extrude(height = lid_thickness) rounded_rect(outer_w, outer_l, corner_radius); // Alignment lip extending down into enclosure translate([0, 0, -lip_height]) linear_extrude(height = lip_height) rounded_rect(inner_w - 2 * lip_clearance, inner_l - 2 * lip_clearance, max(0.5, corner_radius - wall_thickness - lip_clearance)); } // Hollow out center of alignment lip to save material and clear components translate([0, 0, -lip_height - 0.1]) linear_extrude(height = lip_height + 0.2) rounded_rect(inner_w - 2 * wall_thickness, inner_l - 2 * wall_thickness, 2); // Relieve lip at corner screw bosses for (sx = [-1, 1]) { for (sy = [-1, 1]) { bx = sx * (inner_w/2 - lid_screw_od/2 + 0.5); by = sy * (inner_l/2 - lid_screw_od/2 + 0.5); translate([bx, by, -lip_height - 0.5]) cylinder(d = lid_screw_od + 1.0, h = lip_height + 1.0); } } // M3 Countersunk screw holes in lid for (sx = [-1, 1]) { for (sy = [-1, 1]) { bx = sx * (inner_w/2 - lid_screw_od/2 + 0.5); by = sy * (inner_l/2 - lid_screw_od/2 + 0.5); // Through hole translate([bx, by, -lip_height - 1]) cylinder(d = m3_screw_hole_dia, h = lid_thickness + lip_height + 2); // Countersink cone cs_depth = (m3_screw_head_dia - m3_screw_hole_dia) / (2 * tan(countersink_angle / 2)); translate([bx, by, lid_thickness - cs_depth]) cylinder(r1 = m3_screw_hole_dia / 2, r2 = m3_screw_head_dia / 2, h = cs_depth + 0.01); translate([bx, by, lid_thickness]) cylinder(d = m3_screw_head_dia, h = 1.0); } } } } // Side by side assembly view translate([-outer_w / 2 - part_spacing / 2, 0, 0]) { color(base_color) enclosure_base(); } translate([outer_w / 2 + part_spacing / 2, 0, 0]) { color(lid_color) enclosure_lid(); }