Muhammad Sufian

Home/Work/Compact Wi-Fi speech speaker

Firmware · PCB

Compact Wi-Fi speech speaker

A small, low cost Wi-Fi speaker that plays speech from the client's cloud and follows a daily timetable when the internet drops.

  • ESP32-S3
  • ESP-IDF
  • I2S audio
  • OTA + TLS
Under NDA. Client and product names withheld.
Compact Wi-Fi speech speaker

The problem

No microphone, no voice assistant, no battery, no display. That sounds like less work, but it moves the whole problem onto four things: speech quality from a tiny driver, reliable streaming on a cheap radio module, a device that can be provisioned and updated safely at factory scale, and a bill of materials that stays under target at volume. The client fixed USB-C 5 V input, a pre certified module with onboard antenna, a mono Class-D amplifier, an LED ring, a single button, and signed OTA with per device identity.

What I did

Milestone one produced the architecture, six decision records the client signed off, a priced BOM, power and flash budgets, and a proof of concept that had to stream over HTTPS with real TLS for 30 minutes with heap logged every 30 seconds. It passed with zero underruns. Milestone two produced a round two layer board with single sided assembly: USB-C with fuse, TVS and CC pull downs, a synchronous buck, the ESP32-S3 module with strapping handled and the antenna zone clear, the I2S Class-D amplifier with its thermal pad in the pour, a level shifted addressable LED ring, one button and microSD on SPI. The first board came up cleanly.

The firmware splits into an audio pipeline with a 1 MB PSRAM ring buffer and an 8 second lead, a network task with reconnect and backoff, a player task with a command queue, and a UX layer mapping state to ring patterns. The audio chain has a fourth order 150 Hz high pass to protect the driver and a soft knee limiter above 70 percent so maximum volume compresses instead of clipping. The stream broke the first time it left the LAN. lwIP fails DNS instantly on a lease with no server list, so the station now falls back to the gateway and a public resolver. And the default 5.7 KB TCP window over a 290 ms round trip capped throughput at 17 KB/s when a 22 kHz WAV needs 44 KB/s.

A 64 KB window and deeper buffers took it to about 200 KB/s.

Decisions that shaped it

  • Fixed milestones with acceptance tests the client runs without me.
  • Decision records before code for the choices that needed sign off.
  • A soak instrument inside the firmware, logging heap, largest free block, PSRAM and underruns every 30 seconds.
  • Dual OTA partitions from the first build, so production updates need no repartition.

Result

Milestones 1 and 2 delivered. The custom board is built, brought up and streaming from a public host. Milestone 3 covers the decoder, scheduler, signed OTA and the enclosure.

All 19 projects, with files.

Boards, firmware, RF and IoT backends. Every one has a case study and the design files on GitHub.

See all workGitHub