// Parametric PCB Enclosure with Lid // Designed for 100 x 60 x 1.6 mm PCB with 15 mm component height /* [PCB Specifications] */ 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] pcb_standoff_inset = 4.0; // [2:0.5:10] /* [Enclosure Dimensions] */ 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] pcb_clearance = 1.5; // [0.5:0.1:4.0] standoff_height = 5.0; // [3:0.5:12] lid_lip_height = 2.0; // [1:0.5:5] corner_radius = 4.0; // [1:0.5:10] /* [Mounting & Fasteners] */ pcb_insert_dia = 4.2; // [3.0:0.1:6.0] // M3 heat-set insert hole pcb_boss_dia = 7.0; // [5.0:0.5:12.0] lid_screw_dia = 3.3; // [2.5:0.1:4.5] // M3 clearance lid_screw_head_dia = 6.2; // [4.5:0.1:8.0] // M3 countersink head lid_insert_dia = 4.2; // [3.0:0.1:6.0] // M3 heat-set for lid posts lid_post_dia = 8.0; // [6.0:0.5:12.0] /* [Features] */ usb_width = 10.0; // [8:0.5:16] usb_height = 4.0; // [3:0.5:8] usb_height_above_pcb = 3.0; // [1:0.5:10] vent_count = 6; // [0:1:12] vent_length = 20.0; // [10:1:40] vent_height = 2.0; // [1:0.5:5] /* [Display & Colors] */ part_spacing = 25.0; // [10:5:80] base_color = "SteelBlue"; lid_color = "SlateGray"; pcb_color = "ForestGreen"; show_pcb_ghost = true; $fn = 48; // Derived dimensions inner_l = pcb_length + 2 * pcb_clearance; inner_w = pcb_width + 2 * pcb_clearance; inner_h = standoff_height + pcb_thickness + component_height + 1.5; // 1.5mm top margin outer_l = inner_l + 2 * wall_thickness; outer_w = inner_w + 2 * wall_thickness; outer_h = inner_h + floor_thickness; // PCB Standoff positions (relative to center) pcb_hole_x = (pcb_length / 2) - pcb_standoff_inset; pcb_hole_y = (pcb_width / 2) - pcb_standoff_inset; // Lid corner screw positions (near outer corners inside the box) lid_screw_x = (inner_l / 2) - (lid_post_dia / 2) + 0.5; lid_screw_y = (inner_w / 2) - (lid_post_dia / 2) + 0.5; // Rounded rectangle 2D helper module rounded_rect_2d(size, r) { w = size[0]; h = size[1]; offset(r=r) square([w - 2*r, h - 2*r], center=true); } // 3D Rounded box with flat top/bottom module rounded_box(size, r) { linear_extrude(height=size[2]) rounded_rect_2d([size[0], size[1]], r); } // USB-C pill/rounded-rect shape module usb_c_profile(w, h, depth) { r = min(h/2, 1.5); rotate([90, 0, 90]) linear_extrude(height=depth, center=true) rounded_rect_2d([w, h], r); } // Vent slot pill shape module vent_slot(length, height, depth) { rotate([90, 0, 0]) linear_extrude(height=depth, center=true) rounded_rect_2d([length, height], height/2); } // ========================================== // BASE ENCLOSURE // ========================================== module enclosure_base() { difference() { union() { // Main outer shell rounded_box([outer_l, outer_w, outer_h], corner_radius); // Internal lid corner screw bosses for (sx = [-1, 1]) { for (sy = [-1, 1]) { translate([sx * lid_screw_x, sy * lid_screw_y, floor_thickness]) cylinder(h=inner_h, d=lid_post_dia); } } // PCB Mounting Standoffs for (sx = [-1, 1]) { for (sy = [-1, 1]) { translate([sx * pcb_hole_x, sy * pcb_hole_y, floor_thickness]) cylinder(h=standoff_height, d=pcb_boss_dia); } } } // Inner cavity cutout translate([0, 0, floor_thickness]) rounded_box([inner_l, inner_w, inner_h + 1], max(0.5, corner_radius - wall_thickness)); // Lid alignment recess (lip step) around top rim translate([0, 0, outer_h - lid_lip_height]) difference() { translate([0, 0, -0.01]) rounded_box([outer_l + 1, outer_w + 1, lid_lip_height + 0.1], corner_radius); rounded_box([outer_l - 2*(wall_thickness/2), outer_w - 2*(wall_thickness/2), lid_lip_height + 1], max(0.5, corner_radius - wall_thickness/2)); } // Lid screw boss heat-set insert holes for (sx = [-1, 1]) { for (sy = [-1, 1]) { translate([sx * lid_screw_x, sy * lid_screw_y, outer_h - 7]) cylinder(h=7.1, d=lid_insert_dia); } } // PCB standoff heat-set insert holes for (sx = [-1, 1]) { for (sy = [-1, 1]) { translate([sx * pcb_hole_x, sy * pcb_hole_y, floor_thickness + standoff_height - 4.5]) cylinder(h=4.6, d=pcb_insert_dia); } } // USB-C Cutout centered on -X short side, 3mm above PCB pcb_top_z = floor_thickness + standoff_height + pcb_thickness; usb_center_z = pcb_top_z + usb_height_above_pcb; translate([-outer_l/2, 0, usb_center_z]) usb_c_profile(usb_width, usb_height, wall_thickness * 3); // Vent slots on both long sides (+Y and -Y walls) if (vent_count > 0) { vent_total_span = inner_l - 2 * lid_post_dia - 10; vent_spacing_z = min(3.5, (inner_h - 10) / (vent_count > 1 ? (vent_count - 1) : 1)); // Distribute 6 slots (3 rows x 2 columns or 6 vertical stacks) // Let's create a clean 2-row x 3-column array or 3-row x 2-column on each side for (col = [-1, 0, 1]) { for (row = [0, 1]) { x_pos = col * (vent_length * 0.95); z_pos = floor_thickness + standoff_height + 4 + row * (vent_height + 3.0); // +Y side translate([x_pos, outer_w/2, z_pos]) vent_slot(vent_length, vent_height, wall_thickness * 3); // -Y side translate([x_pos, -outer_w/2, z_pos]) vent_slot(vent_length, vent_height, wall_thickness * 3); } } } } } // ========================================== // LID WITH COUNTERSUNK SCREWS & INTERLOCK LIP // ========================================== module enclosure_lid() { difference() { union() { // Main lid plate rounded_box([outer_l, outer_w, lid_thickness], corner_radius); // Alignment lip / rim extending downwards into base translate([0, 0, -lid_lip_height]) rounded_box([outer_l - 2*(wall_thickness/2) - 0.4, outer_w - 2*(wall_thickness/2) - 0.4, lid_lip_height], max(0.5, corner_radius - wall_thickness/2)); } // Inner hollow inside alignment lip to save material & weight translate([0, 0, -lid_lip_height - 0.1]) rounded_box([inner_l, inner_w, lid_lip_height + 0.1], max(0.5, corner_radius - wall_thickness)); // 4 M3 Countersunk Screw Holes for (sx = [-1, 1]) { for (sy = [-1, 1]) { translate([sx * lid_screw_x, sy * lid_screw_y, -lid_lip_height - 1]) { // Through hole cylinder(h=lid_thickness + lid_lip_height + 2, d=lid_screw_dia); // Countersunk head cone translate([0, 0, lid_lip_height + 1 + lid_thickness - (lid_screw_head_dia - lid_screw_dia)/2]) cylinder(h=(lid_screw_head_dia - lid_screw_dia)/2 + 0.1, d1=lid_screw_dia, d2=lid_screw_head_dia); } } } // Decorative subtle top surface chamfer/recess or text label translate([0, 0, lid_thickness - 0.4]) rounded_box([outer_l - 12, outer_w - 12, 0.5], corner_radius); } } // ========================================== // PCB GHOST PREVIEW // ========================================== module pcb_preview() { translate([0, 0, floor_thickness + standoff_height]) { // PCB board difference() { color(pcb_color, 0.85) rounded_box([pcb_length, pcb_width, pcb_thickness], 1.5); // 4 Corner holes for (sx = [-1, 1]) { for (sy = [-1, 1]) { translate([sx * pcb_hole_x, sy * pcb_hole_y, -0.5]) cylinder(h=pcb_thickness + 1, d=3.2); } } } // Representative components color("DimGray", 0.7) { // Main MCU / SoC translate([0, 0, pcb_thickness]) cube([18, 18, 2.5], center=true); // Tall electrolytic capacitors / modules up to component_height translate([25, 12, pcb_thickness + component_height/2]) cylinder(h=component_height, d=10, center=true); translate([25, -12, pcb_thickness + component_height/2]) cylinder(h=component_height, d=10, center=true); // USB connector on board translate([-pcb_length/2 + 4, 0, pcb_thickness + usb_height/2]) cube([8, usb_width - 1, usb_height], center=true); } } } // ========================================== // SCENE ASSEMBLY (BASE & LID SIDE BY SIDE) // ========================================== // Base Enclosure on left translate([-(outer_l + part_spacing) / 2, 0, 0]) { color(base_color) enclosure_base(); if (show_pcb_ghost) { pcb_preview(); } } // Lid on right (presented top up with countersunk screw holes visible) translate([(outer_l + part_spacing) / 2, 0, lid_lip_height]) { color(lid_color) enclosure_lid(); }