1.3 Camera Web Server
Stream live camera video over Wi-Fi with the ESP32-S3’s built-in web server.
Overview
This example turns the board into a wireless IP camera. It initializes the OV3660 camera, connects to Wi-Fi, and starts an HTTP server that streams live MJPEG video — viewable in any browser on the same network.
What You’ll Learn
Initializing the camera with the
esp_cameralibraryConnecting the ESP32-S3 to a Wi-Fi network
Running an embedded HTTP server for video streaming
Understanding ESP32-S3 camera pin mapping (DCMI interface)
Before You Begin
Complete the setup steps in Preparation before continuing.
Note
Use the recommended Arduino IDE settings in Recommended Board Settings unless this lesson says otherwise.
Open the example sketch from the code package:
LAFVIN-ESP32-S3-Multimedia-Kit-main/1.Arduino/3.CameraWebServer/3.CameraWebServer.ino
This example uses the onboard camera module. No external wiring is required — the camera connects directly to the board through its dedicated camera interface.
Important
You must edit the ssid and password variables at the top of the sketch to match your Wi-Fi network before uploading.
Upload and Test
Connect the board with a USB Type-C data cable.
Open
3.CameraWebServer.inoin Arduino IDE.Set your Wi-Fi SSID and password in the sketch.
In the Tools menu, select
ESP32S3 Dev Moduleas the board and choose the correct serial port.Click Upload.
Open Serial Monitor, set the baud rate to
115200, and wait for the IP address to appear:WiFi connected Camera Ready! Use 'http://192.168.1.100' to connect
Open a web browser on any device connected to the same Wi-Fi network and enter the IP address. You will see a live camera stream page with controls.
If you see Camera init failed, double-check the camera module is firmly seated in its connector.
How the Code Works
Camera Initialization
The sketch sets up the camera with a pin configuration table for the ESP32-S3 Eye model:
#include "esp_camera.h"
camera_config_t config;
config.pin_pwdn = -1; // Not used
config.pin_reset = -1; // Not used
config.pin_xclk = 15;
config.pin_sccb_sda = 4;
config.pin_sccb_scl = 5;
config.pin_d0 = 11; // Y2
config.pin_d1 = 9; // Y3
// ... D2–D7 mapped to GPIOs 8, 10, 12, 18, 17, 16
config.frame_size = FRAMESIZE_QVGA; // 320x240
config.pixel_format = PIXFORMAT_JPEG;
config.fb_count = 2; // Double-buffered
esp_err_t err = esp_camera_init(&config);
Wi-Fi Connection
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Web Server
The HTTP server captures camera frames on demand and streams them as MJPEG to connected clients. Frame capture uses esp_camera_fb_get() to grab a JPEG buffer from the camera, which is served directly over HTTP.
In the provided sketch:
The camera model is auto-detected or set to
CAMERA_MODEL_ESP32S3_EYEPSRAM is enabled for double-buffered frame handling
The web server runs in its own FreeRTOS task, so
loop()can remain empty
Try This Next
Change
FRAMESIZE_QVGAtoFRAMESIZE_UXGA(1600x1200) for higher resolution (requires more bandwidth)Experiment with flash control if your camera module has an LED