ESP32-CAM

A Wi-Fi camera on a board the size of a postage stamp. The ESP32-CAM combines an ESP32, an OV2640 2 MP camera, 4 MB PSRAM and a microSD slot for a few dollars. This guide covers the front and back of the board, the full 16-pin pinout, the camera pin map, how to program it with an FTDI adapter or the ESP32-CAM-MB, which pins are free, microSD, power and brownout fixes, live video streaming, and code with projects.

Complete Learning Path — ESP32-CAM

From board anatomy and the full pinout, to the camera pin map, programming, free pins, microSD, power, video streaming, antenna, code and projects

What is the ESP32-CAM?

The ESP32-CAM is a tiny Wi-Fi camera board. On 27 × 40.5 mm it packs an ESP32 (dual-core, 240 MHz, Wi-Fi + Bluetooth), 4 MB PSRAM for image buffers, an OV2640 2-megapixel camera, a microSD slot and a bright flash LED.

It is the cheapest way to build an IP camera, a doorbell cam, a time-lapse recorder or a motion-triggered photo trap. The catch is that it has no USB port and only a few spare pins, and it needs a solid 5 V supply. This guide covers all three.

ESP32-CAM board anatomy diagram front and back: ESP32-S module with PCB antenna and IPEX connector, OV2640 camera on FPC ribbon, microSD slot, white flash LED GPIO4, AMS1117 regulator, 4 MB PSRAM, RST button, red LED GPIO33 and two 8-pin headers — Power4All
Front: camera, ESP32-S module, microSD, flash LED. Back: AMS1117 regulator, PSRAM, RST button, red LED and the 16 header pins.
OV2640
2 MP camera, JPEG
4 MB
PSRAM + 4 MB flash
16
header pins
microSD
save photos
5 V
2 A supply advised

Full ESP32-CAM Pinout

The complete ESP32-CAM pinout: all 16 header pins, printed on the back of the board, with each pin's GPIO number, microSD signal, ADC2/touch channel and special role.

ESP32-CAM detailed pinout diagram: 5V row 5V, GND, IO12, IO13, IO15, IO14, IO2, IO4 and 3V3 row 3V3, IO16, IO0, GND, VCC, U0R, U0T, GND with SD_MMC, ADC2, touch, strapping, flash LED, camera XCLK, PSRAM and UART0 functions — Power4All
The 5V row carries the six microSD/GPIO pins; the 3V3 row carries the serial pins (U0R/U0T), IO0 and IO16.

At a glance, here is what those 16 pins are for:

ESP32-CAM pins at a glance: 16 header pins, 6 power pins, 6 microSD pins, UART0 programming pins, GPIO0 boot and camera clock, GPIO4 flash LED, 14 hidden camera GPIO and 2-3 truly free GPIO — Power4All
Most of the ESP32's pins are used by the camera and PSRAM, so only a few are left for you.

Every Pin Explained

PinGPIOWhat it does / watch out for
5V—Main power input. Feed a stable 5 V (2 A supply recommended).
3V3—3.3 V rail. It can power the board at 3.3 V, but 5 V on the 5V pin is far more reliable.
VCC—Output, 3.3 V by default (5 V on some boards). Don't feed power in here.
GND—Three ground pins.
U0R / U0T3 / 1UART0 RX/TX: connect to the FTDI's TX/RX to upload and for the Serial Monitor.
IO00Boot pin: LOW at reset = flash mode. Also the camera XCLK, so leave it alone at runtime.
IO1616Used by the PSRAM on most boards; avoid it.
IO44Drives the white flash LED (through a transistor) and is SD_D1.
IO2, IO14, IO152, 14, 15SD_D0, SD_CLK, SD_CMD. Needed even in 1-bit SD mode; 2 and 15 are strapping pins.
IO12, IO1312, 13SD_D2/D3 in 4-bit mode, free in 1-bit mode. GPIO12 must be LOW at boot.
No analog with Wi-Fi

Every header pin with an ADC is on ADC2, which the ESP32 cannot use while Wi-Fi is on. For analog sensors in a Wi-Fi project, use an I2C ADC module (for example ADS1115) on two free pins. Pins are 3.3 V only and not 5 V tolerant.

