// SPDX-License-Identifier: CC-BY-SA-4.0 // // OpenScribe parametric enclosure (OpenSCAD). // // M0 scaffold: a parametric two-part shell sized from the board + battery dimensions, with // the openings a recorder needs (mic port, button, USB, LED). Milestone M8 measures the // chosen build from hardware/BOM.md, tunes these parameters, and adds mount/clip features // and print-in-place tolerances. Render each half and export STL from there. // // Usage: set `part = "bottom" | "top" | "both"` and F5/F6 to preview/render. /* [Which part] */ part = "both"; // ["both","bottom","top"] /* [Board] (default: XIAO ESP32-S3 Sense - Build A) */ board_l = 21.0; // board length (mm) board_w = 17.5; // board width (mm) board_h = 3.5; // board thickness incl. components (mm) /* [Battery] (default: ~502030 LiPo) */ batt_l = 30.0; batt_w = 20.0; batt_h = 5.5; /* [Enclosure] */ wall = 1.6; // wall thickness (mm) gap = 0.8; // clearance around internals (mm) corner_r = 3.0; // outer corner radius (mm) lid_lip = 1.2; // overlap between top and bottom (mm) /* [Openings] */ mic_port_d = 1.2; // acoustic port diameter (mm) usb_w = 9.5; usb_h = 3.4; // USB-C cutout button_d = 4.0; // button plunger hole led_d = 2.5; // LED light-pipe hole // ---- derived internal cavity ---- inner_l = max(board_l, batt_l) + 2*gap; inner_w = board_w + batt_w + 3*gap; // board beside battery inner_h = max(board_h, batt_h) + 2*gap; outer_l = inner_l + 2*wall; outer_w = inner_w + 2*wall; outer_h = inner_h + 2*wall; module rrect(l, w, h, r) { hull() for (x=[r, l-r], y=[r, w-r]) translate([x, y, 0]) cylinder(h=h, r=r, $fn=48); } module shell(height) { difference() { rrect(outer_l, outer_w, height, corner_r); translate([wall, wall, wall]) rrect(outer_l-2*wall, outer_w-2*wall, height, max(0.5, corner_r-wall)); } } module bottom() { h = outer_h*0.55; difference() { shell(h); // USB-C cutout on one short side translate([-1, (outer_w-usb_w)/2, wall+1]) cube([wall+2, usb_w, usb_h]); } } module top() { h = outer_h*0.55; difference() { shell(h); // mic acoustic port (top face) translate([outer_l*0.5, outer_w*0.5, h-wall-1]) cylinder(h=wall+2, d=mic_port_d, $fn=24); // record button hole translate([outer_l*0.75, outer_w*0.5, h-wall-1]) cylinder(h=wall+2, d=button_d, $fn=24); // LED light-pipe hole translate([outer_l*0.25, outer_w*0.5, h-wall-1]) cylinder(h=wall+2, d=led_d, $fn=24); } } if (part == "both") { bottom(); translate([0, outer_w + 6, 0]) top(); } else if (part == "bottom") { bottom(); } else { top(); }