Chapter 34 Camera Web Server
In this section, we’ll use ESP32’s video function as an example to study.
Project 34.1 Camera Web Server
Connect ESP32 using USB and check its IP address through serial monitor. Use web page to access IP address to obtain video and image data.
Component List
ESP32-WROVER x1
|
Micro USB Wire x1
|
Circuit
Connect Freenove ESP32 to the computer using the USB cable.
Sketch
Sketch_34.1_As_CameraWebServer
Before running the program, please modify your router’s name and password in the box shown in the illustration above to make sure that your Sketch can compile and work successfully.
If your Arduino IDE prompts you that your sketch is out of your project’s storage space, compile the code again as configured below.
Compile and upload codes to ESP32, open the serial monitor and set the baud rate to 115200, and the serial monitor will print out a network link address.
If your ESP32 has been in the process of connecting to router, but the information above has not been printed out, please re-check whether the router name and password have been entered correctly and press the reset key on ESP32-WROVER to wait for a successful connection prompt.
Open a web browser, enter the IP address printed by the serial monitor in the address bar, and access it.
Taking the Google browser as an example, here’s what the browser prints out after successful access to ESP32’s IP.
We recommend that the resolution not exceed VGA(640x480).
Click on Start Stream. The effect is shown in the image below.
Note
If sketch compilation fails due to ESP32 support package, follow the steps of the image to open the CameraWebServer. This sketch is the same as described in the tutorial above.
The following is the main program code. You need include other code files in the same folder when write your own code.
1/**********************************************************************
2 Filename : Camera Web Serrver
3 Description : ESP32 connects to WiFi and prints a url through a serial port.
4 Users visit the site to view the image data ESP32 camera.
5 Auther : www.freenove.com
6 Modification: 2026/05/16
7**********************************************************************/
8#include "esp_camera.h"
9#include <WiFi.h>
10#include "board_config.h"
11
12// ===================
13// Select camera model
14// ===================
15#define CAMERA_MODEL_WROVER_KIT // Has PSRAM
16//#define CAMERA_MODEL_ESP_EYE // Has PSRAM
17//#define CAMERA_MODEL_ESP32S3_EYE // Has PSRAM
18//#define CAMERA_MODEL_M5STACK_PSRAM // Has PSRAM
19//#define CAMERA_MODEL_M5STACK_V2_PSRAM // M5Camera version B Has PSRAM
20//#define CAMERA_MODEL_M5STACK_WIDE // Has PSRAM
21//#define CAMERA_MODEL_M5STACK_ESP32CAM // No PSRAM
22//#define CAMERA_MODEL_M5STACK_UNITCAM // No PSRAM
23//#define CAMERA_MODEL_AI_THINKER // Has PSRAM
24//#define CAMERA_MODEL_TTGO_T_JOURNAL // No PSRAM
25// ** Espressif Internal Boards **
26//#define CAMERA_MODEL_ESP32_CAM_BOARD
27//#define CAMERA_MODEL_ESP32S2_CAM_BOARD
28//#define CAMERA_MODEL_ESP32S3_CAM_LCD
29
30
31#include "camera_pins.h"
32
33const char* ssid_Router = "********";
34const char* password_Router = "********";
35camera_config_t config;
36
37void startCameraServer();
38void camera_init();
39
40void setup() {
41 Serial.begin(115200);
42 Serial.setDebugOutput(true);
43 Serial.println();
44
45 camera_init();
46
47 WiFi.begin(ssid_Router, password_Router);
48 WiFi.setSleep(false);
49 while (WiFi.status() != WL_CONNECTED) {
50 delay(500);
51 Serial.print(".");
52 }
53 Serial.println("");
54 Serial.println("WiFi connected");
55
56 startCameraServer();
57
58 Serial.print("Camera Ready! Use 'http://");
59 Serial.print(WiFi.localIP());
60 Serial.println("' to connect");
61}
62
63void loop() {
64 ;
65}
66
67void camera_init() {
68 config.ledc_channel = LEDC_CHANNEL_0;
69 config.ledc_timer = LEDC_TIMER_0;
70 config.pin_d0 = Y2_GPIO_NUM;
71 config.pin_d1 = Y3_GPIO_NUM;
72 config.pin_d2 = Y4_GPIO_NUM;
73 config.pin_d3 = Y5_GPIO_NUM;
74 config.pin_d4 = Y6_GPIO_NUM;
75 config.pin_d5 = Y7_GPIO_NUM;
76 config.pin_d6 = Y8_GPIO_NUM;
77 config.pin_d7 = Y9_GPIO_NUM;
78 config.pin_xclk = XCLK_GPIO_NUM;
79 config.pin_pclk = PCLK_GPIO_NUM;
80 config.pin_vsync = VSYNC_GPIO_NUM;
81 config.pin_href = HREF_GPIO_NUM;
82 config.pin_sccb_sda = SIOD_GPIO_NUM;
83 config.pin_sccb_scl = SIOC_GPIO_NUM;
84 config.pin_pwdn = PWDN_GPIO_NUM;
85 config.pin_reset = RESET_GPIO_NUM;
86 config.xclk_freq_hz = 10000000;
87 config.frame_size = FRAMESIZE_QVGA;
88 config.pixel_format = PIXFORMAT_JPEG; // for streaming
89 config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
90 config.fb_location = CAMERA_FB_IN_PSRAM;
91 config.jpeg_quality = 10;
92 config.fb_count = 1;
93
94 // camera init
95 esp_err_t err = esp_camera_init(&config);
96 if (err != ESP_OK) {
97 if(err==ESP_ERR_NOT_SUPPORTED){
98 config.pixel_format = PIXFORMAT_RGB565;
99 esp_err_t err = esp_camera_init(&config);
100 if (err != ESP_OK) {
101 Serial.printf("Camera init failed with error 0x%x", err);
102 return;
103 }
104 }
105 }
106
107 sensor_t * s = esp_camera_sensor_get();
108 // drop down frame size for higher initial frame rate
109 uint16_t pid = s->id.PID;
110 if(pid == OV2640_PID){
111 s->set_hmirror(s, 1);
112 s->set_vflip(s, 1);
113 }
114 else if(pid == OV3660_PID){
115 s->set_hmirror(s, 1);
116 s->set_vflip(s, 0);
117 }
118 else if(pid == GC2145_PID){
119 s->set_hmirror(s, 0);
120 delay(500);
121 s->set_vflip(s, 0);
122 }
123 else if(pid == GC0308_PID){
124 s->set_hmirror(s, 0);
125 delay(500);
126 s->set_vflip(s, 0);
127 }
128 else{
129 s->set_hmirror(s, 1);
130 s->set_vflip(s, 0);
131 }
132 s->set_brightness(s, 1); // Slightly increase brightness
133 s->set_saturation(s, 0); // Reduce saturation
134 s->set_ae_level(s, -3); // Set exposure compensation level
135}
Add procedure files and API interface files related to ESP32 camera.
1#include "esp_camera.h"
2#include <WiFi.h>
3#include "board_config.h"
4
5// ===================
6// Select camera model
7// ===================
8#define CAMERA_MODEL_WROVER_KIT // Has PSRAM
9//#define CAMERA_MODEL_ESP_EYE // Has PSRAM
10//#define CAMERA_MODEL_ESP32S3_EYE // Has PSRAM
11//#define CAMERA_MODEL_M5STACK_PSRAM // Has PSRAM
12//#define CAMERA_MODEL_M5STACK_V2_PSRAM // M5Camera version B Has PSRAM
13//#define CAMERA_MODEL_M5STACK_WIDE // Has PSRAM
14//#define CAMERA_MODEL_M5STACK_ESP32CAM // No PSRAM
15//#define CAMERA_MODEL_M5STACK_UNITCAM // No PSRAM
16//#define CAMERA_MODEL_AI_THINKER // Has PSRAM
17//#define CAMERA_MODEL_TTGO_T_JOURNAL // No PSRAM
18// ** Espressif Internal Boards **
19//#define CAMERA_MODEL_ESP32_CAM_BOARD
20//#define CAMERA_MODEL_ESP32S2_CAM_BOARD
21//#define CAMERA_MODEL_ESP32S3_CAM_LCD
22
23
Enter the name and password of the router
1
2const char* ssid_Router = "********";
Initialize serial port, set baud rate to 115200; open the debug and output function of the serial.
1void setup() {
2 Serial.begin(115200);
3 Serial.setDebugOutput(true);
Configure parameters including interface pins of the camera. Note: It is generally not recommended to change them.
1config.pin_pclk = PCLK_GPIO_NUM;
2config.pin_vsync = VSYNC_GPIO_NUM;
3config.pin_href = HREF_GPIO_NUM;
4config.pin_sccb_sda = SIOD_GPIO_NUM;
5config.pin_sccb_scl = SIOC_GPIO_NUM;
6config.pin_pwdn = PWDN_GPIO_NUM;
7config.pin_reset = RESET_GPIO_NUM;
8config.xclk_freq_hz = 10000000;
9config.frame_size = FRAMESIZE_QVGA;
10config.pixel_format = PIXFORMAT_JPEG; // for streaming
11config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
12config.fb_location = CAMERA_FB_IN_PSRAM;
13config.jpeg_quality = 10;
14config.fb_count = 1;
15
16// camera init
17esp_err_t err = esp_camera_init(&config);
18if (err != ESP_OK) {
19 if(err==ESP_ERR_NOT_SUPPORTED){
20 config.pixel_format = PIXFORMAT_RGB565;
21 esp_err_t err = esp_camera_init(&config);
22 if (err != ESP_OK) {
23 Serial.printf("Camera init failed with error 0x%x", err);
24 return;
25 }
26 }
27}
28
ESP32 connects to the router and prints a successful connection prompt. If it has not been successfully connected, press the reset key on the ESP32-WROVER.
1 Serial.print(WiFi.localIP());
2 Serial.println("' to connect");
3}
4
5void loop() {
6 ;
7}
8
Open the video streams server function of the camera and print its IP address via serial port.
1config.ledc_channel = LEDC_CHANNEL_0;
2config.ledc_timer = LEDC_TIMER_0;
3config.pin_d0 = Y2_GPIO_NUM;
4config.pin_d1 = Y3_GPIO_NUM;
5config.pin_d2 = Y4_GPIO_NUM;
Configure the display image information of the camera.
The set_vflip() function sets whether the image is flipped 180°, with 0 for no flip and 1 for flip 180°.
The set_brightness() function sets the brightness of the image, with values ranging from -2 to 2.
The set_saturation() function sets the color saturation of the image, with values ranging from -2 to 2.
1Serial.println("");
2Serial.println("WiFi connected");
3
4startCameraServer();
5
Modify the resolution and sharpness of the images captured by the camera. The sharpness ranges from 10 to 63, and the smaller the number, the sharper the picture. The larger the number, the blurrier the picture. Please refer to the table below.
config.frame_size = FRAMESIZE_VGA;
config.jpeg_quality = 10;
Reference
Image resolution |
Sharpness |
Image resolution |
Sharpness |
|---|---|---|---|
FRAMESIZE_96x96 |
96x96 |
FRAMESIZE_HVGA |
480x320 |
FRAMESIZE_QQVGA |
160x120 |
FRAMESIZE_VGA |
640x480 |
FRAMESIZE_QCIF |
176x144 |
FRAMESIZE_SVGA |
800x600 |
FRAMESIZE_HQVGA |
240x176 |
FRAMESIZE_XGA |
1024x768 |
FRAMESIZE_240x240 |
240x240 |
FRAMESIZE_HD |
1280x720 |
FRAMESIZE_QVGA |
320x240 |
FRAMESIZE_SXGA |
1280x1024 |
FRAMESIZE_CIF |
400x296 |
FRAMESIZE_UXGA |
1600x1200 |
We recommend that the resolution not exceed VGA(640x480).
Project 34.2 Video Web Server
Connect to ESP32 using USB and view its IP address through a serial monitor. Access IP addresses through web pages to obtain real-time video data.
Component List
ESP32-WROVER x1
|
Micro USB Wire x1
|
Circuit
Connect Freenove ESP32 to the computer using the USB cable.
Sketch
Sketch_34.2_As_VideoWebServer
Before running the program, please modify your router’s name and password in the box shown in the illustration above to make sure that your Sketch can compile and work successfully.
Compile and upload codes to ESP32, open the serial monitor and set the baud rate to 115200, and the serial monitor will print out a network link address.
If your ESP32 has been in the process of connecting to router, but the information above has not been printed out, please re-check whether the router name and password have been entered correctly and press the reset key on ESP32-WROVER to wait for a successful connection prompt.
Open a web browser, enter the IP address printed by the serial monitor in the address bar, and access it.
Taking the Google browser as an example, here’s what the browser prints out after successful access to ESP32’s IP.
The effect is shown in the image below.
The following is the main program code. You need include other code files in the same folder when write your own code.
1#include "esp_camera.h"
2#include <WiFi.h>
3//
4// WARNING!!! PSRAM IC required for UXGA resolution and high JPEG quality
5// Ensure ESP32 Wrover Module or other board with PSRAM is selected
6// Partial images will be transmitted if image exceeds buffer size
7//
8
9// Select camera model
10#define CAMERA_MODEL_WROVER_KIT // Has PSRAM
11
12#include "camera_pins.h"
13
14const char* ssid = "********"; //input your wifi name
15const char* password = "********"; //input your wifi passwords
16
17camera_config_t config;
18void camera_init();
19void startCameraServer();
20
21void setup() {
22 Serial.begin(115200);
23 Serial.setDebugOutput(true);
24 Serial.println();
25
26 camera_init();
27
28 WiFi.begin(ssid, password);
29 while (WiFi.status() != WL_CONNECTED) {
30 delay(500);
31 Serial.print(".");
32 }
33 Serial.println("");
34 Serial.println("WiFi connected");
35
36 startCameraServer();
37
38 Serial.print("Camera Ready! Use 'http://");
39 Serial.print(WiFi.localIP());
40 Serial.println("' to connect");
41}
42
43void loop() {
44 // put your main code here, to run repeatedly:
45 delay(10000);
46}
47
48void camera_init() {
49 config.ledc_channel = LEDC_CHANNEL_0;
50 config.ledc_timer = LEDC_TIMER_0;
51 config.pin_d0 = Y2_GPIO_NUM;
52 config.pin_d1 = Y3_GPIO_NUM;
53 config.pin_d2 = Y4_GPIO_NUM;
54 config.pin_d3 = Y5_GPIO_NUM;
55 config.pin_d4 = Y6_GPIO_NUM;
56 config.pin_d5 = Y7_GPIO_NUM;
57 config.pin_d6 = Y8_GPIO_NUM;
58 config.pin_d7 = Y9_GPIO_NUM;
59 config.pin_xclk = XCLK_GPIO_NUM;
60 config.pin_pclk = PCLK_GPIO_NUM;
61 config.pin_vsync = VSYNC_GPIO_NUM;
62 config.pin_href = HREF_GPIO_NUM;
63 config.pin_sccb_sda = SIOD_GPIO_NUM;
64 config.pin_sccb_scl = SIOC_GPIO_NUM;
65 config.pin_pwdn = PWDN_GPIO_NUM;
66 config.pin_reset = RESET_GPIO_NUM;
67 config.xclk_freq_hz = 10000000;
68 config.frame_size = FRAMESIZE_QVGA;
69 config.pixel_format = PIXFORMAT_JPEG; // for streaming
70 config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
71 config.fb_location = CAMERA_FB_IN_PSRAM;
72 config.jpeg_quality = 10;
73 config.fb_count = 1;
74
75 // camera init
76 esp_err_t err = esp_camera_init(&config);
77 if (err != ESP_OK) {
78 if(err==ESP_ERR_NOT_SUPPORTED){
79 config.pixel_format = PIXFORMAT_RGB565;
80 esp_err_t err = esp_camera_init(&config);
81 if (err != ESP_OK) {
82 Serial.printf("Camera init failed with error 0x%x", err);
83 return;
84 }
85 }
86 }
87
88 sensor_t * s = esp_camera_sensor_get();
89 // drop down frame size for higher initial frame rate
90 uint16_t pid = s->id.PID;
91 if(pid == OV2640_PID){
92 s->set_hmirror(s, 1);
93 s->set_vflip(s, 1);
94 }
95 else if(pid == OV3660_PID){
96 s->set_hmirror(s, 1);
97 s->set_vflip(s, 0);
98 }
99 else if(pid == GC2145_PID){
100 s->set_hmirror(s, 0);
101 delay(500);
102 s->set_vflip(s, 0);
103 }
104 else if(pid == GC0308_PID){
105 s->set_hmirror(s, 0);
106 delay(500);
107 s->set_vflip(s, 0);
108 }
109 else{
110 s->set_hmirror(s, 1);
111 s->set_vflip(s, 0);
112 }
113 s->set_brightness(s, 1); // Slightly increase brightness
114 s->set_saturation(s, 0); // Reduce saturation
115 s->set_ae_level(s, -3); // Set exposure compensation level
116}
117
Configure parameters including interface pins of the camera. Note: It is generally not recommended to change them.
1 Serial.println();
2
3 camera_init();
4
5 WiFi.begin(ssid, password);
6 while (WiFi.status() != WL_CONNECTED) {
7 delay(500);
8 Serial.print(".");
9 }
10 Serial.println("");
11 Serial.println("WiFi connected");
12
13 startCameraServer();
14
15 Serial.print("Camera Ready! Use 'http://");
16 Serial.print(WiFi.localIP());
17 Serial.println("' to connect");
18}
19
20void loop() {
21 // put your main code here, to run repeatedly:
ESP32 connects to the router and prints a successful connection prompt. If it has not been successfully connected, press the reset key on the ESP32-WROVER.
1config.pixel_format = PIXFORMAT_JPEG; // for streaming
2config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
3config.fb_location = CAMERA_FB_IN_PSRAM;
4config.jpeg_quality = 10;
5config.fb_count = 1;
6
7// camera init
8esp_err_t err = esp_camera_init(&config);
Open the video streams server function of the camera and print its IP address via serial port.
1if(err==ESP_ERR_NOT_SUPPORTED){
2 config.pixel_format = PIXFORMAT_RGB565;
3 esp_err_t err = esp_camera_init(&config);
4 if (err != ESP_OK) {
5 Serial.printf("Camera init failed with error 0x%x", err);

