Camera Web Server

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

//
// WARNING!!! PSRAM IC required for UXGA resolution and high JPEG quality
//            Ensure ESP32 Wrover Module or other board with PSRAM is selected
//            Partial images will be transmitted if image exceeds buffer size
//

// Select camera model
#define CAMERA_MODEL_WROVER_KIT // Has PSRAM
//#define CAMERA_MODEL_ESP_EYE // Has PSRAM
//#define CAMERA_MODEL_M5STACK_PSRAM // Has PSRAM
//#define CAMERA_MODEL_M5STACK_V2_PSRAM // M5Camera version B Has PSRAM
//#define CAMERA_MODEL_M5STACK_WIDE // Has PSRAM
//#define CAMERA_MODEL_M5STACK_ESP32CAM // No PSRAM
//#define CAMERA_MODEL_M5STACK_UNITCAM // No PSRAM
//#define CAMERA_MODEL_AI_THINKER // Has PSRAM
//#define CAMERA_MODEL_TTGO_T_JOURNAL // No PSRAM

#include "camera_pins.h"

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

void startCameraServer();

void setup() {
  Serial.begin(115200);
  Serial.setDebugOutput(true);
  Serial.println();

  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;
  config.pin_d2 = Y4_GPIO_NUM;
  config.pin_d3 = Y5_GPIO_NUM;
  config.pin_d4 = Y6_GPIO_NUM;
  config.pin_d5 = Y7_GPIO_NUM;
  config.pin_d6 = Y8_GPIO_NUM;
  config.pin_d7 = Y9_GPIO_NUM;
  config.pin_xclk = XCLK_GPIO_NUM;
  config.pin_pclk = PCLK_GPIO_NUM;
  config.pin_vsync = VSYNC_GPIO_NUM;
  config.pin_href = HREF_GPIO_NUM;
  config.pin_sscb_sda = SIOD_GPIO_NUM;
  config.pin_sscb_scl = SIOC_GPIO_NUM;
  config.pin_pwdn = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;
  config.xclk_freq_hz = 20000000;
  config.pixel_format = PIXFORMAT_JPEG;






 
  // if PSRAM IC present, init with UXGA resolution and higher JPEG quality
  //                      for larger pre-allocated frame buffer.
  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;
  }

#if defined(CAMERA_MODEL_ESP_EYE)
  pinMode(13, INPUT_PULLUP);
  pinMode(14, INPUT_PULLUP);
#endif

  // camera init
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  }

  sensor_t * s = esp_camera_sensor_get();
  // initial sensors are flipped vertically and colors are a bit saturated
  if (s->id.PID == OV3660_PID) {
    s->set_vflip(s, 1); // flip it back
    s->set_brightness(s, 1); // up the brightness just a bit
    s->set_saturation(s, -2); // lower the saturation
  }
  // drop down frame size for higher initial frame rate
  s->set_framesize(s, FRAMESIZE_QVGA);

#if defined(CAMERA_MODEL_M5STACK_WIDE) || defined(CAMERA_MODEL_M5STACK_ESP32CAM)
  s->set_vflip(s, 1);
  s->set_hmirror(s, 1);
#endif

  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() {
  // put your main code here, to run repeatedly:
  delay(10000);
}

The above code is from the example sets in the Arduino IDE, Now I'm new to programming and I would like to understand what is going on in this code. I get that it's for streaming but most of the lines of code I do not get especially after configuring the pins but not to overwhelm anyone How about you guys try to explain to me what is PSRAM and why do we need to check if it's there ?

Please edit your post, select all code and click the </> button to apply code tags, next save your post. It makes it easier to read and copy and it prevents the forum software from interpreting it incorrectly.

Your topic has been moved to a more suitable location on the forum as you did not write a tutorial :wink:

1 Like

PSAM is extra ram added to the ESP32 developer module. The ESP32 can access the extra added RAM to use it, in this case, as a place to store large images. If PSRAM does not exist, then the image sizes the ESP32 CAM can handle is reduced.

1 Like
  // if PSRAM IC present, init with UXGA resolution and higher JPEG quality
  //                      for larger pre-allocated frame buffer.
  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;
  }

Okay! So according to the code above why are they choosing a lower quality when PSRAM is found and a higher quality when its not ? Was it not supposed to be the other way around?

Thank you!

 // if PSRAM IC present, init with UXGA resolution and higher JPEG quality
  //                      for larger pre-allocated frame buffer.
  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;
  }

Okay! So according to the code above why are they choosing a lower quality when PSRAM is found and a higher quality when its not ? Was it not supposed to be the other way around?

UXGA is a much larger image size than SVGA. That's why it needs to be stored in PSRAM.

1 Like

Perhaps a review of the ESP32's esp_camer.h settings is in order before a determination is made of higher/lower?

1 Like

Then this example will be a very steep hill to climb on your first attempt.

