A nightstand noise generator based on M5Stack Atom Echo and integrating with Home Assistant
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

enclosure: fit Adafruit 1214 protoboard, fix plunger length

Tuned the daughterboard params for the actual Adafruit 1214 Perma-
Proto Small Mint Tin (54 × 33 mm with a 45.5 × 25.4 mm mounting hole
pattern) so it drops in flat without drilling. The four bottom-plate
standoffs now land exactly on the 1214's mounting holes.

While verifying the cap geometry against the new (taller) chamber,
caught a long-standing plunger-length bug: the calculation forgot
that the cap's flange itself eats `snooze_cap_flange_h` of the gap
between the chamber ceiling and the Atom button. The plunger was
2 mm too long, which meant the cap rested 2 mm higher than designed
AND the Atom button was held permanently depressed at rest — would
have shown up in firmware as a stuck press once a unit was assembled.

Other small cleanups in the same pass:

* Added back `spk_total_d` (51 mm) and a new `spk_magnet_protrusion`
(43 mm) to params (`spk_total_d` got dropped during the GRS rewrite
but the assembly view still referenced it).
* Updated the speaker reference geometry in `enclosure.scad` so it
sits on the bottom-plate posts (frame plate at z = spk_post_h, mag-
net hanging below) rather than the old "hanging from the top panel"
position.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