OV2640 Camera Pin Map

The camera plugs into a 24-pin FPC connector and uses 16 ESP32 signals: a clock, the SCCB control bus, sync lines and an 8-bit parallel data bus. These are the pins behind CAMERA_MODEL_AI_THINKER.

ESP32-CAM OV2640 camera pin map AI-Thinker: PWDN GPIO32, XCLK GPIO0, SIOD GPIO26, SIOC GPIO27, VSYNC GPIO25, HREF GPIO23, PCLK GPIO22, Y9 GPIO35, Y8 GPIO34, Y7 GPIO39, Y6 GPIO36, Y5 GPIO21, Y4 GPIO19, Y3 GPIO18, Y2 GPIO5 — Power4All
Control & sync on the left, the 8-bit pixel bus (Y2–Y9) on the right. Four data lines use the ESP32's input-only pins 34–39.

How the Board Fits Together

The ESP32 sits in the middle, streaming camera frames into PSRAM, compressing them to JPEG, then sending them over Wi-Fi or writing them to the SD card.

ESP32-CAM system block diagram: ESP32 D0WDQ6 connected to OV2640 camera DVP and SCCB, microSD SD_MMC, flash LED GPIO4, header pins, 4 MB flash, 4 MB PSRAM, PCB or IPEX antenna, red LED GPIO33 and AMS1117 regulator — Power4All
One ESP32 serves the camera, PSRAM, flash, SD card, LEDs and radio; the AMS1117 regulator supplies 3.3 V.

How to Program the ESP32-CAM with an FTDI Adapter

Because the board has no USB port, you upload through a USB-to-serial (FTDI) adapter. That takes four wires plus one jumper to put the chip into flash mode.

ESP32-CAM FTDI programming wiring diagram: FTDI GND to GND, FTDI VCC 5 V to 5V, FTDI TX to U0R GPIO3, FTDI RX to U0T GPIO1 and an IO0 to GND jumper for flash mode — Power4All
TX → U0R and RX → U0T (they cross). The IO0–GND jumper is only for uploading; remove it to run.
Power it from 5 V

Set the FTDI's jumper to 5 V and wire it to the 5V pin. Many FTDI boards can't supply enough current at 3.3 V, and the result is failed uploads and brownout resets.

The Easy Way: ESP32-CAM-MB

The ESP32-CAM-MB is a small shield with a micro-USB port and a CH340 USB-serial chip. Plug the ESP32-CAM on top and you get one-cable uploads and a Serial Monitor.

ESP32-CAM-MB USB programmer board diagram: two female 8-pin headers, CH340 USB-to-serial chip, IO0 and RST buttons and micro-USB port, with five upload steps — Power4All
No wires and no IO0 jumper: if the upload stalls at “Connecting…”, hold IO0, tap RST, then release IO0.

Upload Steps & Arduino IDE Settings

ESP32-CAM upload steps: wire FTDI, IO0 to GND, press RST, upload with AI Thinker ESP32-CAM and Huge APP partition, remove the jumper, press RST; fixes for Failed to connect and Timed out waiting for packet header — Power4All
Board AI Thinker ESP32-CAM, partition Huge APP (3 MB No OTA), then IO0→GND, RST, upload, remove the jumper, RST.

Which ESP32-CAM Pins Are Free?

This is the most-asked ESP32-CAM question. The answer depends on whether you use the SD card:

ESP32-CAM free GPIO guide: free without SD card 2, 4, 12, 13, 14, 15; free with SD 1-bit mode 4, 12, 13; use with care 0, 1, 3, 16; used by the camera 5, 18, 19, 21, 22, 23, 25, 26, 27, 32, 34, 35, 36, 39 — Power4All
No SD card: six free pins. SD in 1-bit mode: GPIO 4, 12, 13. The camera pins are never available.
  • Need I2C? Call Wire.begin(14, 15) (or 12/13) when you're not using the SD card. The ESP32 can route I2C to almost any pin; add pull-up resistors.
  • Need a button or sensor with SD? Use GPIO13 or GPIO12 with SD in 1-bit mode. Don't pull GPIO12 HIGH at boot.
  • Need more pins? Add an I2C I/O expander, or choose an ESP32-S3 camera board.