bool configInitCamera()
{
  camera_config_t config = {}; // Stores the camera configuration parameters
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer   = LEDC_TIMER_0;
  config.pin_d0       = GPIO_NUM_5; //Y2
  config.pin_d1       = GPIO_NUM_18; //Y3
  config.pin_d2       = GPIO_NUM_19; //Y4
  config.pin_d3       = GPIO_NUM_21; //Y5
  config.pin_d4       = GPIO_NUM_36; //Y6
  config.pin_d5       = GPIO_NUM_39; //Y7
  config.pin_d6       = GPIO_NUM_34; //Y8
  config.pin_d7       = GPIO_NUM_35; // Y9
  config.pin_xclk     = GPIO_NUM_0; //XCLK
  config.pin_pclk     = GPIO_NUM_22; //PCLK
  config.pin_vsync    = GPIO_NUM_25; //VSSYNC
  config.pin_href     = GPIO_NUM_23; // HREF
  config.pin_sscb_sda = GPIO_NUM_26; //SIOD
  config.pin_sscb_scl = GPIO_NUM_27; //SIOC
  config.pin_pwdn     = GPIO_NUM_32; //PWDN
  config.pin_reset    = -1; //RESET
  config.xclk_freq_hz = 20000000;
  config.pixel_format = PIXFORMAT_JPEG; ////YUV422,GRAYSCALE,RGB565,JPEG
  config.frame_size = FRAMESIZE_UXGA; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
  /*
    FRAMESIZE_UXGA (1600 x 1200)
    FRAMESIZE_QVGA (320 x 240)
    FRAMESIZE_CIF (352 x 288)
    FRAMESIZE_VGA (640 x 480)
    FRAMESIZE_SVGA (800 x 600)
    FRAMESIZE_XGA (1024 x 768)
    FRAMESIZE_SXGA (1280 x 1024)
  */
  config.jpeg_quality = 10; //0-63 lower number means higher quality
  /*
   * The image quality (jpeg_quality) can be a number between 0 and 63. 
   * A lower number means a higher quality. 
   * However, very low numbers for image quality, 
   * specially at higher resolution can make the ESP32-CAM to crash or it may not be able to take the photos properly.
   * 
   * So, if you notice that the images taken with the ESP32-CAM are cut in half, or with strange colors, 
   * that’s probably a sign that you need to lower the quality (select a higher number).
   */
  config.fb_count = 2;
  // Initialize the Camera
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    log_i("Camera init failed with error %d", err );
    return false;
  } else {
    configureCameraSettings();
    return true;
  }
} //void configInitCamera()

is the note I have been using.

1 Like

@gfvalvo @Idahowalker

#if defined(CAMERA_MODEL_ESP_EYE)
  pinMode(13, INPUT_PULLUP);
  pinMode(14, INPUT_PULLUP);
#endif

  // camera init
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  }

  sensor_t * s = esp_camera_sensor_get();
  // initial sensors are flipped vertically and colors are a bit saturated
  if (s->id.PID == OV3660_PID) {
    s->set_vflip(s, 1); // flip it back
    s->set_brightness(s, 1); // up the brightness just a bit
    s->set_saturation(s, -2); // lower the saturation
  }
  // drop down frame size for higher initial frame rate
  s->set_framesize(s, FRAMESIZE_QVGA);

#if defined(CAMERA_MODEL_M5STACK_WIDE) || defined(CAMERA_MODEL_M5STACK_ESP32CAM)
  s->set_vflip(s, 1);
  s->set_hmirror(s, 1);
#endif

What exactly does this part of the code do ?

The camera model I'm using is an ESP32 Cam AI Thinker

But none of the lines of codes in this section makes sense to me.

Is it checking which model of camera I'm using ?

It configures the camera per the 'config' object and adjust some settings.

Like I said in Post #9, this is most definitely NOT beginner-level code. Best to learn some C++ programming first.

I don't think camera configurations have anything to do with the language c /c++

I'm not a total beginner, I understand easily if explained, I just haven't coded much

Does it configure based on the camera you are using ?

#if defined(CAMERA_MODEL_ESP_EYE) checks to see if the camera is a fisheye thigy and does the things if it is so and skips the things if not.

esp_err_t err = esp_camera_init(&config); configures the camera using the settings as per config and returns a message

Crap, I don't feel like going through this cht line by line and doing a write up on each line.

The OP can go online and read the various CPP and H files associated with the ESP32 CAM, I did, and find out answers to his many questions.

Okay thank you so much.

Will try to get help for the remaining lines

@Allo_Cedric,

Your other topic on the same subject deleted.

Please do not duplicate your questions as doing so wastes the time and effort of the volunteers trying to help you as they are then answering the same thing in different places.

Repeated duplicate posting could result in a temporary or permanent ban from the forum.

Could you take a few moments to Learn How To Use The Forum

It will help you get the best out of the forum in the future.

Thank you.

1 Like

Could anyone else help here ? with this part of the code

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.