abse/museair-usb
USB-C–powered ESP32-C3 controller board with AP63203 buck conversion, AP2112K 3.3V regulation, I²C SEN62 sensor interface, status LED, buttons, UART/I²C headers, and extensive decoupling.
- Version
- 0.5.7
- License
- unset
- Stars
- 0
mechanical/HORIZONTAL-ASSEMBLY.md
# Top-service horizontal assembly — local draft
The enclosure base is one connected part containing all four full-height walls, floor, PCB ledges and floor bosses. Only the flat top lid removes. `assembly.circuit.tsx` provides independent CAD IDs `ENCLOSURE_BASE` and `REMOVABLE_TOP_LID`, with separate `showBase` and `showLid` props. The snap-base revision is local and unpublished; validation/direct-speaker-publication.json describes the earlier published assembly.
## Installation and removal
1. Install four PCB M2 insert envelopes in the internal ledges (3.2 mm outside diameter, 3 mm long). Select inserts and adjust installation pockets to their supplier specification before printing. Load two standard M2 hex nuts (4 mm across flats, 1.6 mm high) into the captive floor pockets. The pockets have 0.1 mm clearance per flat and 0.6 mm closed floor backing; thread strength and printing require a prototype.
2. With the PCB absent, lower the **bare low base** through the central opening, shifted 7.8 mm toward the display wall. Stop just above the floor, slide it forward 7.8 mm, then lower onto its seats. The 58 x 28.7 mm base frame (58.2 mm overall including release tabs) has a 2 mm open frame and low side guides, rather than a tall cage. The three sealed air collars are integrated into the enclosure and preserve the original port profiles.
3. Lower the **bare sensor separately**, shifted 12 mm toward the display wall, until its bottom is just above the frame. Slide forward 12 mm and lower onto the frame. **Only now install** the two M2 x 4 holder screws with 0.5 mm washers; installing them first obstructs the sensor slide. Modeled nut engagement is 1.4 mm and screw-tip clearance to the pocket floor is 0.3 mm. The lead-in noses flex the side arms outward during the forward slide and click into the CAD side recesses. Spread the release tabs outward to remove the sensor. Two stock 2.5 mm nylon ties remain an optional backup through the existing channels; default assembly preview hides them (`showTies=false`). Install the port seals without obstructing any of the three separate air passages.
4. Connect the keyed GH6 sensor lead and route the approximately 64 mm centerline clear of the air ports and ties. Verify manufacturer cavity numbering. Connect the speaker's original PicoBlade plug directly to J7; connect the factory display flex to top-side J8 after the PCB is seated. Keep these cables disconnected and parked during sensor insertion.
5. Seat the PCB on its four ledges using the original holes. Each ledge now connects to a sidewall with paired triangular support webs; speaker and display-flex reliefs remain open. Four internal M2 x 5 screws and 0.5 mm insulating washers clamp the PCB into the inserts with 2.9 mm modeled engagement. No PCB screw enters the lid or protrudes outside. Keep metal hardware isolated from copper.
6. Reconnect J8, J7 and J3, then close the independently removable lid with its four recessed closure screws. Plastic pilot holes need a compatible screw and thread-strength qualification.
7. To service: unplug USB, remove the lid, disconnect J8/J7/J3, undo the four PCB screws, and lift the PCB clear. Undo the two holder screws, spread both clip release tabs outward, and release/cut any optional ties. Remove the sensor and base **separately by reversing their slide-and-lift paths**. Do not try to lift the assembled sensor/base straight past the ledges.
The sampled insertion paths clear the enclosure, speaker, display and rigid frame at 148 poses per part. Sensor/clip contact during insertion is intentional; the check excludes the flexible arms from the rigid sensor-path obstacles and does NOT simulate deformation or insertion force. Final sensor/complete-carrier BREP overlap is zero. The central base clearance is nominally 0.4 mm; the sensor passes 0.4 mm below the ledges during its slide. These tight nominal clearances require a printed fit sample and tolerance adjustment before production. CAD checks do not establish tie retention, air sealing, hardware strength or physical fit. See `validation/compact-sensor-insertion.json` and `preview/compact-sensor-holder/`.
## Manufacturer connector and cable check
[Sensirion SEN6x datasheet v0.92](../docs/history/research/SEN6x-datasheet.pdf), page 15, Figure 4 and Tables 15/16: connector is on the side adjacent to the outlet. Sensor connector ACES 51468-0064N-001; cable mate ACES 51452-006H0H0-001 or compatible JST GHR-06V-S. Minimum wire is AWG26 (or thicker), specified maximum cable length is 500 mm; the I2C guidance recommends as short as possible, under 100 mm, and/or shielding.
The official sensor STEP confirms the connector is in the recessed rear face in this horizontal orientation, not on the top cover. CAD sections locate its inner opening at assembly-world X=0.075..8.825 mm and Z=24.9..26.95 mm, near Y=-6.7 mm. The modeled cable-side plug nose aligns to this opening; its shape is an envelope, not certified connector CAD. Sensor pin assignment: 1 VDD, 2 GND, 3 SDA, 4 SCL, 5 GND/NC, 6 VDD/NC. Use the PCB's existing pin map and verify cavity continuity before power.
The manufacturer mechanical guide also requires firm retention, flexible vibration decoupling and appropriate air sealing. The existing air passages and nominal 4 mm sensor-to-PCB gap are preserved. Sensor CAD © Sensirion; board component CAD from JLCEDA/EasyEDA imports. No electrical routing is changed by this revision.
## Verification and reproduction
`top-service-fit-audit.json` checks one-solid base topology, valid BREP geometry, sensor/holder/case/PCB-envelope clearances and six unobstructed 3 mm screwdriver paths. `sensor-cable-fit.json` checks the cable envelope against the sensor, holder, enclosure and PCB envelope. These establish modeled fit only, not hardware, airflow, thermal or RF performance. Selected inserts, screws, washer dimensions, tolerances, cable bends, seals and retention need prototype checks.
Use `scripts/generate-horizontal-enclosure.py`, `scripts/generate-horizontal-cables.py`, `scripts/prepare-horizontal-assembly.py` and `scripts/sync-horizontal-sensor.py`. `MUSEAIR_HORIZONTAL_OUT` selects the CAD output directory; the default is `mechanical/horizontal`. Run `scripts/check-top-service-mechanics.py` and `scripts/check-horizontal-cable-fit.py` after generating. Keep the main preview on the PCB; the assembly remains in its own file.
### USB-C display update
The assembly omits the illustrative custom USB cable and plug. The PCB group retains the imported JLCPCB C165948 TYPE-C-31-M-12 socket CAD. This model represents the board receptacle; no cable-side plug model was verified. Local close-ups are in `preview/top-service/usb-closeup.png` and `usb-bare.png`. No publication performed.
### Current PCB and new USB cable revision
Supersedes the cable omission above. PCB display regenerated from current dist/index/circuit.json using 33 imported JLCPCB component placements (17 model assets); standalone U3 sensor remains in its own assembly group. New illustrative USB-C cable has an oblong metal nose, rounded molded grip, tapered ribbed strain relief and a continuous curve to the desk. Actual cable fit is untested. Updated CAD snapshots: preview/top-service/cable-desk.png, usb-closeup.png and open.png. No publication.
### PCB-end sensor cable plug
Added an illustrative GHR-06V-S mating housing at J3, with six 1.25 mm wire entries, keyed nose and latch. Position follows J3 imported socket CAD: assembly center (-7,-18), socket front y=-20.432 mm. Plug body x=-11.3..-2.7, y=-23.1..-20.55, z=39.15..42.05 mm; keyed nose enters the socket intentionally. Wire fan now ends inside the housing, with the bound bundle ending at y=-24.1. Supplier dimensions, terminal cavities and keyed engagement remain approximate and need an actual housing/fit check. Updated local image: preview/top-service/pcb-connector.png. This revision has not been pushed.
## Display and audio revision
The PCB now has 65 top-side JLC/EasyEDA component models. The assembly has 19 independent CAD groups; the base and lid remain separately hideable. The new integrated display retaining ribs belong to the base. The lid microphone aperture is at world (-0.7, 12) mm, aligned to the offset acoustic port in the imported ZTS6216 CAD and its manufacturer drawing.
The display flex is a 5.5 mm wide, 0.3 mm thick ribbon with an exact nominal 60 mm routed centerline. It turns back with a 3.6 mm radius, folds diagonally around a 3 mm radius, rises outside the PCB edge and enters the top-side connector around a 2.5 mm radius. Manufacturer approval of these bends, insertion/contact orientation and physical tolerance fit still require a sample.
Speaker wires rise around the PCB edge and cross above the board. Mesh checks allow only intended connector mating contacts and find no unintended cable/component contacts. Off-board speaker and plug models are supplier-dimension envelopes; PCB component CAD uses the actual imported models. A matching GH-2 plug is not supplied with the selected bare-wire speaker and must be factory crimped.
Local snapshots and interactive viewer: `preview/display-audio/`. Display screen values are illustrative. Electrical implementation and firmware/procurement limits: `docs/research/display-audio/IMPLEMENTATION.md`. No publication was performed for this revision.
### Local rounded USB-C surround revision
Speaker/grille/cradle now on the negative-X end wall. The GH2 lead rises around the left PCB edge. The USB opening is a rounded, integral recessed surround, with a 1.2 mm face and a 9.54 x 4.7 mm aperture. Socket front projects 0.475 mm past the local lip, while remaining 3.225 mm behind the overall outer wall. Overall enclosure, display/flex and PCB mounting coordinates stay unchanged. Nominal socket/plug mesh checks pass; physical cable insertion and print tolerances require a sample. See validation/usb-surround-fit.json.
### Current PCB shift toward USB-C
Shared `scripts/horizontal-layout.py` sets PCB assembly X translation to +2.5 mm and surround face X to 39.3 mm. Electrical layout is unchanged. The socket is nearly flush with this lip, 0.725 mm behind the overall outer wall; PCB side gap is 0.5 mm. Four PCB mounts follow the PCB. Two right closure posts move slightly toward the corners to avoid the shifted board; matching lid screw holes follow. Microphone hole/gasket, button and lightpipe follow their PCB components. The fixed display retains its exact 60 mm FPC and nominal original bend radii; the sensor and speaker cables adjust only their service runs/mating ends. Check top-service mechanics, display/audio meshes, horizontal sensor cable and shifted PCB fit scripts. J6 has only 2.53 mm between its imported model and the inner wall: programming is still intended before enclosure installation; the actual SH3 lead envelope and wire bends require qualification for programming in the fitted enclosure. This supersedes unchanged-pose dimensions in the earlier USB surround section.
## Raised ASK cap — 7 October 2026
ASK now uses TS-1102S-B-H-B / C480275, nominal 7.5 mm actuator height. The plastic cap is a separate ASK_BUTTON_CAP CAD group, with independent showButton prop; lid and base remain separate. Its floating cup contacts the actuator and snaps below the lid, with nominal .60 mm head clearance and .25 mm stroke. Imported switch CAD is corrected to the H variant from its manufacturer drawing. Cap/actuator CAD checks include ±.20 mm switch height; printed snap retention, overtravel force and physical fit remain untested. See docs/research/ask-button/IMPLEMENTATION.md and validation/ask-button-mechanics.json.
## Upright push-in clips (2026-10-10; not published)
Two short upright cantilever clips rise directly from broad feet on the base. The corner return arms have been removed. Each upper web is0.6mm thick and2.6mm wide, with a tapered1.2mm-wide foot and nominal0.3mm rounded root transitions. Clip topZ14.1mm is6.7mm above the frame. Small0.8mm latch noses retain the original0.3mm engagement into unmodified manufacturer STEP recesses at Y=-8.1,Z=12.9mm. Both vertical and forward-slide lead-in ramps are included; outward tip pads release the clips. Overall width remains58.2mm. The short upright beam is structurally more direct, but its elastic range, root fatigue and actual retention are untested. This is custom prototype geometry, not a supplier-approved interface.
On the bench the sloped tips permit a downward push, but inside the enclosure the PCB ledges require the existing drop-and-forward-slide path. Sensor and base still enter separately. Keep the two base screws out until the sensor has slid into place; flex/spread clips as needed. The insertion script checks rigid geometry, not the intended clip deformation or insertion force.
Sensirion mechanical guide v1.01, pages9–10, shows a snap fixture but explicitly requires adapting it for material, process, seals and vibration isolation. Existing nominal side clearance leaves room for outward flex; elastic deformation, tolerance stack, insertion/removal force, latch pull-out strength, fatigue and vibration/air sealing are untested. PETG or nylon is a candidate prototype material; orient layers to support the flexures, avoid brittle resin, and test a small clip coupon with the actual sensor before printing the enclosure. The shallow0.3mm engagement makes tolerance testing essential. Root geometry, latch engagement and retention may need revision after testing.
## Native-viewer PCB grouping (2026-10-10)
The assembly has one PCB_COMPLETE CAD component containing the substrate, copper, pads, silkscreen and all 65 actual main-index PCB component models. SEN62, sensor holder, mounting screws, cables and enclosure remain separate. There are 18 default CAD groups plus optional retention ties. Use the viewer's right-click Hide "PCB_COMPLETE" and Unhide All Components commands.
The board comes from the actual native @tscircuit/3d-viewer scene of the checked index, excluding the separately assembled U3 sensor. Its native black soldermask, gold pads, white artwork, original component geometry/materials, and all six 1621x2468 textures are retained. PCB face materials draw both sides to avoid being culled by the glTF import transform, retain their original alpha-blend setting and render with the original native lighting materials, including roughness/normal/metalness textures and clearcoat. All component materials retain their original lighting. Only the board-face shading compatibility changes; texture pixels and physical geometry remain unchanged. Lossless WebP encoding preserves every visible pixel. Geometry is unchanged; external geometry buffers and images belong to the same single glTF model and avoid per-request registry upload limits. Embedded descendant CAD IDs are removed so picking resolves to PCB_COMPLETE rather than individual index component IDs. Its world pose is X=2.5 mm, Z=37.8 mm with a 90-degree XY rotation, as before.
Reproduce: capture the native viewer's loaded scene with Three GLTFExporter (binary, no sensor CAD), then run scripts/package-native-assembly-pcb.py with that GLB and its losslessly encoded image directory; run prepare-horizontal-assembly.py and build assembly.circuit.tsx. The packer validates the 65 component identities and pixel equality, preserves materials/normals/UVs, and writes the one PCB glTF plus its registry asset references. mechanical/horizontal/reference/pcb-native-world.glb preserves the exact native posed board and is preferred by the enclosure generator. CPU circuit-json-to-gltf exports and sync-assembly-pcb.py are superseded for assembly appearance; do not overwrite the native reference with them. validation/assembly-native-pcb.json records current model provenance and source/index hashes. This changes presentation only, not the electrical PCB or fabrication files.
## Purchased LED light pipe and clean air ports (2026-10-10)
The printed light pipe is removed from the lid model. Its empty 3.0734 mm hole is dimensioned for the clear Bivar PLP1-200 candidate; see docs/research/led-light-pipe/SELECTION.md for manufacturer dimensions, LED gap and supplier links. The existing status LED is green. No substitute homemade purchased-part CAD is included. Three foam seals remain behind the sensor collars; the three overlapping seal pieces embedded inside the enclosure collars were removed. PCB finish uses lighting again and retains the real index black soldermask and its native full-resolution artwork.
2026-10-10 material correction: restored original native board material settings instead of suppressing specular/clearcoat. Original silver J1 USB-C shell and all component materials compare equal to native capture. Black cable grip is a separate cable part. The current real index still specifies black soldermask. See validation/native-material-restoration.json.
## Native multi-material export correction (2026-10-10)
The previous native GLB exported non-indexed multi-material meshes as several primitives referencing the entire same vertex range. That superimposed each material over the whole part; J1's black material could cover its silver shell. Re-export with sequential indices on each cloned non-indexed multi-material geometry before GLTFExporter; preserve geometry.groups so each primitive exports only its own index range. Do not recolor the connector or remove its genuine black insulator. The packer rejects multi-material meshes without distinct index accessors. This fixes component material assignment while preserving actual face geometry and positions.
Export preparation (in the loaded native board viewer, with U3 excluded):
```js
const root = window.__TSCIRCUIT_THREE_OBJECT.clone(true)
root.traverse(mesh => {
if (mesh.isMesh && Array.isArray(mesh.material) && !mesh.geometry.index) {
mesh.geometry = mesh.geometry.clone()
mesh.geometry.setIndex(Array.from({length: mesh.geometry.attributes.position.count}, (_, i) => i))
}
})
const glb = await new GLTFExporter().parseAsync(root, {binary: true})
```