ESP32 CAM, ESP32 CAM installation, ESP32 CAM programming, program ESP32 CAM, ESP32 CAM upload code, getting started with ESP32 CAM, ESP32 CAM pinout
ESP32-CAM Connected to the Programming Shield

In today’s tutorial, we’ll show you how to program the ESP32-CAM module. ESP32-CAM module is suitable for building basic surveillance or monitoring systems. Its price is quite reasonable. You can use it for lots of AI-based projects like object detection, face recognition etc. 

However, many users face hard luck when setting up and uploading code to ESP32-CAM development boards. This tutorial will provide you with a guideline for successfully programming the ESP32-CAM.  

Overview of the ESP32-CAM Development Board

The ESP32-CAM is a standalone development board that integrates an ESP32-S chip, a camera module, onboard flash memory, and a microSD card slot. It features built-in Wi-Fi and Bluetooth connectivity and supports OV2640 or OV7670 cameras with a resolution of up to 2 megapixels.

ESP32 CAM, ESP32 CAM installation, ESP32 CAM programming, program ESP32 CAM, ESP32 CAM upload code, getting started with ESP32 CAM, ESP32 CAM pinout
ESP32-CAM front and back view

Key Features:

  • Ultra-small 802.11b/g/n Wi-Fi + Bluetooth/BLE SoC module

  • Low-power, dual-core 32-bit processor with a clock speed of up to 240MHz and computing power of 600 DMIPS

  • 520 KB built-in SRAM and 4M external PSRAM

  • Supports multiple interfaces: UART, SPI, I2C, PWM, ADC, and DAC

  • Compatible with OV2640 and OV7670 cameras and includes built-in flash storage

  • Enables Wi-Fi-based image uploads and supports TF cards

  • Multiple sleep modes for power efficiency

  • Operates in STA, AP, and STA+AP modes

Specifications:

  • Dimensions: 27 × 40.5 × 4.5 mm

  • SPI Flash: Default 32Mbit

  • RAM: 520KB internal + 4M external PSRAM

  • Bluetooth: BT 4.2 BR/EDR and BLE

  • Wi-Fi Standards: 802.11 b/g/n/e/i

  • Interfaces: UART, SPI, I2C, PWM

  • TF Card Support: Up to 16GB (4G recommended)

  • GPIO Pins: 9 available

  • Image Output Formats: JPEG (only with OV2640), BMP, Grayscale

  • Antenna: Onboard with 2dBi gain

  • Security: WPA/WPA2/WPAS-Enterprise/WPS

  • Power Supply: 5V

  • Operating Temperature: -20°C to 85°C

Power Consumption:

  • Without flash: 180mA @ 5V

  • With max brightness flash: 310mA @ 5V

  • Deep sleep mode: 6mA @ 5V

  • Modem sleep mode: 20mA @ 5V

  • Light sleep mode: 6.7mA @ 5V

ESP32-CAM Pinout

The ESP32-CAM module has fewer accessible GPIO pins compared to a standard ESP32 board since many are allocated for the camera and SD card module. Certain pins should be avoided during programming:

  • GPIO1, GPIO3, and GPIO0 are essential for uploading code and should not be used for other functions.

  • GPIO0 is linked to the camera XCLK pin and should remain unconnected during normal operation. It must be pulled to GND only when uploading firmware.

  • P_OUT Pin: Labeled as VCC on some boards, this pin provides 3.3V or 5V output depending on the solder pad configuration. It cannot be used to power the board—use the dedicated 5V pin instead.

  • GPIO 2, 4, 12, 13, 14, and 15 are assigned to the SD card reader. If the SD card module is unused, these pins can be repurposed as general I/O.

ESP32 CAM, ESP32 CAM installation, ESP32 CAM programming, program ESP32 CAM, ESP32 CAM upload code, getting started with ESP32 CAM, ESP32 CAM pinout
ESP32-CAM Pinout

Notably, the onboard flash LED is connected to GPIO 4, meaning it may turn on when using the SD card reader. To prevent this behaviour, use the following code snippet:

SD_MMC.begin("/sdcard", true);


For an in-depth explanation of the ESP32-CAM pinout and GPIO usage, refer to the Random Nerd Tutorials guide: ESP32-CAM AI-Thinker Pinout Guide: GPIOs Usage Explained.

Schematic 

