ESP32-CAM (AI-Thinker)
Interactive ESP32-CAM pinout showing which pins the camera, microSD and PSRAM use, how to upload without USB, and a compile-checked first sketch.
Community draft — report a mistake
The AI-Thinker ESP32-CAM packs an ESP32, 4 MB of PSRAM, an OV2640 camera and a microSD slot onto a board smaller than a matchbox — the cheapest way to build a Wi-Fi camera, a door-bell or a time-lapse logger.
The trade-off is pins and USB. The camera occupies most of the chip’s GPIOs, the SD card shares the rest, and there is no USB port: you program it through a USB-serial adapter (or the ESP32-CAM-MB base board, which adds USB and the boot circuit).
Two LEDs are worth knowing: a tiny red one on GPIO33 (inverted) that is perfect for status, and the very bright white flash LED on GPIO4 — use it sparingly, it gets hot.
Interactive pinout
Hover or tap a pin for its functions and traps. Filter to light up every I2C, ADC or boot pin.
- Safe for most uses
- Works, with a caveat
- Avoid unless you know why
- Power / control
Power it from a solid 5 V supply. Camera start-up plus Wi-Fi pulls current spikes that brown out a weak supply. Use 5 V / 1 A or more on the 5V pin, not the 3.3 V pin.
Very few pins are really free. The camera uses most GPIOs internally, the microSD slot shares 2/4/12/13/14/15 and the PSRAM uses 16. Without an SD card, 12–15 and 2 are usable — mind the strapping rules on 2, 12 and 15.
Flashing without USB. Connect a 3.3 V USB-serial adapter (TX→U0R, RX→U0T, GND), bridge IO0 to GND, press RESET and upload. Remove the bridge and press RESET to run.
Set up your computer
- Install Arduino IDE 2.x from arduino.cc.
- File → Preferences → Additional boards manager URLs:
https://espressif.github.io/arduino-esp32/package_esp32_index.json - Boards Manager → install esp32 by Espressif Systems (we compile against esp32 3.3.12).
- Tools → Board → AI Thinker ESP32-CAM, then pick the port that appears when you plug the board in.
Your platformio.ini:
[env:esp32cam]
platform = espressif32
board = esp32cam
framework = arduino
monitor_speed = 115200[env:esp32cam] platform = espressif32 board = esp32cam framework = arduino monitor_speed = 115200
First program
// First program for the AI-Thinker ESP32-CAM: blink the small red LED on GPIO33 (back of the board).
// The red LED is INVERTED (LOW = on). We avoid GPIO4: it drives the very bright white flash LED.
// Upload: IO0 to GND, press RESET, upload, then remove the IO0 link and press RESET again.
constexpr uint8_t RED_LED = 33;
void setup() {
Serial.begin(115200);
pinMode(RED_LED, OUTPUT);
Serial.println("FlashReady: ESP32-CAM blink");
}
void loop() {
digitalWrite(RED_LED, LOW); // on
delay(500);
digitalWrite(RED_LED, HIGH); // off
delay(500);
}// First program for the AI-Thinker ESP32-CAM: blink the small red LED on GPIO33 (back of the board).
// The red LED is INVERTED (LOW = on). We avoid GPIO4: it drives the very bright white flash LED.
// Upload: IO0 to GND, press RESET, upload, then remove the IO0 link and press RESET again.
constexpr uint8_t RED_LED = 33;
void setup() {
Serial.begin(115200);
pinMode(RED_LED, OUTPUT);
Serial.println("FlashReady: ESP32-CAM blink");
}
void loop() {
digitalWrite(RED_LED, LOW); // on
delay(500);
digitalWrite(RED_LED, HIGH); // off
delay(500);
}Common errors
Camera init failed with error 0x105 / 0x20004
Wrong camera model selected in the sketch (use the AI-Thinker pin set), a loose ribbon cable, or not enough power. Reseat the ribbon with the latch fully closed and use a 5 V supply.
Brownout detector was triggered
The supply sags when the camera or Wi-Fi starts. Fix the power rather than disabling the detector.
Timed out waiting for packet header
IO0 is not tied to GND at reset, or TX/RX are swapped. Full fix guide.
Image is dark green or noisy
The first frames after start-up are often bad; discard one or two. Also check that PSRAM is enabled (Tools → PSRAM → Enabled) for larger frame sizes.
