Inspiration
What it does
EchoHawk is a one-button emergency relay. Press the button on the ESP32 node, hear a beep, and say what's happening. Your speech is turned into text, packed into a short burst of tones, and sent through the air to a receiver, which decodes it back into words on a call-center dashboard. The dispatcher sees the alert the moment the button is pressed, live status updates (listening, transcribing, transmitting), and then the message itself.
How we built it
- Node: an ESP32-WROOM-32 running Arduino firmware. A button press sends an alert over a WebSocket and waits for an acknowledgment. If none comes back, it keeps retrying, so an alert is never silently lost. A relay module clicks to confirm the alert was received.
- Voice station (Python): takes the alert, records the speaker until they pause, and runs Whisper speech-to-text locally on the laptop.
- Acoustic link: our own data-over-sound modem. A chirp marks the start of each packet, then every 4 bits of data plays as one of 16 tones between 5.8 and 7.3 kHz, and a CRC-8 checksum catches errors. Long messages are split into numbered packets and put back together on the other end.
- Receiver + dashboard: a Python listener finds the chirp, decodes the tones, checks the CRC, and pushes the finished text to the dashboard over WebSockets.
Challenges we ran into
- Getting the hardware talking: USB driver and port issues on macOS, a campus Wi-Fi network that blocks devices from reaching each other (we switched to a phone hotspot), and a hotspot name the ESP32 couldn't match because iPhones use a curly apostrophe.
- Unreliable touch input: capacitive touch on a bare jumper wire misfired, so we switched to a wire-to-ground button that triggers every time.
- A hidden decoder bug: the receiver only looked back 0.8 seconds for the start chirp, so any message longer than about 6 characters failed. We caught it in simulation and rewrote the decoder to handle multi-packet messages.
- Audio timing: heavy signal processing and playback inside the audio callback froze the mic stream. On top of that, the transmitter could hear its own tones and set itself off in a loop. We moved the processing to a worker thread and muted the mic while the device transmits.
Accomplishments that we're proud of
- A working end-to-end chain: button → speech → text → sound → text → dashboard.
- Our own acoustic modem with error checking, multi-packet messages, and no false triggers from background noise in testing.
- A reliable alert path: every alert is acknowledged, and unacknowledged alerts keep retrying.
- Going from a bare ESP32 on a breadboard to a full system in one build session.
What we learned
- How data-over-sound works: chirp-based synchronization, frequency-shift keying, and why timing alignment makes or breaks decoding.
- Real-world networking details: device isolation on campus Wi-Fi, port conflicts, and acknowledgment-and-retry design.
- Simulating the audio channel before touching hardware catches bugs you would never find by ear.
- Speech-to-text and data-over-sound solve different problems, and a working system needs both.
What's next for EchoHawk
- A trigger that doesn't depend on Wi-Fi: send the button alert over LoRa or a mesh network so the whole path works without internet.
- A mic on the node: add an INMP441 microphone so the ESP32 can capture voice itself instead of relying on the laptop.
- Faster transmission: more tones per symbol and text compression, to cut the current ~0.1 s per character.
- The real dashboard: a web dashboard for dispatchers with alert history, node locations, and message playback.
Log in or sign up for Devpost to join the conversation.