Blog

AI Thinker ESP32-CAM Development Board

AI Thinker ESP32-CAM Development Board

WiFi + Bluetooth with OV2640 Camera Module – Arduino Compatible IoT Camera Solution

Introduction

The ESP32-CAM is a compact development board combining ESP32-S chip with OV2640 camera module, perfect for IoT vision projects. It features WiFi/Bluetooth connectivity, microSD card slot, and GPIO pins in a minimal footprint.

ESP32-CAM Board

Key Features

📷 Camera Module

OV2640 (2MP with JPEG output)

📶 Dual Connectivity

WiFi + Bluetooth 4.2

💾 Storage Options

MicroSD card slot (up to 4GB)

Low Power

Deep sleep current ~6μA

Technical Specifications

Core Processor ESP32-S (Xtensa LX6 dual-core)
Clock Speed 240MHz (up to 600 DMIPS)
Wireless 802.11 b/g/n WiFi + Bluetooth 4.2
Camera OV2640 (2MP, 1600×1200 max)
Image Formats JPEG, BMP, Grayscale
RAM 520KB SRAM + 4MB PSRAM
Flash 4MB (default)
GPIO 9 usable pins (shared with camera)

Pin Configuration

ESP32-CAM Pinout

Pin Function Notes
3V3 3.3V Power Max 500mA
5V 5V Input When not using 3V3
GND Ground
GPIO 0 Boot Mode Pull LOW to flash
GPIO 2 LED/Serial Connected to onboard LED
GPIO 4 SD Card/General SD_MMC_D1
GPIO 12 SD Card/General SD_MMC_CLK
GPIO 13 Camera/General CAMERA_PCLK
GPIO 14 Camera/General CAMERA_XCLK
GPIO 15 Camera/General CAMERA_VSYNC
Note: Many GPIO pins are shared with camera functions – check documentation before use

Basic Setup

  1. Install Arduino IDE (1.8.10+)
  2. Add ESP32 board support via Boards Manager (URL: https://dl.espressif.com/dl/package_esp32_index.json)
  3. Select “AI Thinker ESP32-CAM” board
  4. Connect GPIO0 to GND to enter flash mode
  5. Connect via USB-to-TTL adapter (RX→TX, TX→RX, 3V3→3V3, GND→GND)

Camera Web Server Example

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

// Camera pins (AI Thinker ESP32-CAM)
#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

const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";

void startCameraServer();

void setup() {
  Serial.begin(115200);
  
  // Initialize camera
  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;
  // ... (complete all pin assignments)
  config.xclk_freq_hz = 20000000;
  config.pixel_format = PIXFORMAT_JPEG;
  
  if(psramFound()){
    config.frame_size = FRAMESIZE_UXGA;
    config.jpeg_quality = 10;
    config.fb_count = 2;
  } else {
    config.frame_size = FRAMESIZE_SVGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;
  }
  
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed: 0x%x", err);
    return;
  }
  
  // Connect to WiFi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  
  startCameraServer();
  Serial.print("Camera Ready! Use 'http://");
  Serial.print(WiFi.localIP());
  Serial.println("' to connect");
}

void loop() {
  delay(10000);
}

Image Capture to SD Card

#include "FS.h"
#include "SD_MMC.h"

void captureToSD() {
  camera_fb_t *fb = esp_camera_fb_get();
  if(!fb) {
    Serial.println("Camera capture failed");
    return;
  }
  
  // Initialize SD card
  if(!SD_MMC.begin()){
    Serial.println("SD Card Mount Failed");
    return;
  }
  
  // Save image
  String path = "/image" + String(millis()) + ".jpg";
  fs::FS &fs = SD_MMC; 
  File file = fs.open(path.c_str(), FILE_WRITE);
  
  if(!file){
    Serial.println("Failed to open file");
  } else {
    file.write(fb->buf, fb->len);
    Serial.printf("Saved: %s\n", path.c_str());
  }
  file.close();
  SD_MMC.end();
  
  esp_camera_fb_return(fb);
}

Optimization Tips

Image Quality

config.frame_size = FRAMESIZE_VGA;
config.jpeg_quality = 12; // 0-63 (lower=better)

Adjust resolution and quality based on available RAM

Power Saving

esp_sleep_enable_timer_wakeup(10000000);
esp_deep_sleep_start();

Use deep sleep between captures to save power

Motion Detection

if(abs(new_pixel - last_pixel) > threshold) {
  // Motion detected
}

Implement basic motion detection to trigger captures

Troubleshooting

Camera Not Initializing

  • Verify all camera pins are properly defined
  • Check power supply (needs 500mA+ for camera)
  • Ensure proper board selection in Arduino IDE

WiFi Connection Issues

  • Check antenna is properly connected
  • Try reducing WiFi transmit power
  • Verify credentials and network availability

SD Card Problems

  • Format card as FAT32 (max 4GB)
  • Check card detect pin (GPIO13)
  • Verify proper voltage level conversion if needed