How to Set Up ESP32-CAM with FTDI Module: Complete Guide for Beginners

To set up and use the ESP32-CAM with an FTDI module for uploading code and communication, follow these steps carefully. I’ll guide you through the hardware connections and provide you with an example code to get started.

Components Needed:

  1. ESP32-CAM module
  2. FTDI module (USB-to-Serial adapter)
  3. Jumper wires
  4. Breadboard (optional)
  5. External 5V power supply (optional but recommended)

Step 1: Wiring Connections (ESP32-CAM + FTDI Module)

The ESP32-CAM works at 3.3V logic, but the FTDI module typically communicates at 5V, so make sure to connect the correct pins.

Here’s how to connect the ESP32-CAM and FTDI module:

ESP32-CAM PinFTDI PinDescription
GNDGNDGround connection
5VVCC5V (Use a 5V power supply)
U0T (TX)RX (FTDI)FTDI RX to ESP32-CAM TX
U0R (RX)TX (FTDI)FTDI TX to ESP32-CAM RX
IO0 (GPIO0)GNDPull GPIO0 to GND for flashing
  • Important: IO0 (GPIO0) pin must be grounded (connected to GND) during the upload process to put the ESP32-CAM into flashing mode. After uploading the code, you can disconnect GPIO0 from GND.

Step 2: Set Up Software and Environment

You will need the Arduino IDE or PlatformIO to program the ESP32-CAM.

1. Install Arduino IDE (if you don’t have it already).

2. Add ESP32 Board Support:

  • Open Arduino IDE.
  • Go to File > Preferences.
  • In the Additional Boards Manager URL field, add:
    https://dl.espressif.com/dl/package_esp32_index.json
  • Then go to Tools > Board > Board Manager and search for ESP32. Install it.

3. Select Board and Port:

  • After installing the ESP32 board, select ESP32 Wrover Module or the correct ESP32 board in Tools > Board.
  • Select the correct COM port where your FTDI module is connected.

Step 3: Code for ESP32-CAM (Basic Example)

Here’s a simple example that streams video from the ESP32-CAM’s camera to a web browser.

Example Code for ESP32-CAM (Camera Web Stream)

#include "esp_camera.h"
#include <WiFi.h>
#include <WebServer.h>

// WiFi Credentials
const char* ssid = "Enter WiFi User ID";
const char* password = "Enter Wifi Password";

WebServer server(80);
WiFiServer streamServer(81);

// AI Thinker ESP32-CAM Pins
#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 startCamera() {

  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;

  // Grayscale camera
  config.pixel_format = PIXFORMAT_GRAYSCALE;

  config.frame_size = FRAMESIZE_QVGA;   // 320x240
  config.jpeg_quality = 12;
  config.fb_count = 1;
  config.grab_mode = CAMERA_GRAB_LATEST;

  esp_err_t err = esp_camera_init(&config);

  if (err != ESP_OK) {
    Serial.printf("Camera Init Failed: 0x%x\n", err);
    while (true);
  }

  Serial.println("Camera Ready");
}

void handleRoot() {

  String html =
  "<html><head>"
  "<meta name='viewport' content='width=device-width, initial-scale=1'>"
  "<title>ESP32-CAM Stream</title>"
  "</head><body>"
  "<h2 align='center'>ESP32-CAM Live Stream</h2>"
  "<div align='center'>"
  "<img src='http://" + WiFi.localIP().toString() + ":81/stream'>"
  "</div>"
  "</body></html>";

  server.send(200, "text/html", html);
}

void streamVideo() {

  WiFiClient client = streamServer.available();

  if (!client) return;

  Serial.println("Client Connected");

  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: multipart/x-mixed-replace; boundary=frame");
  client.println();

  while (client.connected()) {

    camera_fb_t *fb = esp_camera_fb_get();

    if (!fb) {
      Serial.println("Capture Failed");
      continue;
    }

    uint8_t *jpg_buf = NULL;
    size_t jpg_len = 0;

    bool converted = frame2jpg(fb, 40, &jpg_buf, &jpg_len);

    if (converted) {

      client.printf("--frame\r\n");
      client.printf("Content-Type: image/jpeg\r\n");
      client.printf("Content-Length: %u\r\n\r\n", jpg_len);

      client.write(jpg_buf, jpg_len);
      client.printf("\r\n");

      free(jpg_buf);
    }

    esp_camera_fb_return(fb);

    delay(30);
  }

  Serial.println("Client Disconnected");
}

void streamTask(void *pvParameters) {

  while (true) {
    streamVideo();
    vTaskDelay(1);
  }
}

void setup() {

  Serial.begin(115200);
  delay(1000);

  startCamera();

  WiFi.begin(ssid, password);

  Serial.print("Connecting to WiFi");

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println();
  Serial.println("WiFi Connected");

  Serial.print("Open Browser: http://");
  Serial.println(WiFi.localIP());

  server.on("/", handleRoot);
  server.begin();

  streamServer.begin();

  xTaskCreatePinnedToCore(
    streamTask,
    "streamTask",
    8192,
    NULL,
    1,
    NULL,
    0
  );
}

void loop() {
  server.handleClient();
}

Step 4: Upload the Code

  • Once you have everything connected and the code ready, click the Upload button in the Arduino IDE to upload the code to the ESP32-CAM.
  • During the upload, GPIO0 must remain grounded to enable flash mode.
  • After the upload is complete, disconnect GPIO0 from GND and press the Reset button on the ESP32-CAM.

Step 5: Viewing the Video Stream

  • Open the Serial Monitor in Arduino IDE (set the baud rate to 115200).
  • After the ESP32-CAM connects to your Wi-Fi, you should see the IP address printed in the serial monitor.
  • Open a web browser and enter the IP address followed by port 81 (e.g., http://***.***.*.x:**).
  • You should now see the camera stream live in your browser.

Additional Tips:

  1. Power Requirements: ESP32-CAM can sometimes draw more power than the FTDI module provides. If you’re having trouble with stability, consider using an external 5V power supply to power the ESP32-CAM.
  2. Camera Quality: Adjust the frame size and JPEG quality for better performance or lower latency in the code above.
  3. GPIO0 and Reset: Always keep an eye on the GPIO0 pin to ensure it’s properly configured for flashing or running mode.