ESP32-CAM: A $10 Wi-Fi Camera with Live Video Streaming
Run the official CameraWebServer example on an AI-Thinker ESP32-CAM: live video in the browser, snapshots, face detection and quality controls.
What you get
The ESP32-CAM (AI-Thinker) board with an OV2640 camera costs a few dollars, yet it can stream MJPEG video to your browser, take snapshots and even detect faces. We'll use Espressif's official CameraWebServer example, which already ships a complete web UI.
Parts
- ESP32-CAM AI-Thinker board with OV2640 camera
- USB-UART adapter (FTDI / CP2102 / CH340) with a 5 V output — or the ESP32-CAM-MB micro-USB daughter board (the easiest option)
- Female-female jumper wires
- 5 V ≥ 1 A power supply for continuous use
Wiring for flashing (without ESP32-CAM-MB)
| USB-UART | ESP32-CAM |
|---|---|
| 5V | 5V |
| GND | GND |
| TX | U0R (GPIO 3) |
| RX | U0T (GPIO 1) |
| — | IO0 ↔ GND (jumper — flashing only) |
The IO0 → GND jumper puts the board into bootloader mode. Remove it after flashing.
Arduino IDE setup
- esp32 by Espressif Systems board package 3.x.
- Board: AI Thinker ESP32-CAM.
- Partition Scheme: Huge APP (3MB No OTA/1MB SPIFFS) — the example is large.
- Open File → Examples → ESP32 → Camera → CameraWebServer.
What to change in the example
Select the camera model — uncomment the AI-Thinker line and comment out the others (in newer core versions this lives in board_config.h, in older ones in CameraWebServer.ino itself):
// #define CAMERA_MODEL_WROVER_KIT
// #define CAMERA_MODEL_ESP_EYE
#define CAMERA_MODEL_AI_THINKER // ← our board
Set your network:
const char *ssid = "YOUR_SSID";
const char *password = "YOUR_PASSWORD";
Flash and run
- Fit the IO0–GND jumper, press
RST, upload the sketch. - Remove the jumper, open the Serial Monitor (115200) and press
RSTagain. - The log prints
Camera Ready! Use 'http://192.168.x.x' to connect. - Open the address → Start Stream. The raw stream is also at
http://<IP>:81/stream.
Tuning quality
The web UI lets you change resolution (up to UXGA 1600×1200), JPEG quality, brightness, white balance and mirroring. For smooth video, VGA/SVGA at quality 10–12 is the sweet spot.
Troubleshooting
Brownout detector was triggered— insufficient power. Use a dedicated 5 V ≥ 1 A supply and short, thick wires.Camera init failed with error 0x105— wrong camera model selected or a loose camera ribbon.- Runs hot — normal during continuous streaming; add a small heatsink or lower the resolution.
- The bright LED on GPIO 4 is the built-in flash; you can control it from the UI.
Security
The example has no authentication. Never expose the camera port to the internet. For remote viewing use a VPN (WireGuard, Tailscale) or integrate with Home Assistant / Frigate.
Ideas
- PIR motion sensor + snapshot to a Telegram bot.
- Plant growth time-lapse saved to microSD.
- Ready-made ESPHome firmware (
esp32_camera) for Home Assistant integration.