Following is a full schematic of the ESP32-CAM. 

ESP32 CAM, ESP32 CAM installation, ESP32 CAM programming, program ESP32 CAM, ESP32 CAM upload code, getting started with ESP32 CAM, ESP32 CAM pinout
ESP32-CAM Schematic

Driver installation

You need to install the CP210X driver on your computer to get the ESP32-CAM working. You can download the driver from here

Board installation

No matter which method you choose to program your ESP32-CAM, you need to do the board installation. If ESP32 boards are already installed in your Arduino IDE, feel free to skip this installation section. Go to File > preferences, type https://dl.espressif.com/dl/package_esp32_index.json and click OK. 

ESP32 CAM, ESP32 CAM installation, ESP32 CAM programming, program ESP32 CAM, ESP32 CAM upload code, getting started with ESP32 CAM, ESP32 CAM pinout
ESP32 Board Installation

  • Go to Tools>Board>Boards Manager and click ‘install’. 

ESP32 CAM, ESP32 CAM installation, ESP32 CAM programming, program ESP32 CAM, ESP32 CAM upload code, getting started with ESP32 CAM, ESP32 CAM pinout
ESP32 Library Installation

Install the ESP32-CAM library.

  • Download the ESP32-CAM library from Github (the link is given in the reference section). Follow the path sketch>include library> add.zip library. 

ESP32 CAM, ESP32 CAM installation, ESP32 CAM programming, program ESP32 CAM, ESP32 CAM upload code, getting started with ESP32 CAM, ESP32 CAM pinout

Now select the correct path to the library, click on the library folder and press open. 

ESP32 CAM, ESP32 CAM installation, ESP32 CAM programming, program ESP32 CAM, ESP32 CAM upload code, getting started with ESP32 CAM, ESP32 CAM pinout

Board selection and code uploading

Connect the camera board to your computer. Some camera boards come with a micro USB connector of their own. You can connect the camera to the computer using a micro USB data cable. If the board has no connector, you need to connect the FTDI module to the computer with the data cable. You will need to install the FTDI driver first.

  • When you’re done with the connection,  Go to Tools>boards>esp32>Ai thinker ESP32-CAM

ESP32 CAM, ESP32 CAM installation, ESP32 CAM programming, program ESP32 CAM, ESP32 CAM upload code, getting started with ESP32 CAM, ESP32 CAM pinout
ESP32 Camera board selection

After selecting the board, select the appropriate COM port and upload the following code:

Method 1: Using the ESP32-CAM Programmer Shield

ESP32-CAM programmer shield is made exclusively to program the ESP32-CAM. The shield is equipped with a USB-to-serial converter.  The built-in USB-to-serial converter simplifies the process of connecting the board to a computer for programming and debugging. It also includes a microSD card slot for expanded storage, enabling easy data storage and retrieval. Additionally, the shield features a power switch and an LED indicator, allowing for straightforward power control and status monitoring. With its compact design and user-friendly functionality, the ESP32-CAM-MB Programmer Shield is a valuable tool for developers working with the ESP32-CAM-MB board.

ESP32 CAM, ESP32 CAM installation, ESP32 CAM programming, program ESP32 CAM, ESP32 CAM upload code, getting started with ESP32 CAM, ESP32 CAM pinout
ESP32-CAM Programming Shield

Connecting ESP32-CAM with the Programmer Shield

Just connect the ESP32-CAM module on top of the Programming Shield as shown below, and connect a USB cable from the Programming Shield to your computer. Now you can program your ESP32-CAM.

ESP32 CAM, ESP32 CAM installation, ESP32 CAM programming, program ESP32 CAM, ESP32 CAM upload code, getting started with ESP32 CAM, ESP32 CAM pinout
ESP32-CAM Connected to the Programming Shield

Connecting the Programming Shield to Your Computer

First, take a functional  USB cable.  It should be securely connected and to the USB port of your computer. When plugged in, you should hear a notification sound from your computer. A red LED on the Programming Shield should illuminate. Next, confirm that you have selected the AI Thinker ESP32-CAM board and the appropriate Serial Port. Refer to the image below for guidance.

ESP32 CAM, ESP32 CAM installation, ESP32 CAM programming, program ESP32 CAM, ESP32 CAM upload code, getting started with ESP32 CAM, ESP32 CAM pinout
Selecting AI Thinker ESP32-CAM board and Serial Port

