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

Chapter01_00

Micro USB Wire x1

Chapter08_00

Circuit

Connect Freenove ESP32 to the computer using the USB cable.

../../../_images/Chapter32_01.png

Sketch

Sketch_34.1_As_CameraWebServer

../../../_images/Chapter34_00.png

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.

../../../_images/Chapter34_01.png

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.

../../../_images/Chapter34_02.png

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).

../../../_images/Chapter34_03.png

Click on Start Stream. The effect is shown in the image below.

../../../_images/Chapter34_04.png

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.

../../../_images/Chapter34_05.png

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

Chapter01_00

Micro USB Wire x1

Chapter08_00

Circuit

Connect Freenove ESP32 to the computer using the USB cable.

../../../_images/Chapter32_01.png

Sketch

Sketch_34.2_As_VideoWebServer

../../../_images/Chapter34_06.png

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.

../../../_images/Chapter34_07.png

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.

../../../_images/Chapter34_08.png

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);