AnasSarkiz/muse-voice-remote

Muse Voice Remote — bare ESP32-S3R8, 155 TOP JLCPCB parts with real supplier CAD, native 3D assembly and GLB exports. Revised 17 mm case allocation; 0.30 mm via drill /0.45 mm pad. Checked prototype PCB; mechanical, RF and MUSE qualification pending.

Version
1.3.2
License
unset
Stars
0

design/assembly-stack.ts

import { assembly } from "./assembly"

// PDF page 3 uses Z from the outer front surface, NOT from the PCB.
// PCB front = 4.20, PCB rear = 5.20; tscircuit PCB midplane = 0.
export const stack = {
  pcbCentreFromFront: 4.7,
  lcdFront: 0.6,
  lcdRear: 3.4,
  rearInner: assembly.case.depth - 0.8,
  batterySwelling: 0.57,
  transducerBottom: 9.25, // allocation only, above USB and the BOOT actuator
} as const
export const fromFront = (z: number) => z - stack.pcbCentreFromFront

export const assemblyEnvelopes = [
  { name: "ENV_LCD_ER_TFT028A2_4", label: "ER-TFT028A2-4 · nominal envelope", kind: "display", x: 0, y: 0,
    z: fromFront((stack.lcdFront + stack.lcdRear) / 2), size: [assembly.display.width, assembly.display.height, assembly.display.depth], color: [0.14, 0.2, 0.27], explode: -16 },
  { name: "ENV_LCD_ACTIVE_PIXELS", label: "Active pixels · faces front (−Z)", kind: "display", x: assembly.display.activeX, y: 0,
    z: fromFront(stack.lcdFront) - 0.02, size: [assembly.display.activeWidth, assembly.display.activeHeight, 0.02], color: [0.05, 0.58, 0.68], explode: -16 },
  { name: "ENV_BATTERY_UNSELECTED", label: "Battery · maximum envelope, unselected", kind: "battery", x: assembly.battery.x, y: assembly.battery.y,
    z: fromFront(assembly.battery.zBottom + assembly.battery.depth / 2), size: [assembly.battery.width, assembly.battery.height, assembly.battery.depth], color: [0.78, 0.58, 0.2], explode: 17 },
  { name: "ENV_SPEAKER_UNSELECTED", label: "Speaker · allocation, unselected", kind: "speaker", x: assembly.speaker.x, y: assembly.speaker.y,
    z: fromFront(stack.transducerBottom + assembly.speaker.depth / 2), size: [assembly.speaker.width, assembly.speaker.height, assembly.speaker.depth], color: [0.2, 0.48, 0.8], explode: 13 },
  { name: "ENV_MOTOR_UNSELECTED", label: "Motor · allocation, unselected", kind: "motor", x: assembly.motor.x, y: assembly.motor.y,
    z: fromFront(stack.transducerBottom + assembly.motor.depth / 2), size: [assembly.motor.diameter, assembly.motor.diameter, assembly.motor.depth], color: [0.63, 0.34, 0.75], explode: 13 },
  { name: "ENV_CASE_OUTER_ONLY", label: "Case · outside envelope, no engineered apertures", kind: "case", x: 0, y: 0,
    z: fromFront(assembly.case.depth / 2), size: [assembly.case.width, assembly.case.height, assembly.case.depth], color: [0.45, 0.65, 0.75], explode: 27 },
] as const