Press the upload button to upload your code.

ESP32 CAM, ESP32 CAM installation, ESP32 CAM programming, program ESP32 CAM, ESP32 CAM upload code, getting started with ESP32 CAM, ESP32 CAM pinout
Upload button in Arduino IDE

Press the IOo button of the programming shield. 

ESP32 CAM, ESP32 CAM installation, ESP32 CAM programming, program ESP32 CAM, ESP32 CAM upload code, getting started with ESP32 CAM, ESP32 CAM pinout
IO0 button on Programming Shield

The text ‘connecting’ should appear in the output panel.

ESP32 CAM, ESP32 CAM installation, ESP32 CAM programming, program ESP32 CAM, ESP32 CAM upload code, getting started with ESP32 CAM, ESP32 CAM pinout
Waiting to connect

While holding down the IOo button, press the RST button and release. See the following picture to know the location of the RST button, that you need to press.

ESP32 CAM, ESP32 CAM installation, ESP32 CAM programming, program ESP32 CAM, ESP32 CAM upload code, getting started with ESP32 CAM, ESP32 CAM pinout
IOo and RST Buttons

When the dots in the text “Connecting …..” stop appearing you can release the IO0 button as well. If the following text appears, it indicates that the code is being uploaded:

ESP32 CAM, ESP32 CAM installation, ESP32 CAM programming, program ESP32 CAM, ESP32 CAM upload code, getting started with ESP32 CAM, ESP32 CAM pinout
Code loaded successfully

Running Mode

When the code is uploaded, you will see the message “Hard resetting via RTS pin…” in the Output Panel. You must press the RST button on the ESP32-CAM module to run the uploaded program. Avoid using the RST button on the Programming Shield. Also, do not press the IO0 button.

Test Code for ESP32-CAM with Programming Shield

This simple Blink program turns on the Flash LED on the ESP32-CAM for 10 milliseconds, then waits for 2 seconds before repeating the cycle.

int flashPin = 4;

void setup() {

  pinMode(flashPin, OUTPUT);

}


void loop() {

  digitalWrite(flashPin, HIGH);

  delay(10);

  digitalWrite(flashPin, LOW);

  delay(2000);

}

You will see the LED flashing if the code is uploaded without any problem. 

Method 2: Programming ESP32-CAM with FTDI programmer.

List of components


ESP32 CAM, ESP32 CAM installation, ESP32 CAM programming, program ESP32 CAM, ESP32 CAM upload code, getting started with ESP32 CAM, ESP32 CAM pinout

Components

Quantity

ESP32-CAM WiFi + Bluetooth Camera Module

1

FTDI USB to Serial Converter 3V3-5V

1

Male-to-female jumper wires

4

Female-to-female jumper wire

1

MicroUSB data cable

1

Circuit diagram

Following is the circuit diagram of this project.

ESP32 CAM, ESP32 CAM installation, ESP32 CAM programming, program ESP32 CAM, ESP32 CAM upload code, getting started with ESP32 CAM, ESP32 CAM pinout
Circuit Diagram

ESP32 CAM, ESP32 CAM installation, ESP32 CAM programming, program ESP32 CAM, ESP32 CAM upload code, getting started with ESP32 CAM, ESP32 CAM pinout

ESP32-CAM WiFi + Bluetooth Camera Module FTDI USB to Serial Converter 3V3-5V (Voltage selection button should be in 5V position)

5V

VCC

GND

GND

UOT

Rx

UOR

TX

IO0

GND (FTDI or ESP32-CAM)

Programming

Testing Code for ESP32-CAM with FTDI Programmer

This code functions similarly to a standard Blink program but gradually increases the brightness of the flash LED over 255 steps before turning it off for a second and repeating the cycle.

int flashPin = 4;


void setup() {

  pinMode(flashPin, OUTPUT);

}


void loop() {

  for (int brightness = 0; brightness < 255; brightness++) {

    analogWrite(flashPin, brightness);

    delay(1);

  }

  analogWrite(flashPin, 0);

  delay(1000);

}


Since programming the ESP32-CAM (even with the FTDI Programmer) can be cumbersome, it’s advisable to first verify the functionality of the SD card and camera before attempting more complex projects. The following sections outline how to do this.


Testing the SD Card