+36 -27
+10 -8
enclosure/enclosure.scad
··· 20 20 // Bottom plate, attached from below. 21 21 bottom_plate(); 22 22 23 - // Snooze cap at rest position (flange touching the underside of the top 24 - // panel). The cap origin sits with its flange's bottom-front-left at 25 - // z = outer_h - top_t - snooze_cap_flange_h, x/y centered on the well. 23 + // Snooze cap at rest position: flange's top face touches the underside 24 + // of the top panel; plunger bottom kisses the Atom button. The cap is 25 + // rendered with its plunger bottom at its local z=0, so we place that 26 + // at the Atom button top (= atom_z_bottom + atom_body_h). 26 27 flange_w_local = snooze_well_w + 2 * snooze_cap_flange_overhang; 27 28 flange_d_local = snooze_well_d + 2 * snooze_cap_flange_overhang; 28 29 translate([(outer_w - flange_w_local) / 2, 29 30 wall_t + snooze_well_cy - flange_d_local / 2, 30 - outer_h - top_t - snooze_cap_flange_h - (inner_h - (atom_z_bottom + atom_body_h))]) 31 + atom_z_bottom + atom_body_h]) 31 32 color("white", 0.6) snooze_cap(); 32 33 33 - // Reference geometry — a translucent box where the Atom Echo lives, 34 - // for visual verification of clearances. Comment out for a clean view. 34 + // Reference geometry — a translucent box where the Atom Echo lives. 35 35 %translate([(outer_w - atom_w) / 2, 36 36 wall_t + snooze_well_cy - atom_d / 2, 37 37 atom_z_bottom]) 38 38 cube([atom_w, atom_d, atom_body_h]); 39 39 40 - // Reference geometry — speaker frame footprint hanging from the top panel. 40 + // Reference geometry — speaker, sitting on the four bottom-plate posts. 41 + // Frame plate at z = spk_post_h; magnet hangs spk_magnet_protrusion below; 42 + // cone tip rises (spk_total_d - spk_magnet_protrusion) above. 41 43 %translate([(outer_w - spk_frame) / 2, 42 44 wall_t + spk_grille_cy - spk_frame / 2, 43 - outer_h - top_t - spk_total_d]) 45 + spk_post_h - spk_magnet_protrusion]) 44 46 cube([spk_frame, spk_frame, spk_total_d]);
+16 -9
enclosure/lib/params.scad
··· 47 47 // clearance between magnet bottom and bottom plate. 48 48 // ============================================================ 49 49 50 - spk_frame = 95; // largest lateral extent (mounting-ear to mounting-ear) 51 - spk_mount_pattern = 60; // square M3 hole pattern (centers) 52 - spk_mount_hole_d = 3.4; // M3 clearance 53 - spk_cone_cutout = 67; // baffle opening (estimate; measure & update) 50 + spk_frame = 95; // largest lateral extent (mounting-ear to mounting-ear) 51 + spk_mount_pattern = 60; // square M3 hole pattern (centers) 52 + spk_mount_hole_d = 3.4; // M3 clearance 53 + spk_cone_cutout = 67; // baffle opening (estimate; measure & update) 54 + spk_total_d = 51; // total speaker depth (cone tip to magnet bottom) 55 + spk_magnet_protrusion = 43; // magnet hangs this far below the frame plate 54 56 55 57 // ============================================================ 56 58 // Daughterboard — protoboard the Atom presses onto. 59 + // Sized for the Adafruit 1214 (Perma-Proto Small Mint Tin Size): 60 + // 54 × 33 mm × 1.6 mm FR4, with 4 mounting holes on a 45.5 × 25.4 mm 61 + // rectangular pattern centered on the board. 57 62 // ============================================================ 58 63 59 - dboard_t = 1.6; 60 - dboard_w = atom_w + 14; 61 - dboard_d = atom_d + 14; 62 - dboard_pin_h = 6; 63 - dboard_standoff_h = 6; 64 + dboard_t = 1.6; 65 + dboard_w = 54; // Adafruit 1214 long axis 66 + dboard_d = 33; // Adafruit 1214 short axis 67 + dboard_screw_pattern_w = 45.5; // mounting hole pattern, long axis 68 + dboard_screw_pattern_d = 25.4; // mounting hole pattern, short axis 69 + dboard_pin_h = 6; 70 + dboard_standoff_h = 6; 64 71 65 72 // ============================================================ 66 73 // Snooze cap + well
+5 -6
enclosure/parts/bottom-plate.scad
··· 61 61 62 62 module daughterboard_standoffs() { 63 63 standoff_d = 5; 64 - standoff_id = 1.6; 65 - inset = 3; 64 + standoff_id = 1.6; // M2 self-tap pilot into PLA 66 65 67 - for (sx = [dboard_cx - dboard_w / 2 + inset, 68 - dboard_cx + dboard_w / 2 - inset]) 69 - for (sy = [dboard_cy - dboard_d / 2 + inset, 70 - dboard_cy + dboard_d / 2 - inset]) 66 + for (sx = [dboard_cx - dboard_screw_pattern_w / 2, 67 + dboard_cx + dboard_screw_pattern_w / 2]) 68 + for (sy = [dboard_cy - dboard_screw_pattern_d / 2, 69 + dboard_cy + dboard_screw_pattern_d / 2]) 71 70 difference() { 72 71 translate([sx, sy, 0]) 73 72 cylinder(h = dboard_standoff_h, d = standoff_d);
+5 -4
enclosure/parts/snooze-cap.scad
··· 20 20 EPS = 0.05; 21 21 22 22 // Distance the plunger has to descend below the flange to reach the Atom 23 - // button. Derived from the chamber height and the Atom-on-daughterboard 24 - // stack — when the flange top touches the underside of the top panel, 25 - // the plunger bottom should just kiss the Atom button. 23 + // button. When the flange's TOP face touches the underside of the top 24 + // panel, the plunger bottom should just kiss the Atom button — so the 25 + // plunger spans from the flange's BOTTOM (top-panel-underside minus 26 + // flange thickness) down to the button. 26 27 atom_button_top_z = atom_z_bottom + atom_body_h; 27 - plunger_h = inner_h - atom_button_top_z; 28 + plunger_h = inner_h - snooze_cap_flange_h - atom_button_top_z; 28 29 29 30 // Z layout of the cap, bottom-up: 30 31 z_plunger_bot = 0;