📟

Expertise

ESP32 & IoT

Motion and face detection, camera streaming, and the limits of a $6 microcontroller

Why the ESP32-CAM specifically

It's cheap, it has just enough processing power to be genuinely interesting, and it forces you to think about resource constraints in a way a Raspberry Pi mostly doesn't. Streaming video, running motion detection, and writing to an SD card all have to share a chip with a fraction of the RAM a normal computer takes for granted — every feature has a cost, and you feel that cost immediately.

The core build: an ESP32-CAM handling video capture and a basic web interface, an INMP441 I2S microphone for audio alongside it, motion detection to trigger recording instead of running constantly, and Wi-Fi to get footage off the device without physically pulling the SD card each time.

ESP32-CAM
Core capture unit
INMP441
I2S digital microphone

The real constraint: everything competes for the same resources

🧠

RAM is the actual bottleneck

Camera frame buffers alone can eat most of the available memory at higher resolutions — running a web server, motion detection, and SD writes simultaneously means dropping resolution or frame rate is often the only way to keep the thing stable.

📶

Wi-Fi and camera streaming fight each other

Pushing a live MJPEG stream over Wi-Fi while also trying to write frames to SD card can starve one or the other — the fix was usually about deciding priority explicitly rather than hoping the scheduler sorts it out.

🔋

Power draw adds up fast

Camera + Wi-Fi radio + SD writes simultaneously pull noticeably more current than any one of them alone — undersized power supplies caused random brownout resets that looked like software bugs until traced back to hardware.

How the pieces fit together

📷

Capture

ESP32-CAM handles frame capture and basic motion comparison between consecutive frames — cheap enough computationally to run continuously without starving everything else.

🎙️

Audio

The INMP441 talks over I2S rather than analog — noticeably cleaner signal, at the cost of needing to get the I2S pin configuration exactly right, which isn't always well documented for this specific chip pairing.

💾

Storage

SD card writes only trigger on motion, not continuously — both to save card life and because continuous writing while streaming was one of the resource conflicts mentioned above.

🌐

Interface

A lightweight web UI served directly from the ESP32 for live view and basic settings — no external server needed for the core functionality, keeping the whole thing self-contained on the local network.

From idle to recorded clip

1

Idle monitoring

Low-frequency frame comparison running continuously, deliberately lightweight so it doesn't compete with anything else for CPU time.

2

Motion detected

Frame delta crosses a threshold, which switches the device into active recording mode rather than running full capture around the clock.

3

Record to SD

Video and I2S audio get written locally, since relying on Wi-Fi for real-time transfer during the event risks dropped frames if the connection wobbles.

4

Transfer over Wi-Fi

Once recording stops, the file gets pulled off over the local network — decoupling "recording" from "transferring" avoided most of the resource conflicts I ran into early on.

Mistakes worth mentioning

Brownouts mistaken for firmware bugs

Random resets under load looked like a software crash for a while — it was actually the power supply sagging under peak current draw, not the code.

🎛️

I2S pin mapping trial and error

Getting the INMP441 wired and configured correctly took more iteration than expected — small pin-mapping mistakes produce garbled or silent audio with no obvious error message pointing at the cause.

📉

Streaming and recording fighting simultaneously

Trying to do both at full quality at once caused frame drops in both — the fix was reducing stream resolution specifically during active recording, not trying to brute-force both at max settings.

Lessons learned & what's next

🔌

Power supply quality is not optional

A properly rated 5V supply with adequate current headroom fixed more "mystery bugs" than any code change did.

🧩

Decouple features that compete for resources

Recording and streaming don't have to happen at identical quality simultaneously — degrading one gracefully beats both failing together.

🍓

Next: offloading to a Raspberry Pi

Using the ESP32 purely for capture and motion triggering, then handing heavier processing (like face detection) to a Raspberry Pi on the same network — playing to each device's actual strengths instead of asking one chip to do everything.

Working on a hardware project of your own?

Happy to talk through embedded/IoT builds, constraints and all.

Get In Touch