microSD Card: 4-bit vs 1-bit Mode

The slot uses the ESP32's fast SD_MMC host. In 4-bit mode it takes all six header GPIO; 1-bit mode is a little slower but gives three pins back.

ESP32-CAM microSD card pins diagram: DAT2 GPIO12, CD/DAT3 GPIO13, CMD GPIO15, VDD 3.3 V, CLK GPIO14, VSS GND, DAT0 GPIO2, DAT1 GPIO4; SD_MMC 4-bit mode vs 1-bit mode SD_MMC.begin sdcard true — Power4All
SD_MMC.begin() = 4-bit; SD_MMC.begin("/sdcard", true) = 1-bit (frees GPIO 4, 12, 13 and stops the flash LED flickering).

Power Supply & the Brownout Error

The #1 ESP32-CAM problem isn't code, it's power. The camera and Wi-Fi draw short current peaks, and a weak supply resets the board with “Brownout detector was triggered”.

ESP32-CAM power supply diagram: 5 V into the AMS1117 3.3 V LDO feeding the ESP32, PSRAM and camera LDOs; current draw idle 100-180 mA, streaming 250-310 mA, with flash LED over 400 mA; brownout detector fix — Power4All
Give it 5 V at 2 A, short wires, and a 470–1000 µF capacitor across 5V–GND.

Live Video Streaming (CameraWebServer)

The built-in CameraWebServer example turns the board into an IP camera you can watch from any browser on your network.

ESP32-CAM video streaming web server diagram: OV2640 to ESP32-CAM JPEG in PSRAM to Wi-Fi router to phone or laptop browser, with the control page on port 80, MJPEG stream on port 81 /stream and /capture for a still photo — Power4All
Control page at http://<IP>/, live stream at :81/stream, and a single photo at /capture.

Resolutions & Image Quality

The OV2640 goes up to UXGA (1600 × 1200), but bigger frames stream more slowly. For smooth video, start at SVGA or VGA.

ESP32-CAM OV2640 resolutions drawn to scale: UXGA 1600x1200, SXGA 1280x1024, XGA 1024x768, SVGA 800x600, VGA 640x480, CIF 400x296, QVGA 320x240, QQVGA 160x120 — Power4All
Set frame_size and jpeg_quality (10–63, lower = better) in camera_config_t.

Using an External Antenna

Weak Wi-Fi and a choppy stream? The module has an IPEX (u.FL) socket, but it only works once you move a tiny 0 Ω link.

ESP32-CAM external antenna diagram: 0 ohm resistor selecting the PCB antenna by default or the IPEX u.FL connector for an external 2.4 GHz antenna — Power4All
Move the 0 Ω resistor from the PCB position to the IPEX position, then plug in a 2.4 GHz antenna.

ESP32-CAM vs ESP32 DevKit vs ESP32-S3

ESP32-CAM vs ESP32 DevKit vs ESP32-S3 comparison: camera connector, PSRAM, microSD slot, USB, usable GPIO, Bluetooth, AI acceleration and best use — Power4All
The ESP32-CAM wins on price for a Wi-Fi camera; the ESP32-S3 adds native USB, more pins and AI acceleration.

Code Examples

Every camera sketch starts with the same pin configuration. Save Example 1 as camera_init.h and reuse it.

1. Initialise the camera (AI-Thinker pins)

#include "esp_camera.h"
bool initCamera() {
  camera_config_t c = {};
  c.ledc_channel = LEDC_CHANNEL_0;  c.ledc_timer = LEDC_TIMER_0;
  c.pin_d0 = 5;  c.pin_d1 = 18; c.pin_d2 = 19; c.pin_d3 = 21;   // Y2..Y5
  c.pin_d4 = 36; c.pin_d5 = 39; c.pin_d6 = 34; c.pin_d7 = 35;   // Y6..Y9
  c.pin_xclk = 0;  c.pin_pclk = 22; c.pin_vsync = 25; c.pin_href = 23;
  c.pin_sccb_sda = 26; c.pin_sccb_scl = 27;             // older cores: pin_sscb_*
  c.pin_pwdn = 32; c.pin_reset = -1;
  c.xclk_freq_hz = 20000000;
  c.pixel_format = PIXFORMAT_JPEG;
  c.frame_size   = FRAMESIZE_SVGA;                          // 800 x 600
  c.jpeg_quality = 12;                                     // 10-63, lower = better
  c.fb_count     = 1;
  return esp_camera_init(&c) == ESP_OK;
}

