Clarify Enclosure Labels And Validate Clearance
This commit is contained in:
@@ -10,6 +10,8 @@ Working memory, not an implementation timeline. Source is authoritative; begin w
|
|||||||
|
|
||||||
## Parametric enclosure — initial concept, physical validation pending
|
## Parametric enclosure — initial concept, physical validation pending
|
||||||
|
|
||||||
|
- Label-only follow-up: removed DISPLAY, grouped `USB: UART0 / CDC` (local wiring/measurement evidence does not establish physical left/right roles), and raised `ESP32 / Serial Swiss / Army Knife` on the blank roof left of the display. Shared labels export retained; unlabeled lid CSG exactly matches the pre-change source. Lid STL and three previews refreshed; base/plungers and PCB unchanged. CGAL simple lid/labels exports, source/datum/mesh checks and actual-glyph roof clearance >=1 mm passed; no physical print/test. Lid detail now views readable branding from the USB side.
|
||||||
|
|
||||||
- `hardware/case/` corrected per user: 5 mm base insert bosses directly support carrier underside Z7.4/top Z9; two M3 RS-232 and four M2 OLED brass male/female bodies ABOVE carrier span 10 mm to module underside Z19. Studs cross actual 1.6 mm carrier holes into respective inserts; four separate carrier holes take direct M3 screws. ESP32 has no supplied mounting holes and remains header-supported. No under-carrier brass or printable spacers remain. Shell now **106 × 86.8 × 37.4 mm**, roof underside Z35 (10 mm lower); ports/display/DB9 panel/hangers/buttons follow the corrected datums. Red RF overlay/enclosure reserve restriction removed; physical antenna retained, no Wi-Fi guarantee and no PCB/schematic/copper/reserve/layout/export changes.
|
- `hardware/case/` corrected per user: 5 mm base insert bosses directly support carrier underside Z7.4/top Z9; two M3 RS-232 and four M2 OLED brass male/female bodies ABOVE carrier span 10 mm to module underside Z19. Studs cross actual 1.6 mm carrier holes into respective inserts; four separate carrier holes take direct M3 screws. ESP32 has no supplied mounting holes and remains header-supported. No under-carrier brass or printable spacers remain. Shell now **106 × 86.8 × 37.4 mm**, roof underside Z35 (10 mm lower); ports/display/DB9 panel/hangers/buttons follow the corrected datums. Red RF overlay/enclosure reserve restriction removed; physical antenna retained, no Wi-Fi guarantee and no PCB/schematic/copper/reserve/layout/export changes.
|
||||||
- Superseding DB9 change: separate plate/export/mode and M3 insert hangers removed. Cover now has integral nominal 48 mm-wide × 2.4 mm-thick connector panel at Y−0.47…1.93, Z21.07…35, continuous roof connection and two nominal 6 mm forward ribs outside flange bounds, extended into the wall to close former 1 mm side slits. Bottom-open 18.078 mm shell slot and closed Ø3.6 post holes at real 25 mm spacing permit straight vertical lowering **after removing both screw posts and all cables**; front-wall recess also opens to seam. Panel clears PCB by 0.5 mm and anchors by 3.10 mm in Y. No horizontal-slide claim. Insert count now 10 M3 + 4 M2, all base. Added forward-only base closure Y−3.4…−0.5: shoulders Z20.82, 17.578038-wide tongue Z21.69762024, 0.25 mm seams, 0.6 below STEP shell, 0.5 forward of module PCB. PCB files untouched.
|
- Superseding DB9 change: separate plate/export/mode and M3 insert hangers removed. Cover now has integral nominal 48 mm-wide × 2.4 mm-thick connector panel at Y−0.47…1.93, Z21.07…35, continuous roof connection and two nominal 6 mm forward ribs outside flange bounds, extended into the wall to close former 1 mm side slits. Bottom-open 18.078 mm shell slot and closed Ø3.6 post holes at real 25 mm spacing permit straight vertical lowering **after removing both screw posts and all cables**; front-wall recess also opens to seam. Panel clears PCB by 0.5 mm and anchors by 3.10 mm in Y. No horizontal-slide claim. Insert count now 10 M3 + 4 M2, all base. Added forward-only base closure Y−3.4…−0.5: shoulders Z20.82, 17.578038-wide tongue Z21.69762024, 0.25 mm seams, 0.6 below STEP shell, 0.5 forward of module PCB. PCB files untouched.
|
||||||
- Three default CGAL exports, native registration (including flange plane, hole diameters/no ESP32 NPTH), evaluated stack/connector/stud/web fixtures, edge-manifold meshes, three parameter CGAL smoke tests and continuous 60 mm vertical envelope sweeps passed; restored-post negative control detects blockage. Thicker-panel sweep caught and fixed residual inner-wall strip; default and raised/thicker variant now pass. Closure follow-up regenerated base/lid and all three previews (unchanged plungers revalidated); default plus two variant sweeps include per-step upstand/lid travel, base/lid seating and electronics insertion. Four parameter mesh tests pass; closure guards and STEP shell-minimum registration added. Three regenerated previews visually inspected, including bare-lid detail. This is selected-envelope CAD clearance, not complete hardware or strength qualification.
|
- Three default CGAL exports, native registration (including flange plane, hole diameters/no ESP32 NPTH), evaluated stack/connector/stud/web fixtures, edge-manifold meshes, three parameter CGAL smoke tests and continuous 60 mm vertical envelope sweeps passed; restored-post negative control detects blockage. Thicker-panel sweep caught and fixed residual inner-wall strip; default and raised/thicker variant now pass. Closure follow-up regenerated base/lid and all three previews (unchanged plungers revalidated); default plus two variant sweeps include per-step upstand/lid travel, base/lid seating and electronics insertion. Four parameter mesh tests pass; closure guards and STEP shell-minimum registration added. Three regenerated previews visually inspected, including bare-lid detail. This is selected-envelope CAD clearance, not complete hardware or strength qualification.
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ Measured shell centres **X15.23 and 26.63**, widths **8.87**, mouth plane **Y77.
|
|||||||
|
|
||||||
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.
|
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.
|
One grouped two-line label, **USB** above **CDC | UART0**, spans the combined bay; it does **not** assign left/right ports. The [wiring guide](../../docs/wiring.md#administration-and-native-usb-connectors) establishes bridge/UART0 and native/CDC roles, but neither it nor the measured HW678 mouth geometry establishes physical connector-to-role order. Seller labels are not used as mapping evidence. Both connections remain physically available independent of networking.
|
||||||
|
|
||||||
### DB9: external flange retention, not a guessed thread
|
### DB9: external flange retention, not a guessed thread
|
||||||
|
|
||||||
@@ -117,6 +117,8 @@ Reseating a same-length **4.8 mm** post body puts its mouth at **Y−5.270**, **
|
|||||||
8. 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.
|
8. 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.
|
||||||
9. 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.
|
9. 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.
|
||||||
|
|
||||||
|
The roof prominently carries the README project name on three lines, **ESP32 / Serial Swiss / Army Knife**, left of the display and readable from the USB end. The former DISPLAY caption is removed; RS-232 and button captions are unchanged. All text comes from the shared `labels()` module, including `part="labels"`; `emboss=false` omits it only from the lid.
|
||||||
|
|
||||||
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`.
|
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
|
## Regeneration and checks
|
||||||
@@ -133,10 +135,10 @@ python3 validate.py
|
|||||||
/usr/bin/python3 -B validate.py --source --installation --variants
|
/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 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 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
|
QT_QPA_PLATFORM=offscreen openscad -o lid-detail.png --render --imgsize=1200,900 --viewall --autocenter --projection=o --colorscheme=Metallic --camera=0,0,0,55,0,25,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.
|
`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. The default checks also project the actual label glyphs against the roof, requiring at least 1 mm clearance from its edges, display/button openings and screw-head recesses. 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](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.
|
Validation results and bounded parameter/sweep tests are recorded in [checks.md](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.
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 91 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 22 KiB |
@@ -303,8 +303,12 @@ module label_at(x,y,s,size=2.5) {
|
|||||||
}
|
}
|
||||||
module labels() {
|
module labels() {
|
||||||
label_at(module_cx,7,"RS-232",3);
|
label_at(module_cx,7,"RS-232",3);
|
||||||
label_at(20.93,74,"USB",3); // native vs UART left/right NOT established
|
// One grouped bay label: physical UART0/CDC left/right is not established.
|
||||||
label_at(module_cx,35,"DISPLAY",2.4);
|
label_at(20.93,71,"USB",3);
|
||||||
|
label_at(20.93,76,"CDC | UART0",2.4);
|
||||||
|
label_at(20.93,32,"ESP32",5);
|
||||||
|
label_at(20.93,41,"Serial Swiss",4);
|
||||||
|
label_at(20.93,50,"Army Knife",4);
|
||||||
for(i=[0:2]) label_at(button_centres[i][0],77,["BACK","SELECT","NEXT"][i],2.1);
|
for(i=[0:2]) label_at(button_centres[i][0],77,["BACK","SELECT","NEXT"][i],2.1);
|
||||||
}
|
}
|
||||||
module lid() {
|
module lid() {
|
||||||
|
|||||||
+90668
-18344
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 32 KiB |
@@ -235,6 +235,28 @@ def variant_check():
|
|||||||
print('PASS parameter CGAL mesh', part, defines)
|
print('PASS parameter CGAL mesh', part, defines)
|
||||||
|
|
||||||
|
|
||||||
|
def label_check():
|
||||||
|
"""Actual glyph solids must stay on roof, 1 mm clear of all roof openings."""
|
||||||
|
with tempfile.TemporaryDirectory(prefix="case-labels-") as temp:
|
||||||
|
wrapper = Path(temp)/"labels.scad"
|
||||||
|
wrapper.write_text(
|
||||||
|
f'include <{ROOT / "enclosure.scad"}>\n'
|
||||||
|
'cube(1);\n'
|
||||||
|
'translate([0,0,80]) linear_extrude(1) difference() {\n'
|
||||||
|
' projection() labels();\n'
|
||||||
|
' offset(delta=-1) projection(cut=true)\n'
|
||||||
|
' translate([0,0,-top_z+eps/2]) lid_body();\n'
|
||||||
|
'}\n')
|
||||||
|
path = Path(temp)/"clearance.stl"
|
||||||
|
result = subprocess.run(
|
||||||
|
["openscad", "-o", str(path), "-D", 'part="check"', str(wrapper)],
|
||||||
|
env={**os.environ, "QT_QPA_PLATFORM": "offscreen"},
|
||||||
|
capture_output=True, text=True, timeout=180)
|
||||||
|
assert result.returncode == 0 and "ERROR:" not in result.stderr, result.stderr
|
||||||
|
near([mesh_check(path, 1)["volume_mm3"]], [1])
|
||||||
|
print("PASS actual label glyphs within roof, >=1 mm from edges, display, buttons and screw-head openings")
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
parser.add_argument("--source", action="store_true", help="also check saved KiCad/STEP registration")
|
parser.add_argument("--source", action="store_true", help="also check saved KiCad/STEP registration")
|
||||||
@@ -246,6 +268,7 @@ def main():
|
|||||||
if args.installation:
|
if args.installation:
|
||||||
installation_check()
|
installation_check()
|
||||||
geometry_check()
|
geometry_check()
|
||||||
|
label_check()
|
||||||
if args.source:
|
if args.source:
|
||||||
source_check()
|
source_check()
|
||||||
reports = [mesh_check(ROOT / name, n) for name, n in [
|
reports = [mesh_check(ROOT / name, n) for name, n in [
|
||||||
|
|||||||
Reference in New Issue
Block a user