The ESP32-CAM officially supports up to 4GB microSD cards, but 8GB and 16GB cards generally work fine. Larger cards require reformatting to FAT32, which can be done using guiformat.exe from Ridgecrop.

The test program below creates a file, writes a test message to it, and reads back the content. If the output matches expectations, the SD card is functioning correctly.

#include "SD_MMC.h"

#include "FS.h"

#include "LittleFS.h"


int flashPin = 4;


void setup() {

  Serial.begin(115200);  

  SD_MMC.begin();

  LittleFS.begin(true);


  // Create and write a test file

  File file = LittleFS.open("/test.txt", FILE_WRITE);

  file.print("*** Test successful ***");

  file.close();


    file = LittleFS.open("/test.txt");

  while (file.available()) {

    Serial.write(file.read());

  }

  file.close();


  // Set the flash LED as output 

  pinMode(flashPin, OUTPUT);

// turn the LED off

  analogWrite(flashPin, 0);

}


void loop() {

}


Code Breakdown

1. Libraries & Initialization:


#include "SD_MMC.h"

#include "FS.h"

#include "LittleFS.h"


Additionally, we define flashPin to control the flash LED:

int flashPin = 4;


2. Setup Function:
The setup() function initializes serial communication at 115200 baud:

Serial.begin(115200);


Then we need to initialize the SD card and LittleFS file system. The argument true ensures that LittleFS is formatted if it isn't already:

SD_MMC.begin();

LittleFS.begin(true);


A file named test.txt is created, a test message is written, and the file is closed:

File file = LittleFS.open("/test.txt", FILE_WRITE);

file.print("*** Test successful ***");

file.close();


The file is reopened in read mode, its contents are printed to the serial monitor, and then it is closed:

file = LittleFS.open("/test.txt");

while (file.available()) {

  Serial.write(file.read());

}

file.close();


We need to turn off the flash LED. 

pinMode(flashPin, OUTPUT);

analogWrite(flashPin, 0);


3. Loop Function:
The loop() function remains empty since the entire process occurs within setup(). 


Serial Monitor Output

If the SD card test is successful, you will see *** Test successful ***

in the Serial Monitor.

This confirms that data can be written to and read from the SD card.

Additional SD Card Testing

For more extensive diagnostics, you can use the SDMMC_Test.ino example provided in the ESP32 library. This program includes additional debugging information and can be accessed via:

File > Examples > Examples for AI-Thinker ESP32-CAM > SDMMC > SDMMC_Test

Testing the Camera

After verifying the SD card, the next step is to test the camera module. The following is a simplified program that captures an image each time the ESP32-CAM is reset. The image will be saved in the SD card.

#include "esp_camera.h"

#include "soc/rtc_cntl_reg.h"

#include "SD_MMC.h"

#include "EEPROM.h"

// Pin configuration for AI-Thinker ESP32-CAM module

#define PWDN_GPIO_NUM     32

#define RESET_GPIO_NUM    -1

#define XCLK_GPIO_NUM      0

#define SIOD_GPIO_NUM     26

#define SIOC_GPIO_NUM     27

#define Y9_GPIO_NUM       35

#define Y8_GPIO_NUM       34

#define Y7_GPIO_NUM       39

#define Y6_GPIO_NUM       36

#define Y5_GPIO_NUM       21

#define Y4_GPIO_NUM       19

#define Y3_GPIO_NUM       18

#define Y2_GPIO_NUM        5

#define VSYNC_GPIO_NUM    25

#define HREF_GPIO_NUM     23

#define PCLK_GPIO_NUM     22

void configCamera() {

  camera_config_t config;

  config.ledc_channel = LEDC_CHANNEL_0;

  config.ledc_timer = LEDC_TIMER_0;

  config.pin_d0 = Y2_GPIO_NUM;

  config.pin_d1 = Y3_GPIO_NUM;

  config.pin_d2 = Y4_GPIO_NUM;

  config.pin_d3 = Y5_GPIO_NUM;

  config.pin_d4 = Y6_GPIO_NUM;

  config.pin_d5 = Y7_GPIO_NUM;

  config.pin_d6 = Y8_GPIO_NUM;

  config.pin_d7 = Y9_GPIO_NUM;

  config.pin_xclk = XCLK_GPIO_NUM;

  config.pin_pclk = PCLK_GPIO_NUM;

  config.pin_vsync = VSYNC_GPIO_NUM;

  config.pin_href = HREF_GPIO_NUM;

  config.pin_sscb_sda = SIOD_GPIO_NUM;

  config.pin_sscb_scl = SIOC_GPIO_NUM;

  config.pin_pwdn = PWDN_GPIO_NUM;

  config.pin_reset = RESET_GPIO_NUM;

  config.xclk_freq_hz = 20000000;

  config.pixel_format = PIXFORMAT_JPEG;

  config.frame_size = FRAMESIZE_UXGA;

  config.jpeg_quality = 10;

  config.fb_count = 2;

  esp_camera_init(&config);

}