2. Blink the red status LED (GPIO33, active LOW)

void setup() { pinMode(33, OUTPUT); }
void loop() {
  digitalWrite(33, LOW);  delay(500);    // LOW = LED on
  digitalWrite(33, HIGH); delay(500);
}

3. Dim the flash LED with PWM (GPIO4)

void setup() { ledcAttach(4, 5000, 8); }    // core 3.x: pin, Hz, bits
void loop()  { ledcWrite(4, 20); }         // ~8 % brightness, very bright LED!

4. Take one photo and save it to the SD card

#include "SD_MMC.h"
// + initCamera() from Example 1
void setup() {
  Serial.begin(115200);
  if (!initCamera() || !SD_MMC.begin("/sdcard", true)) { Serial.println("init failed"); return; }
  camera_fb_t *fb = esp_camera_fb_get();                 // grab a JPEG frame
  File f = SD_MMC.open("/photo.jpg", FILE_WRITE);
  f.write(fb->buf, fb->len); f.close();
  esp_camera_fb_return(fb);
  Serial.println("saved /photo.jpg");
}
void loop() {}

ESP32-CAM Projects

Three popular builds, from a live Wi-Fi camera to a battery-friendly motion trap.

Project 1: Wi-Fi security camera (live stream)

Parts: ESP32-CAM, FTDI or ESP32-CAM-MB, 5 V 2 A supply. Uses the built-in example; no extra code.
// File > Examples > ESP32 > Camera > CameraWebServer
#define CAMERA_MODEL_AI_THINKER          // uncomment this model, comment the others
const char *ssid     = "my-ssid";
const char *password = "password";
// Upload, open Serial Monitor @115200, browse to the printed IP address
ESP32-CAM PIR motion sensor photo project wiring: HC-SR501 PIR VCC to 5V, OUT to GPIO13, GND to GND; ESP32-CAM wakes, takes a photo and saves it to microSD in 1-bit mode — Power4All
Project 2 wiring: PIR OUT → GPIO13 (free because SD runs in 1-bit mode), VCC → 5V, GND → GND.

Project 2: Motion-triggered photo trap

Parts: HC-SR501 PIR sensor, microSD card (FAT32). The board sleeps until motion, snaps a photo, saves it, then sleeps again.
#include "SD_MMC.h"
RTC_DATA_ATTR int n = 0;                              // photo counter survives deep sleep
// + initCamera() from Code Example 1
void setup() {
  if (initCamera() && SD_MMC.begin("/sdcard", true)) {    // 1-bit: frees GPIO13
    camera_fb_t *fb = esp_camera_fb_get();
    File f = SD_MMC.open("/pic" + String(++n) + ".jpg", FILE_WRITE);
    f.write(fb->buf, fb->len); f.close();
    esp_camera_fb_return(fb);
  }
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, 1);           // wake when PIR goes HIGH
  esp_deep_sleep_start();
}
void loop() {}

Project 3: Time-lapse recorder

Parts: microSD card and a 5 V supply. Same as Project 2, but it wakes on a timer: one photo every 60 s.
// Project 2 code, but replace the wake-up line with:
esp_sleep_enable_timer_wakeup(60 * 1000000ULL);          // 60 seconds
// Tip: the first frames after power-up can be dark/green — grab and
// discard one or two frames before saving the real photo.

ESP32-CAM Specifications

