IoT Product Development and Design

Roommate Noise Guard

An intelligent IoT device that prevents roommate conflicts by monitoring noise and intervening gently—preserving both peace and relationships.

The Problem

Shared living often means shared noise. Confronting a roommate about loud behavior is awkward, strains relationships, and creates long-term tension. From my own experiences and interviews with friends, noise emerged as a universal pain point. The aim wasn’t just to quiet the space—it was to preserve harmony without direct confrontation.

The core challenge: keep the home peaceful without sacrificing relationships. People either avoid the talk—letting resentment build—or have uncomfortable conversations that make things worse.
Prototype

The Solution

Roommate Noise Guard prototype on wall
24-bit Audio Precision
60 Hz–15 kHz Range

A discreet system detects threshold violations and responds with graduated, non-confrontational nudges.

Core Technology Stack
ESP32 INMP441 MEMS Mic MicroPython IFTTT (cloud) I²S Audio PWM

Smart intervention: LED visual cues → soft audio reminders → private SMS notifications.

Key detail: 2-second sampling with cloud-managed thresholds for easy sensitivity and quiet-hour tuning.

Build Gallery

ESP32 with INMP441 on breadboard
ESP32 + INMP441 on breadboard
Circuit schematic for mic and buzzer driver
Circuit schematic (mic & buzzer driver)
Enclosure mockup with LED indicator
Enclosure mockup w/ LED cue

Development Process

1

User Research

Interviewed 15+ people in shared housing. 80% preferred anonymous notifications over direct confrontation.

2

Hardware

Selected INMP441 for high SNR and digital I²S. Added a simple driver stage to boost buzzer output for clear audio alerts.

3

Software & Cloud

Optimized MicroPython for 4 MB constraints. Chose IFTTT over MQTT for reliability and easy SMS integration.

4

Testing & Calibration

Separate thresholds for conversation, TV, and music. Tuned 2-second windows to avoid notification loops.

5

User Trials

Beta in 3 households for 2 weeks. Iterated on timing, sensitivity, and UX based on feedback.

Results & Impact

25%
Conflict Reduction

Beta testers reported ~85% fewer noise-related confrontations.

2s
Real-time Response

Detects and responds within ~2 seconds.

24/7
Continuous Monitoring

24/7 monitoring with customizable quiet hours.

$35
Low-cost

Total component cost under $35.

Challenges & Key Learnings

Technical: Memory Optimization

Instead of storing audio on the ESP32 (4 MB), I process in real time with threshold triggers to cut memory use.

Product: User Psychology

Direct SMS felt aggressive; graduated cues (visual → audio → digital) changed behavior with less friction.

Engineering: Audio Processing

Frequency + duration (not just volume) help distinguish disruptive noise from normal living sounds.

Scale: Cloud Architecture

IFTTT limits suggest a custom backend for richer routing and settings at larger scale.

Code

Core snippets from the prototype. Full repo available here:https://github.com/saracrogh/Noise-guard.
boot.py (Wi-Fi bring-up)
# boot.py (excerpt) — keep minimal so main.py always runs
import network, time
SSID = "YOUR_SSID"
PASS = "YOUR_PASSWORD"
wlan = network.WLAN(network.STA_IF); wlan.active(True)
if not wlan.isconnected():
    wlan.connect(SSID, PASS)
    for _ in range(20):
        if wlan.isconnected(): break
        time.sleep(0.5)
print("Wi-Fi:", "OK" if wlan.isconnected() else "FAILED", wlan.ifconfig())
main.py (I²S mic + optional cloud)
# main.py (excerpt)
from machine import Pin, PWM, I2S
import struct, time
THRESHOLD, WINDOW_S, SAMPLE_RATE, CHUNK_BYTES = 440, 2, 16000, 6400
led = Pin(26, Pin.OUT); buz = PWM(Pin(15), freq=1, duty=0); C3,G3,DUTY = 2000,3000,500
def play_buzzer():
    for _ in range(2):
        buz.duty(DUTY); buz.freq(C3); time.sleep(0.5)
        buz.freq(G3); time.sleep(0.5)
        buz.duty(0); time.sleep(1.0)
sck, ws, sd = Pin(12), Pin(13), Pin(27)
i2s = I2S(0, sck=sck, ws=ws, sd=sd, mode=I2S.RX, bits=16, format=I2S.MONO, rate=SAMPLE_RATE, ibuf=16000)
def avg_amplitude_over_window(seconds=WINDOW_S):
    target_bytes = int(SAMPLE_RATE * seconds * 2)
    got = runsum = numsamples = 0
    buf = bytearray(CHUNK_BYTES); mv = memoryview(buf)
    while got < target_bytes:
        n = i2s.readinto(mv)
        if not n: break
        for x in range(0, n, 4):
            l, r = struct.unpack_from(" THRESHOLD: led.value(1); play_buzzer()
    time.sleep(0.5)
config.json (quiet hours & sensitivity)
{
  "quiet_hours": { "start": "22:00", "end": "07:00" },
  "threshold_db": 50,
  "window_s": 2
}

Future Roadmap

1

Mobile App

Calibration tools, quiet hours scheduling, and real-time monitoring.

2

ML Classification

Differentiate music, conversation, and appliance noise for smarter alerts.

3

Multi-Room Mesh

Coordinate multiple devices for complete apartment coverage.

4

Sleek Enclosure

Move from breadboard to a polished housing.

5

Assistant Integrations

Connect with Alexa and Google Home.