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: targeted plunger for the flush button, M2.5 standoff pilot

Two unrelated tweaks driven by trial-fitting the first assembled unit:

The Atom Echo's button isn't a raised tactile dome — it's a flush
D-shaped cap on one half of the top face, with the surrounding plastic
fixed. A full-face plunger gets stopped by that fixed plastic before
the button can move. Replaced the 24×24 mm centered plunger with an
8×8 mm plunger sized to fit inside the button cap (10×10 mm bounding
box, 1 mm clearance per side), offset −2.75 mm / +1.7 mm in chassis
coords so it lands over the button measured at (20, 11) from the
rear-left mounting post on the soldered protoboard. Snooze cap stays
visually centered on the chassis; only the plunger inside it moves.

Bumped the daughterboard standoff pilot from 1.6 mm (M2 self-tap) to
2.2 mm (M2.5 self-tap) — the 1.6 mm holes were way too tight for the
M2.5 screws actually being used, and 2.2 leaves a small bit of give so
the screws thread cleanly without splitting the PLA wall.

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

+63 -11
+7
enclosure/enclosure.scad
··· 37 37 atom_z_bottom]) 38 38 cube([atom_w, atom_d, atom_body_h]); 39 39 40 + // Reference geometry — the Atom's button cap on its top face. The 41 + // plunger should land inside this footprint when viewed from above. 42 + %translate([button_cx - button_cap_w / 2, 43 + button_cy - button_cap_d / 2, 44 + atom_z_bottom + atom_body_h]) 45 + cube([button_cap_w, button_cap_d, 0.5]); 46 + 40 47 // Reference geometry — speaker, sitting on the four bottom-plate posts. 41 48 // Frame plate at z = spk_post_h; magnet hangs spk_magnet_protrusion below; 42 49 // cone tip rises (spk_total_d - spk_magnet_protrusion) above.
+42
enclosure/lib/params.scad
··· 27 27 header_right_pin_count = 4; 28 28 header_edge_offset = 2.0; 29 29 30 + // Button cap on the Atom's top face: a roughly D-shaped piece of plastic 31 + // flush with the surrounding fixed top, depresses below the surface when 32 + // pressed. The snooze cap's plunger has to fit *inside* this footprint 33 + // — anything overhanging onto the surrounding fixed plastic gets stopped 34 + // before reaching the switch. Treated as a rectangular bounding box for 35 + // plunger sizing. 36 + button_cap_w = 10; 37 + button_cap_d = 10; 38 + 39 + // Position of the button cap center on the protoboard, measured from 40 + // the rear-left mounting hole of the Adafruit 1214 (the corner closest 41 + // to the speaker / cable exit). User coordinate convention: 42 + // +X = right (along the protoboard's long axis) 43 + // +Y = forward (toward the front of the enclosure) 44 + button_x_from_rear_left_post = 20; 45 + button_y_from_rear_left_post = 11; 46 + 47 + // Margin between the plunger and the button cap edge on each side, to 48 + // absorb print tolerances and assembly misalignment without the plunger 49 + // catching on the surrounding fixed plastic. 50 + plunger_clearance = 1; 51 + 52 + plunger_w = button_cap_w - 2 * plunger_clearance; 53 + plunger_d = button_cap_d - 2 * plunger_clearance; 54 + 30 55 // ============================================================ 31 56 // MAX98357A I2S amp breakout (Adafruit 3006 / generic clone) 32 57 // See: reference/signal-chain.md ··· 68 93 dboard_screw_pattern_d = 25.4; // mounting hole pattern, short axis 69 94 dboard_pin_h = 6; 70 95 dboard_standoff_h = 6; 96 + dboard_standoff_d = 5; 97 + dboard_standoff_pilot_d = 2.2; // M2.5 self-tap pilot into PLA 71 98 72 99 // ============================================================ 73 100 // Snooze cap + well ··· 205 232 206 233 snooze_well_cy = front_margin + snooze_well_d / 2; 207 234 spk_grille_cy = front_margin + snooze_well_d + zone_gap + spk_frame / 2; 235 + 236 + // Button position derived in chassis coordinates. The snooze cap stays 237 + // visually centered above the chassis; the plunger inside it is offset 238 + // to land precisely over the Atom's button cap. 239 + rear_left_post_x = outer_w / 2 - dboard_screw_pattern_w / 2; 240 + rear_left_post_y = wall_t + snooze_well_cy + dboard_screw_pattern_d / 2; 241 + 242 + button_cx = rear_left_post_x + button_x_from_rear_left_post; 243 + button_cy = rear_left_post_y - button_y_from_rear_left_post; 244 + 245 + snooze_cap_cx = outer_w / 2; 246 + snooze_cap_cy = wall_t + snooze_well_cy; 247 + 248 + button_offset_x = button_cx - snooze_cap_cx; 249 + button_offset_y = button_cy - snooze_cap_cy;
+3 -5
enclosure/parts/bottom-plate.scad
··· 60 60 } 61 61 62 62 module daughterboard_standoffs() { 63 - standoff_d = 5; 64 - standoff_id = 1.6; // M2 self-tap pilot into PLA 65 - 66 63 for (sx = [dboard_cx - dboard_screw_pattern_w / 2, 67 64 dboard_cx + dboard_screw_pattern_w / 2]) 68 65 for (sy = [dboard_cy - dboard_screw_pattern_d / 2, 69 66 dboard_cy + dboard_screw_pattern_d / 2]) 70 67 difference() { 71 68 translate([sx, sy, 0]) 72 - cylinder(h = dboard_standoff_h, d = standoff_d); 69 + cylinder(h = dboard_standoff_h, d = dboard_standoff_d); 73 70 translate([sx, sy, -EPS]) 74 - cylinder(h = dboard_standoff_h + 2 * EPS, d = standoff_id); 71 + cylinder(h = dboard_standoff_h + 2 * EPS, 72 + d = dboard_standoff_pilot_d); 75 73 } 76 74 } 77 75
+11 -6
enclosure/parts/snooze-cap.scad
··· 1 1 // Snooze cap — translucent press button. Drops into the well in the top 2 2 // panel from below; the flange catches on the underside of the top panel 3 - // as the up-stop. The Atom Echo's tactile dome under the plunger acts as 4 - // the return spring. 3 + // as the up-stop. The Atom Echo's flush button cap (a D-shaped piece on 4 + // one half of its top face) sits under the plunger and acts as the 5 + // return spring. The plunger is sized to fit inside the button cap's 6 + // footprint and is offset from the cap's centerline to land over it — 7 + // the surrounding plastic on the Atom's top face is fixed, so a 8 + // full-face plunger would be stopped before reaching the switch. 5 9 // 6 10 // Print in translucent or white PLA so the SK6812 LED diffuses through. 7 11 // Print upside-down (cap top on the build plate) for the cleanest first ··· 40 44 flange_d = snooze_well_d + 2 * snooze_cap_flange_overhang; 41 45 42 46 module snooze_cap() { 43 - // Plunger — centered over the Atom Echo footprint. 44 - translate([(flange_w - atom_w) / 2, 45 - (flange_d - atom_d) / 2, 47 + // Plunger — sized to fit inside the Atom's button cap, offset from 48 + // the snooze cap's centerline to land over the button. 49 + translate([flange_w / 2 + button_offset_x - plunger_w / 2, 50 + flange_d / 2 + button_offset_y - plunger_d / 2, 46 51 z_plunger_bot]) 47 - cube([atom_w, atom_d, plunger_h]); 52 + cube([plunger_w, plunger_d, plunger_h]); 48 53 49 54 // Flange — wider than the well opening, catches the underside of 50 55 // the top panel.