Skip to main content
Get up and running with USB video streaming in just a few steps. This guide will walk you through creating your first UVC camera application.

Prerequisites

Before you begin, make sure you have:
1

Hardware Ready

  • ESP32-S2 or ESP32-S3 development board with USB host support
  • USB camera (UVC compatible)
  • USB cable for connecting camera to ESP32
  • Power supply (camera may need external power)
2

Software Installed

  • Arduino IDE (1.8.x or 2.x)
  • arduino-esp32 >= v2.0.14
  • ESP32_USB_STREAM library installed
If you haven’t installed the library yet, see Installation.

Your First UVC Camera Application

Let’s create a simple application that captures video frames from a USB camera.

Step 1: Create a New Sketch

Create a new Arduino sketch and include the library:
#include <Arduino.h>
#include "USB_STREAM.h"

Step 2: Define the Frame Callback

Create a callback function that will be called when each new frame arrives:
static void onCameraFrameCallback(uvc_frame *frame, void *user_ptr)
{
    Serial.printf("Frame received! format=%d, seq=%u, width=%u, height=%u, length=%u\n",
                  frame->frame_format, 
                  frame->sequence, 
                  frame->width, 
                  frame->height, 
                  frame->data_bytes);
}

Step 3: Complete Setup Code

Here’s the complete setup() function:
void setup()
{
    Serial.begin(115200);
    
    // 1. Instantiate USB_STREAM object
    USB_STREAM *usb = new USB_STREAM();

    // 2. Allocate memory buffers
    uint8_t *_xferBufferA = (uint8_t *)malloc(55 * 1024);
    assert(_xferBufferA != NULL);
    uint8_t *_xferBufferB = (uint8_t *)malloc(55 * 1024);
    assert(_xferBufferB != NULL);
    uint8_t *_frameBuffer = (uint8_t *)malloc(55 * 1024);
    assert(_frameBuffer != NULL);

    // 3. Configure UVC parameters
    usb->uvcConfiguration(
        FRAME_RESOLUTION_ANY,      // width: accept any resolution
        FRAME_RESOLUTION_ANY,      // height: accept any resolution
        FRAME_INTERVAL_FPS_15,     // 15 frames per second
        55 * 1024,                 // transfer buffer size
        _xferBufferA,              // transfer buffer A
        _xferBufferB,              // transfer buffer B
        55 * 1024,                 // frame buffer size
        _frameBuffer               // frame buffer
    );

    // 4. Register callback function
    usb->uvcCamRegisterCb(&onCameraFrameCallback, NULL);

    // 5. Start streaming
    usb->start();

    // 6. Wait for camera to connect
    usb->connectWait(1000);
    
    Serial.println("Camera streaming started!");
}

void loop()
{
    vTaskDelay(100);  // Minimal delay
}

Step 4: Upload and Test

  1. Connect your ESP32 board to your computer
  2. Select the correct board and port in Arduino IDE
  3. Upload the sketch
  4. Connect a USB camera to the ESP32’s USB host port
  5. Open Serial Monitor (115200 baud)

Expected Output

You should see output like this in the Serial Monitor:
Camera streaming started!
Frame received! format=7, seq=0, width=640, height=480, length=38400
Frame received! format=7, seq=1, width=640, height=480, length=38400
Frame received! format=7, seq=2, width=640, height=480, length=38400
...

Understanding the Configuration

Let’s break down the key configuration parameters:
FRAME_RESOLUTION_ANY
constant
Accepts any resolution the camera supports. You can also specify exact values like 640, 480, etc.
FRAME_INTERVAL_FPS_15
constant
Sets the frame rate to 15 FPS. Other options: FRAME_INTERVAL_FPS_5, FRAME_INTERVAL_FPS_10, FRAME_INTERVAL_FPS_20, FRAME_INTERVAL_FPS_30
Transfer Buffers
uint8_t*
Two buffers for double-buffering USB transfers. Size must be >= one frame size. 55KB is a safe default for most resolutions.
Frame Buffer
uint8_t*
Buffer to store the complete assembled frame. Size must be >= one frame size.

Buffer Size Guidelines

Choose buffer sizes based on your resolution:
ResolutionFrame Size (MJPEG)Recommended Buffer
320x240~15-20 KB25 KB
640x480~30-40 KB55 KB
800x600~50-60 KB80 KB
1280x720~80-100 KB120 KB

Next Steps

Advanced Features

Learn about suspend/resume, dynamic resolution changes, and advanced configuration

Audio Streaming

Add USB audio (microphone/speaker) to your application

Memory Optimization

Optimize buffer allocation and memory usage

API Reference

Explore the complete API documentation

Troubleshooting

Possible causes:
  • Camera not powered properly
  • Incorrect USB wiring
  • Camera not UVC compatible
Solutions:
  • Check USB D+/D- connections (GPIO 19/20)
  • Ensure camera has sufficient power
  • Try a different camera
  • Check serial output for error messages
Cause: Not enough heap memory available for buffer allocation.Solutions:
  • Reduce buffer sizes
  • Use ESP32-S3 with PSRAM
  • Check other memory allocations in your code
Possible causes:
  • Camera requires specific resolution/format
  • Insufficient USB bandwidth
  • Timing issues
Solutions:
  • Try specifying exact resolution instead of FRAME_RESOLUTION_ANY
  • Reduce frame rate
  • Add longer delay after start() before connectWait()
For more troubleshooting tips, see the Troubleshooting Guide.

Build docs developers (and LLMs) love