Parametric prototype enclosure
Initial mechanical concept — not print-tested, assembled, load-tested, RF-qualified or a validated fit. The included *-default.stl files are exports of the provisional values in enclosure.scad, not production drawings. No PCB, schematic, routing, footprint or prior hardware export was modified.
Parts and operation
Open enclosure.scad in OpenSCAD (tested here with 2021.01). Set part to:
| Mode | Result |
|---|---|
assembly / exploded |
Assembled / exploded reference preview; not printable combined parts |
base |
Floor, carrier insert bosses, daughterboard insert bosses, side assembly bosses |
lid |
Roof, skirt, screw head wells, button guides, integral bottom-open DB9 retaining panel and ribs, raised labels |
plunger / plungers |
One / three identical captive button actuators |
| labels | Raised text alone for a second material or separately attached lettering |
| layout | Spaced parts for inspection; orient/support each part separately in the slicer |
show_references displays simplified hardware only in F5 preview ($preview and % background geometry); it is excluded from STL/F6 geometry. The reference boxes are not complete component models. Orange/brown DB9 post-body envelopes are shown reseated outside the integral panel; they illustrate unverified hardware, not guaranteed stock-thread or cable fit. Gold dummies represent two M3 and four M2 male/female brass standoffs above the carrier, with lower studs and blind upper bores; their OD, stud length and bore depth are provisional. The red RF overlay and enclosure RF-reserve restriction have been removed at the user's request. Actual antenna geometry remains; no PCB reserve/copper/layout was changed and no Wi-Fi performance guarantee is implied.
All dimensions are mm. Parameter/source coordinates are carrier-local, X right and Y down toward USB; add (100,100) for KiCad coordinates. The rendered model maps Y_world = 80 - Y_carrier, so the DB9 is above the USB end in top view. Text is separately transformed to remain readable from the USB end.
Default envelope and exact chosen stack
The carrier remains 82 × 80, with its 36 × 19 top-left notch represented in the reference. The case is rectangular, covering the notch without adding internal metal there. Its width is 106 (X=-12…94), depth 86.8 (Y=-3.4…83.4), roof height 37.4. Raised labels reach 38.0 and released plunger tips 38.9. This is exactly 10 mm lower than the mistaken under-carrier-brass stack. Only 1 mm internal clearance and a 2.4 mm wall are added at each cable end; the case assembly hardware is placed laterally, not beyond the top/bottom PCB edges.
| Datum above exterior bottom | Default Z |
|---|---|
| Floor upper surface | 2.4 |
| All carrier/daughterboard insert-boss tops / carrier underside | 7.4 |
| Carrier top, saved PCB thickness 1.6 / brass body bottoms | 9.0 |
| B3F-1000 released actuator top | 13.3 |
| Base top / lid skirt bottom | 15.0 / 15.25 |
| Button guide bottom / roof underside | 15.6 / 35.0 |
| Brass body tops / module underside, carrier-top-to-underside gap 10 | 19.0 |
| RS-232 module top, STEP thickness 1.57 | 20.57 |
| ESP32 / OLED module tops, provisional thickness 1.6 | 20.6 |
| DB9 shell/lock centre axis | 26.84762024 |
| DB9 nominal flange upper edge | 33.12262024 |
| Roof underside / exterior | 35.0 / 37.4 |
The user's intended/reported module elevation is 10 mm. The descriptions “8.5 mm female + 2.5 mm male” do not independently prove a 10 or 11 mm mating height. This design explicitly interprets the requested 10 as the gap between carrier top and module underside, and exposes module_gap; verify that datum against the actual mated stack. module_gap is the brass body height, not an additional height below the carrier. carrier_bottom = floor_t + carrier_boss_h = 7.4; the 5 mm bosses give nominal floor-to-carrier-underside clearance for solder/prongs, subject to actual component measurements. There is no under-carrier brass. Unknown module thicknesses, display height and USB height are not promoted to measurements.
PCB and daughterboard fixture
- Carrier M3 axes: (3.5,22.5), (3.5,75), (78,4), (78,76); verified against actual saved Ø3.2 NPTH holes. Base bosses Ø8 end at Z7.4 and directly support the carrier underside. Fasten the carrier with four M3 screws through these holes into the base inserts, not with brass underneath. These four positions do not coincide with daughterboard mounting holes.
- Case M3 axes: (-6,12), (-6,68), (88,12), (88,68). Ø9 bosses and lateral ribs stay outside the board; top-access Ø6.4 × 2.8 deep head wells, Ø3.4 screw paths, base inserts. Flat butt seam has a 0.25 vertical gap; screws locate it. No snap-fit or sealing claim.
- RS-232 module M3 axes: (44.905,17.907), (69.035,17.907), 24.13 spacing, real saved carrier Ø3 holes.
- OLED M2 axes: (45.72,37.75), (68.22,37.75), (45.72,60.25), (68.22,60.25), 22.5 grid, real saved carrier Ø2 holes. Do not confuse this with a screw clearance specification.
- With
daughter_supports=true, dedicated insert bosses terminate at carrier underside Z7.4. Screw the two M3 RS-232 and four M2 OLED brass male/female standoffs down through their respective existing carrier holes into the inserts. Their 10 mm bodies rest on the actual carrier top Z9.0 and support the module undersides at Z19.0. Short screws through each daughterboard engage the upper female threads. M3 boss OD7, brass reference OD6; M2 boss OD6, brass reference OD4. ESP32 has no supplied mounting holes: despite the request referring to three components, it remains supported by its two headers (simplified black references), not fictional standoffs or newly drilled PCB holes. No printed column crosses a PCB plane; only the metal studs pass through existing holes. - Check underside solder-joint/prong, trace, insert, washer and pad clearances before tightening; the nominal underside clearance is now 5 mm, not 15 mm. The user's mostly-copper-free observation is not a measured clearance proof for conductive brass shoulders. The exact underside envelopes and mounting-land allowances are unavailable. Plastic shoulders must not crush components; exposed insert tops must not contact copper. If necessary use insulating washers and account for their thickness, reduce shoulder diameters after checking wall strength, or set
daughter_supports=falseand provide another verified fixture. Do not drill or modify the carrier to force a fit.
Insert pockets are examples, not validated fits: M3 Ø4.2 × 4 deep; M2 Ø3.2 × 3 deep, 0.3 entry flare. These numbers do not specify insert OD/length, thread engagement or thermal process. Choose the actual insert family and set diameter/depth/boss OD using its supplier recommendations and a material-specific test coupon first. Install inserts before electronics. Default carrier pockets leave 3.4 mm solid material to the outside bottom (1 mm boss web plus 2.4 floor).
Default insert count with all options enabled: 10 M3 (4 carrier, 4 case, 2 RS-232) and 4 M2 (OLED), all in the base. No DB9 panel insert hangers, panel-to-lid screws or separate printable plate remain. Connector screw posts use their own verified thread, not an inferred M3 designation.
Screw-length selection is by measured engagement, not a fixed BOM promise:
- Carrier screws: 1.6 mm carrier thickness + washers + engagement into the base insert. Keep the head and shoulder clear of nearby components/copper.
- Case screw under-head plane Z34.6 to insert mouth Z15 is 19.6, plus chosen engagement (e.g. 3 gives 22.6); do not blindly use an overlong 25 mm screw in a 4 mm pocket.
- Lower brass studs first traverse 1.6 mm carrier, then engage the base inserts.
brass_m3_stud_l/brass_m2_stud_ldefault to 4 mm reference lengths, not measured hardware: tips at Z5.0 give 2.4 mm engagement, leaving 1.6 mm to the M3 pocket bottom / 0.6 mm to the M2 pocket bottom. Actual insert usable threads may differ from pocket depth: measure before selecting. Upper daughterboard screws traverse 1.57 RS-232 / 1.6 OLED, plus washers and chosen engagement into the top female, not the base. Preview female depths are 4/3 mm, also unknown. Verify studs/screws pass the nominal 3/2 mm holes without force; these are not generous M3/M2 clearance holes. - Connector posts traverse 2.4 mm integral panel plus any washers/gap before engaging the connector flange. See the thread-reach and cable-mating gates below; these are not panel-to-lid screws.
Cable interfaces
USB: retain the accepted inboard mouths
Measured shell centres X15.23 and 26.63, widths 8.87, mouth plane Y77.705, remain unchanged — mouths are 2.295 inside the carrier bottom. The user's PCB fit/USB acceptance is retained, but it does not validate this new case.
A single joined bay spans X9.595…32.265, Z19.6…26.6 (22.67 × 7), through the bottom-end wall. It admits both plug overmoulds instead of adding fragile individual webs. There are no internal bosses or tunnels between the wall and mouths. Mouth-to-exterior-wall distance is 5.695: the plug must reach through that recess. The opening is deliberately generous relative to measured widths; shell height/depth and both plug overmoulds still need measurement. usb_below_module_top, usb_above_module_top, usb_extra_width are cutout controls; usb_reference_depth/h affect only the approximate preview. Enlarge for the actual plugs rather than moving U1 or growing Y without justification.
Signage says USB, not a guessed left/right native-USB vs USB-UART mapping. Both connections remain physically available independent of networking.
DB9: external flange retention, not a guessed thread
The STEP registers flange front Y1.930, original post mouths Y−2.870, shell nose Y−3.870, with module front Y0. Flange bounds are X41.57…72.37, Z20.57262024…33.12262024, thickness 0.4. Shell maximum root/lip envelope is 16.878038 × 9.1; the design uses a conservative rectangular clearance, not a reconstructed D-profile.
Integral cover mounting: a 48 mm nominal wide × 2.4 mm axial-thickness panel spans X33…81 (0.02 mm union overlap at each wall), Y−0.470…1.930, Z21.07…35 and joins the roof directly. Two 6 mm nominal wide full-height ribs, X33…39 and X75…81 (outer union overlap 0.02 mm), run forward to the outer wall plane Y−3.4. They provide broad roof load paths rather than small insert posts, with 2.57/2.63 mm lateral clearance to the flange. The ribs are forward of the connector anchors (nearest anchor Y5.03; panel rear Y1.93 gives 3.10 mm separation). Panel bottom remains 0.5 mm above the module PCB top; neither wings nor ribs extend through the PCB. Load/print strength still needs testing.
The shell slot is 18.078038 mm wide, X47.930981…66.009019, open through the panel bottom, with top Z31.99762024 (0.6 above shell top). There is no lower crossbar to trap the connector. The upper rail is 3.00238 mm high, continuous with the roof. Two closed Ø3.6 through holes retain screw posts on X44.47 / 69.47, Z26.84762024, 25 mm spacing, parallel to Y. The minimum slot-to-hole ligament is 1.660981 mm. external_fastener_clearance is clearance only, not a thread designation. The module mounting holes remain a separate 24.13 mm Z-axis system; anchor/prong holes are not new mounting points.
The outer-wall service recess is X33…81, open down to the lid seam (Z15.25) so no lid crossbar sweeps over the shell. The former 1 mm side slits are closed by extending the integral panel/ribs to join the wall boundaries. A base-only stepped upstand fills the lower opening: shoulders span X33.25…80.75 and rise from Z15 to Z20.82; the 17.578038 mm-wide central tongue rises to Z21.69762024, leaving 0.6 mm below the STEP shell minimum Z22.29762024. The steps interfit without an undercut, retaining 0.25 mm horizontal edge/tongue seams and the vertical shoulder-to-panel seam. The upstand is 2.9 mm deep, Y−3.4…−0.5: it stays 0.5 mm forward of the PCB edge Y0 and 5.53 mm forward of the nearest anchor Y5.03, rather than filling through the PCB/underside. This closes unwanted openings, not the required manufacturing/cable clearances, and is not a sealed enclosure. Forward ribs narrow the unobstructed central cable approach to X39…75 (36 mm). Shell nose stays 0.47 mm beyond the ordinary outer wall and 3.4 mm beyond the panel front. Full cable-hood, tool and mating clearance must be checked against that recess, not assumed from nose protrusion alone.
Installation path, not a horizontal-slide claim: remove both connector screw posts and unplug all cables. Hold the lid at its final XY registration and lower it straight down. The shell enters the bottom-open slot; the closed side holes sweep beside the shell, where the removed posts used to obstruct them. The panel remains forward of the flange and above the PCB for the entire descent. The USB shells end at Y77.705, inboard of the rear inner wall Y81 by 3.295 mm, so a closed USB bay does not require a horizontal slide with cables removed. Downward button guides stay on their final XY axes, stop above switch tops, and case bosses approach their corresponding base bosses without a lateral move. The nominal continuous 60 mm sweep is tested in validate.py --installation, including a negative control that detects unremoved posts. This checks selected envelopes, not unmodeled components or manufacturing tolerances.
Hardware gate — do not skip: remove stock posts only if the real connector permits it without damaging captive nuts/anchors. Screw their male studs from outside through the cover holes into the connector, leaving post bodies outside and female cable-lock receptacles available. Actual thread/pitch, removability, stud length, usable female depth and clamp torque are unmeasured; STEP Ø3 bores/Ø3.4 chamfers prove neither M3 nor 4-40. Ordinary screws inserted into the original front bores do not implement this clamp.
For under-shoulder stud length L, washer thickness w, and flange gap g, available engagement is L − panel_t − w − g: default L − 2.4 − w. To retain the previous engagement, studs must provide 2.4 mm more reach (plus any washer/gap). Reusing stock posts is conditional; verified longer-stud replacements or compatible extensions may be required, and must neither bottom nor interfere internally. Do not order a guessed thread. Default panel_flange_gap=0 registers direct flange contact; any positive gap needs a measured, supported clamp stack, not tightening across air and bending the PCB.
Reseating a same-length 4.8 mm post body puts its mouth at Y−5.270, 1.4 mm forward of the shell nose, instead of 1 mm behind it. This is a significant full-mating risk, not validated by thread engagement. A verified shorter shoulder/body, recessed cable hardware or another compatible panel-mount post geometry may be necessary; retaining the original mouth plane would require a 2.4 mm body length at the default panel face, whose female thread depth is not established. Keep full shell mating and functional cable locks as acceptance limits. If no compatible hardware exists, revise the cover/hardware design rather than force it. panel_t, panel_flange_gap, external_fastener_clearance and panel_rib_w expose the relevant choices; do not thin structural webs just to make stock threads reach.
db_panel=false omits the integral panel/ribs and base upstand for temporary access only, not equivalent connector retention. The obsolete panel export mode and panel-default.stl are removed; there is no duplicate printable plate.
Display, buttons and antenna
- OLED window follows the supplied display boundary X44.97…69.47, Y40.5…57, plus 0.6 margin: 25.7 × 17.7. This is not a known active-pixel rectangle. It leaves the M2 fixings outside the aperture. Glass thickness/height and optical viewing angle remain unknown; the provisional 2 mm preview glass top is Z22.6, leaving a fairly deep 12.4 mm viewing recess below the roof. Check readability and consider a later stepped bezel after measuring; no lid load is applied to the glass.
- Buttons are Omron B3F-1000, body 6 × 6, actuator Ø3.5, released height 4.3 ±0.2, travel 0.25 +0.2/−0.1. Actual saved body centres are (44.97,70.25), (56.97,70.25), (68.97,70.25). Labels are BACK / SELECT / NEXT, consistent with existing board/function evidence.
- Each 25.6 long Ø5 plunger contacts the released switch and protrudes 1.5 above the roof. An Ø8 × 1.2 retaining flange starts 0.5 above its contact tip and stays below the Ø9 outer / Ø5.5 bore guide. Guide bottom is 2.3 above the nominal switch top, giving 0.6 upward retention clearance. Insert stems from under the lid; they cannot be installed from above. The closed case/switch holds them from below, the flange stops extraction upward. Hold with removable tape during assembly; they can fall out of a detached lid.
- These are free sliding, switch-returned actuators, not printed springs. There is no independent downward overload stop: use normal tactile-switch force, never drive/hammer the plunger. Verify no preload, reliable return in different orientations, bore friction, tolerances, stroke and switch force before use. Shorten the tip/adjust flange/guide parameters if actual stack requires it. A ruggedized overload stop requires measured switch/body tolerances and is not claimed here.
- The case does not enforce the carrier RF reserve and has no red RF overlay, per user instruction. The measured projecting antenna X12.045…29.675/Y14.745…21.635, at Z19…20.6, remains physically represented and unobstructed by case hardware, with 14.4 mm to the roof underside. The PCB, its reserve and copper are unchanged. The plastic cover is not an RF-performance guarantee; no new RF qualification is claimed.
Assembly and printing
- Measure insert family, actual assembled stack and connector hardware before committing to a full print. Inspect the rendered assembly against physical parts. Print cutout/insert/guide coupons or slicer-cut samples first.
- Print the base floor down. Indicative starting point only: 0.4 mm nozzle, 0.2 mm layers, 4 perimeters, 4–5 top/bottom layers, 25–40% infill with local solid regions around inserts. PETG is a reasonable prototype option; PLA is for fit checks away from heat. Determine material/thermal suitability yourself. No sealing, flame or temperature rating is established.
- Lid can be printed roof-up with supports beneath the roof, guides, integral panel/ribs and cable openings, avoiding supports in bores where practical. Alternatively print roof-down with
emboss=false, attach separately printed text, or use a proper multi-material setup. Integrated raised text prevents a flat roof-down first layer; do not ignore this 0.6 mm offset. No support-free claim for the supplied embossed lid. - There is no separate DB9 plate to print. No plastic spacers are printed; the brass dummies are preview-only purchased hardware. Print plungers with brim and support under their low retaining flange, or choose a slicer orientation that yields smooth, strong shafts. Deburr guides without opening them so far that stems tilt/jam. Test all three independently.
- Heat-set inserts with a controlled tool to the selected supplier process. All inserts are in the base; none are used for the DB9 panel. Remove strings/debris; inspect for splits, exposed insert metal and screw bottoming.
- Seat the carrier directly on all base support bosses and secure its four M3 mounting holes. Install the two M3 and four M2 10 mm brass standoffs above the carrier, with lower studs through the corresponding existing carrier holes into inserts. Seat the RS-232/OLED on them and fasten with short screws into the top females; seat the ESP32 on its headers. Check that brass body height matches the header's seated height, neither bending boards nor lifting connectors; check DB9 prongs and all underside solder joints against the 5 mm floor clearance.
- Disconnect all cables and remove the two verified-removable DB9 screw posts before lowering the lid. Insert plungers from under the lid and hold with removable tape. Align the cover in its final XY position and lower vertically: shell enters the bottom-open slot, panel wings clear the PCB, guides align over buttons. Do not slide horizontally, tilt around the USB end or force the shell. Verify free seating and button return; start the four case screws loosely.
- Insert verified stock or replacement post studs from outside through the two closed cover holes into the connector. Check clamp contact, engagement and bottoming independently; do not use them to pull a misaligned flange/PCB into position. Tighten case/post hardware cautiously to verified values. Test full USB/DB9 mating and cable locks, particularly the changed post-mouth reach; perform a restrained cable-load test before trusting retention.
- To remove the cover, unplug every cable, unscrew both connector posts completely out of the cover holes and remove the four case screws; lift vertically, retaining the plungers. The electronics remain secured by their independent carrier/daughterboard fasteners.
Raised labels are positive 0.6 mm emboss, not engraving. Single-colour is the default; roof-up printing allows a filament change just above the roof for contrasting text (check actual sliced layers). For a separate material export labels, and export the lid with emboss=false. In a multi-object slicer, preserve XY origin and translate the flat text object up 22.13 mm relative to the default lid export (its initial 0.02 overlaps the roof). Do not auto-centre individual letters; STL carries neither colour nor assembly transforms. Changes to stack require recalculating that offset: top_z - eps - split_z - seam_clearance.
Regeneration and checks
Run from hardware/case; no network or added dependencies are needed. Shell commands below terminate; allow roughly a minute per export on slower machines.
QT_QPA_PLATFORM=offscreen openscad -o base-default.stl -D 'part="base"' enclosure.scad
QT_QPA_PLATFORM=offscreen openscad -o lid-default.stl -D 'part="lid"' enclosure.scad
QT_QPA_PLATFORM=offscreen openscad -o plungers-default.stl -D 'part="plungers"' enclosure.scad
python3 validate.py
/usr/bin/python3 -B validate.py --source --installation --variants
QT_QPA_PLATFORM=offscreen openscad -o assembly-preview.png --imgsize=1200,1000 --viewall --autocenter --projection=o --camera=0,0,0,55,0,25,200 -D 'part="exploded"' enclosure.scad
QT_QPA_PLATFORM=offscreen openscad -o db9-preview.png --imgsize=1200,900 --viewall --autocenter --projection=o --camera=0,0,0,80,0,180,200 -D 'part="assembly"' enclosure.scad
QT_QPA_PLATFORM=offscreen openscad -o lid-detail.png --render --imgsize=1200,900 --viewall --autocenter --projection=o --camera=0,0,0,100,0,155,200 -D 'part="lid"' enclosure.scad
validate.py uses Python's standard library and installed OpenSCAD for evaluated datum, stud-engagement and nozzle-web fixtures, plus ASCII STL checks; --source additionally uses the already installed system KiCad pcbnew binding, read-only. It verifies current outline/holes/placements, measured U1 USB mouth graphics and STEP-derived lock/shell data against case constants. It is a drift tripwire, not a full source parser for every SCAD expression. It checks each STL has two oppositely directed uses of every triangle edge, nonzero triangle area, the expected connected component count (1 base, 1 lid, 3 plungers), positive total signed volume and minimum Z≈0. It does not prove vertex-manifoldness, absence of self-intersections, full component collision clearance or physical fit.
Validation results and bounded parameter/sweep tests are recorded in checks.md. The remaining exports are base, integral lid and three plungers; the corrected 37.4 mm shell / 7.4–9–19 mm stack is unchanged. No slicer, physical print, screw-fit, cable-load, hardware/firmware, thermal or RF acceptance is implied.
Evidence and remaining measurements
Authoritative sources used, all local:
- Saved carrier PCB: exact stepped outline, 1.6 thickness, all mounting holes, module/button placements and integrated measured U1 graphics.
- User acceptance: aligned centreline 56.97, approved M3/M2 hardware and 10 mm brass standoffs, user-accepted USB fit, unresolved mating-height arithmetic.
- Footprint measurements, Omron notes.
- DB9 mechanical notes, extracted measurements, source STEP, CAD provenance/license. These are extracted selected face bounds, not complete connector reconstruction. Original female-module STEP reference is applied to the male module only under the user's reported external-geometry equivalence. No third-party STEP geometry is redistributed into the printed parts.
Before calling this a fit: measure actual insert OD/length/process and all screw heads/studs/engagement; module underside-to-carrier-top gap and board thicknesses; USB shell Z/depth and both real overmoulds; glass top/active area/view angle; component/solder underside heights and support lands; switch height/force/return; actual DB9 thread, removability, panel-jackscrew seating, flange Z, cable hood/lock reach and panel strength. Check assembled height against screw-length choices. Tune parameters and regenerate all affected STLs; previews and prior exports do not update automatically. Keep the 10 mm report and header arithmetic ambiguity explicit until measured.


