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.
// Reference PCB centre=4.70. Fit revision moves it 0.50 mm toward the LCD.
// PCB front/rear=3.70/4.70. Electrical PCB coordinates are unchanged.
export const stack = {
  referencePcbCentreFromFront: 4.7,
  pcbCentreFromFront: 4.2,
  lcdFront: 0.6,
  lcdRear: 3.4,
  rearInner: assembly.case.depth - 0.8,
  batterySwelling: 0.57,
  speakerBottom: 11,
  motorBottom: 11.8,
  batteryPad: 0.2,
} 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.speakerBottom + 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.motorBottom + 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_BATTERY_PAD", label: "Battery · 0.20 mm soft insulating pad", kind: "pad", x: assembly.battery.x, y: assembly.battery.y,
    z: fromFront(15.1), size: [45, 28, stack.batteryPad], color: [0.2, 0.23, 0.25], explode: 26 },
  { name: "ENV_BATTERY_SWELLING", label: "Battery · reserved expansion volume, keep empty", kind: "reserve", x: assembly.battery.x, y: assembly.battery.y,
    z: fromFront(assembly.battery.zBottom-stack.batterySwelling/2), size: [assembly.battery.width, assembly.battery.height, stack.batterySwelling], color: [0.85, 0.5, 0.15], explode: 17 },
] as const