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.

Rust 72.0%
OpenSCAD 18.1%
Makefile 6.2%
Shell 1.7%
Other 2.0%
8 1 0

Clone this repository

https://tangled.org/guid.foo/sound-machine https://tangled.org/did:plc:bhkqjvwmkxtpthcbdl2xtv46/sound-machine
git@knot.guid.foo:guid.foo/sound-machine git@knot.guid.foo:did:plc:bhkqjvwmkxtpthcbdl2xtv46/sound-machine

For self-hosted knots, clone URLs may differ based on your setup.

Download tar.gz
README.md

sound-machine#

Two M5Stack Atom Echo–based nightstand white noise machines, replacing the Google Home speakers that used to live on our nightstands. Short press triggers a Home Assistant routine (lights off, white noise on, etc., depending on time of day), with offline fallback for travel use. Long-press cycles volume yo-yo through preset levels. Double-press is the late-night-lights gesture (raise outdoor + downstairs lights at low brightness for a 3 AM wake-up).

This repo holds everything for the project: firmware, design docs, hardware reference, and (eventually) 3D-printed enclosure models.

Layout#

sound-machine/
├── README.md                   # this file
├── Makefile                    # top-level entry: `make` builds firmware (and future model rendering)
├── .envrc                      # direnv: ESP toolchain env + libxml2 shim path
├── .envrc.private.example      # template for host-only secrets (OTA dir, MQTT URL)
├── firmware/                   # Rust firmware (esp-idf-svc, std). See firmware/README.md
└── reference/                  # Design docs and hardware reference
    ├── mqtt-contract.md            # wire protocol between device and HA
    ├── operating-modes.md          # firmware state machine, LED scheme, NVS, OTA
    ├── signal-chain.md             # audio path: ESP32 → MAX98357A → speaker
    ├── atom-echo/                  # M5Stack Atom Echo pinmap, dimensions, schematic
    ├── speakers/                   # Adafruit 1314 driver notes
    └── datasheets/                 # vendor PDFs for ESP32-PICO-D4, NS4168, SPM1423

Status#

  • Hardware research and selection complete — see reference/
  • MQTT contract and operating modes designedreference/mqtt-contract.md, reference/operating-modes.md
  • Toolchain validated end-to-endfirmware/ builds, flashes, and runs on real hardware
  • v0.1.0 — offline-mode firmware — button, audio, NVS, LED
  • v0.2.0 — online-mode firmware — WiFi + MQTT + HA Discovery
  • v0.3.x — OTA-capable firmware — two-slot partition layout, HA update entity with progress bar, esp_ota_mark_app_valid rollback
  • 🚧 Awaiting hardware — MAX98357A amps on order from DigiKey
  • 🚧 Enclosure design — 3D-printable case TBD

Architecture in one paragraph#

Each device runs Rust firmware (esp-idf-svc, std mode) on an Atom Echo. WiFi connects to the home network, MQTT to a LAN-only broker (no TLS), HA Discovery announces entities. The button publishes events; HA decides what to do; HA sends back a "play white noise" command. Audio is generated locally on-device (no streaming dependency) and sent over I2S to an external MAX98357A amp driving a 3" 4Ω speaker. Onboard NS4168 amp is bypassed (no I2S data sent to its pins) — it's known not to be sized for sustained white noise. When WiFi or MQTT drops, the device falls into offline mode where the button toggles white noise locally; same code path as travel use.

Firmware updates are over-the-air via HA's MQTT update entity: make firmware-ota-publish builds the new binary, copies it to a static HTTP host on the LAN, and announces the version on a shared MQTT topic. HA shows an Install button on each device's card; clicking it streams the firmware in over plain HTTP, with a live progress bar driven by retained MQTT publishes. ESP-IDF's two-slot partition layout means a broken firmware automatically rolls back to the previous version on the next reset.

Both units run the same firmware binary — identity is derived at runtime from the chip's STA MAC and used directly as the topic-prefix segment (nightstand/<mac_hex>/...). HA users name each device in the HA UI; the MQTT contract guarantees stable unique_ids per MAC.

For the gory details: firmware/README.md, reference/mqtt-contract.md, reference/operating-modes.md.