unsigned int incrementCounter() {

  unsigned int counter = 0;

  EEPROM.get(0, counter);

  EEPROM.put(0, counter + 1);

  EEPROM.commit();

  return counter;

}


void captureImage() {

  camera_fb_t* fb = esp_camera_fb_get();

  unsigned int counter = incrementCounter();

  String filename = "/pic" + String(counter) + ".jpg";

  Serial.println(filename);

  File file = SD_MMC.open(filename.c_str(), FILE_WRITE);

  file.write(fb->buf, fb->len);

  file.close();

  esp_camera_fb_return(fb);

}

void setup() {

  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);

  Serial.begin(115200);

  SD_MMC.begin();

  EEPROM.begin(16);

  configCamera();

  captureImage();

  esp_deep_sleep_start();

}

void loop() {

}

Code Overview

  • The configCamera() function sets up the camera with the appropriate pin configurations.

  • The incrementCounter() function tracks the number of captured images using EEPROM.

  • The captureImage() function takes a picture and saves it to the SD card.

  • The setup() function initializes the camera and SD card, captures an image, and puts the ESP32-CAM into deep sleep mode to conserve power.

This basic framework can be expanded for use cases such as motion-triggered or interval-based image capture.

Frequently Asked Questions

Here are some common problems that you may face while working with the ESP32-CAM.  You have provided the solutions too. 

Wi-Fi Connectivity

Q: Why isn’t my ESP32-CAM connecting to Wi-Fi?
A: Check if you have entered the right SSID and password.

Camera & Image Quality

Q: Is there any way to improve the image quality of the camera?
A: Adjust the camera settings in your code, experimenting with different resolutions and frame rates for the best results.

Q: Why are my images blurry or unclear?
A: Poor lighting conditions can degrade image quality. Ensure proper lighting, fine-tune camera settings, and remove the protective lens foil.

Serial Communication & Code Upload

Q: Why the camera is not responding to serial monitor commands?
A:  Check the connections between the board and the computer. Also, confirm that the baud rate (115200) in your code matches the serial monitor settings.

Q: Why do I see  “Timed out waiting for packet header” during code upload?

 A: An unstable USB connection may cause this problem. You can try a different USB cable or PORT. 

Q: What to do if the  ESP32-CAM freezes during code upload?
A: Disconnect and reconnect the USB cable, reset the board, and attempt the upload again. Check that your code isn't causing crashes.

Q: How to resolve the error “A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header”?
A: This may be caused by an incorrect baud rate or a faulty USB cable. 

SD Card Issues

Q: Why isn’t my SD card being detected?
A: The SD card is properly inserted and formatted as FAT32. Cards between 4GB and 16GB work best, while higher-capacity cards may cause issues.

Power & Performance

Q: My ESP32-CAM gets hot—should I be concerned?
A: It’s normal for the board to warm up during operation, but excessive heat could indicate a short circuit or power issue.

Q: How can I reduce power consumption?
A: Use sleep modes.

Other Camera Issues

Q: Why isn’t my ESP32-CAM capturing images?
A: Check that the camera module is securely connected, and ensure the correct camera module type is defined in your code.

Q: Can I use ESP32-CAM for video streaming?
A: Use a web server library such as ESP32-CAM-Webserver to stream video over Wi-Fi. Ensure your network can handle the required bandwidth.

Bootloader & OTA Programming

Q: Why won’t my ESP32-CAM enter bootloader mode?
A: Ensure GPIO0 is connected to GND, and press the reset button at the correct moment to enter bootloader mode.

Q: Can I upload code wirelessly?
A: Yes, for that you have to use Over-The-Air (OTA) programming. 

If you continue to experience issues, double-check the wiring, connections, and settings in your code.