ESP32-CAM specifications table: ESP32-S module, dual-core 240 MHz, 520 KB SRAM, 4 MB PSRAM, 4 MB flash, OV2640 2 MP camera, microSD, Wi-Fi, Bluetooth 4.2, IPEX antenna, flash LED, 16 pins, no USB, 5 V input, 3.3 V logic, 27 x 40.5 mm — Power4All
Typical values for the common AI-Thinker style board; clones vary slightly.

Key Terms — Glossary

TermMeaning
OV2640The 2-megapixel image sensor with built-in JPEG compression.
FPCFlexible printed circuit: the thin ribbon that connects the camera.
DVPDigital video port: the 8-bit parallel camera bus plus sync lines.
SCCBThe camera's I2C-like control bus (SIOD/SIOC).
PSRAMExtra 4 MB RAM that holds camera frame buffers.
SD_MMCThe ESP32's fast SD card host, in 1-bit or 4-bit mode.
FTDIA common USB-to-serial (USB-TTL) adapter used to program boards without USB.
Flash modeBoot mode entered when GPIO0 is LOW at reset, used for uploading.
BrownoutA supply dip that makes the ESP32 reset itself for safety.
MJPEG“Motion JPEG”: video sent as a stream of JPEG pictures.
IPEX / u.FLA tiny coaxial socket for an external antenna.

Frequently Asked Questions

Quick answers to the questions people ask most about the ESP32-CAM.

What is the ESP32-CAM?

A low-cost ESP32 board with an OV2640 2 MP camera, 4 MB PSRAM, 4 MB flash, a microSD slot and a flash LED. It has Wi-Fi and Bluetooth, 16 header pins and no USB port, and is widely used for Wi-Fi cameras, streaming and photo projects.

How do I program the ESP32-CAM without a USB port?

Use an FTDI USB-to-serial adapter: GND→GND, VCC (5 V)→5V, TX→U0R, RX→U0T. Connect IO0 to GND, press RST, and upload with AI Thinker ESP32-CAM selected. Or plug the board into an ESP32-CAM-MB and use its micro-USB port.

Why does my ESP32-CAM say Brownout detector was triggered?

The supply dipped during a camera/Wi-Fi current peak. Use a stable 5 V supply rated about 2 A on the 5V pin, short thick wires and a 470–1000 µF capacitor across 5V–GND. Don't run it from an FTDI's 3.3 V pin.

Which GPIO pins are free on the ESP32-CAM?

The header exposes GPIO 0, 1, 2, 3, 4, 12, 13, 14, 15 and 16. Without the SD card, 2, 4, 12, 13, 14 and 15 are free; with SD in 1-bit mode, 4, 12 and 13 are free. GPIO0 is the camera clock and boot pin, 1/3 are serial and 16 is used by the PSRAM.

What camera does the ESP32-CAM use and what is the maximum resolution?

Usually an OV2640 2 MP camera with JPEG output up to UXGA (1600 × 1200). Use SVGA (800 × 600) or VGA (640 × 480) for smoother streaming.

How do I fix Failed to connect to ESP32: Timed out waiting for packet header?

The board isn't in flash mode or the wiring is wrong. Check IO0 is at GND, press RST just before uploading, confirm TX→U0R and RX→U0T, power the 5V pin at 5 V, and try a better USB cable.

Can the ESP32-CAM use an external antenna?

Yes. Move the tiny 0 Ω resistor next to the IPEX (u.FL) socket from the PCB-antenna position to the IPEX position, then plug in a 2.4 GHz antenna.

What is the ESP32-CAM-MB?

A programmer shield with a micro-USB port, a CH340 USB-serial chip and IO0/RST buttons. The ESP32-CAM plugs on top, so you can upload and use the Serial Monitor over one cable, with no FTDI and no jumper wires.

Conclusion & Key Takeaways

The ESP32-CAM is the cheapest route to a Wi-Fi camera. Once you know its three quirks (no USB, few free pins, needs good 5 V power), it's easy to use.

OV2640

2 MP, JPEG, up to UXGA.

No USB

FTDI or ESP32-CAM-MB.

IO0 → GND

to upload, then RST.

Free pins

4, 12, 13 with SD 1-bit.

5 V, 2 A

beats brownouts.

Flash LED

GPIO4 · red LED GPIO33.

Continue Learning