← All projects
Camera Intermediate

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.

Difficulty
Intermediate
Time
1–2 h
Category
Camera

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

  1. esp32 by Espressif Systems board package 3.x.
  2. Board: AI Thinker ESP32-CAM.
  3. Partition Scheme: Huge APP (3MB No OTA/1MB SPIFFS) — the example is large.
  4. 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

  1. Fit the IO0–GND jumper, press RST, upload the sketch.
  2. Remove the jumper, open the Serial Monitor (115200) and press RST again.
  3. The log prints Camera Ready! Use 'http://192.168.x.x' to connect.
  4. 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.