ESP32S3 Sense camera issue (OV2640)

Hi,

I recently bought a Seeed XIAO ESP32S3 Sense and I’m having trouble to get the camera to work properly.

One of the issues is that I’m being only able to take one picture and after that I get an error and it stop work until I reset the board.

I’m using a simple HTTP server implementation to get the picture on a browser.

Here is the error:

W (29749) cam_hal: Failed to get the frame on time!

** Even setting the log output verbosity to “Verbose” that is the only error message I see on terminal.

And here is my code:

static void camera_setup(void)
{
    camera_config_t camera_config = {
        .ledc_channel = LEDC_CHANNEL_0,
        .ledc_timer = LEDC_TIMER_0,

        .pin_d0 = Y2_GPIO_NUM,
        .pin_d1 = Y3_GPIO_NUM,
        .pin_d2 = Y4_GPIO_NUM,
        .pin_d3 = Y5_GPIO_NUM,
        .pin_d4 = Y6_GPIO_NUM,
        .pin_d5 = Y7_GPIO_NUM,
        .pin_d6 = Y8_GPIO_NUM,
        .pin_d7 = Y9_GPIO_NUM,

        .pin_xclk       = XCLK_GPIO_NUM,
        .pin_pclk       = PCLK_GPIO_NUM,
        .pin_vsync      = VSYNC_GPIO_NUM,
        .pin_href       = HREF_GPIO_NUM,
        .pin_sscb_sda   = SIOD_GPIO_NUM,
        .pin_sscb_scl   = SIOC_GPIO_NUM,
        .pin_pwdn       = PWDN_GPIO_NUM,
        .pin_reset      = RESET_GPIO_NUM,

        .xclk_freq_hz   = 10000000,
        .frame_size     = FRAMESIZE_XGA,
        .pixel_format   = PIXFORMAT_JPEG,
        .grab_mode      = CAMERA_GRAB_WHEN_EMPTY,
        .fb_location    = CAMERA_FB_IN_PSRAM,
        .jpeg_quality   = 10,
        .fb_count       = 1,
    };

    esp_err_t err = esp_camera_init(&camera_config);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "Camera init failed");
    }

    ESP_LOGI(TAG, "Camera init successfully");

    sensor_t * cam_sensor = esp_camera_sensor_get();
    cam_sensor->set_ae_level(cam_sensor, 0);                    // -2 to 2
    cam_sensor->set_aec_value(cam_sensor, 1500);                 // 0 - 1200
    cam_sensor->set_aec2(cam_sensor, 0);                        // 0 = Disable , 1 = Enable
    cam_sensor->set_agc_gain(cam_sensor, 0);                    // 0 - 30
    cam_sensor->set_awb_gain(cam_sensor, 1);                    // 0 = Disable , 1 = Enable
    cam_sensor->set_bpc(cam_sensor, 0);                         // 0 = Disable , 1 = Enable
    cam_sensor->set_brightness(cam_sensor, 1);                  // -2 to 2
    cam_sensor->set_colorbar(cam_sensor, 0);                    // 0 = Disable , 1 = Enable
    cam_sensor->set_contrast(cam_sensor, 0);                    // -2 to 2
    cam_sensor->set_dcw(cam_sensor, 0);                         // 0 = Disable , 1 = Enable
    cam_sensor->set_exposure_ctrl(cam_sensor, 0);               // 0 = Disable , 1 = Enable
    cam_sensor->set_gain_ctrl(cam_sensor, 0);                   // 0 = Disable , 1 = Enable
    cam_sensor->set_gainceiling(cam_sensor, (gainceiling_t)6);  // 0 - 6
    cam_sensor->set_hmirror(cam_sensor, 0);                     // 0 = Disable , 1 = Enable
    cam_sensor->set_lenc(cam_sensor, 0);                        // 0 = Disable , 1 = Enable
    cam_sensor->set_raw_gma(cam_sensor, 0);                     // 0 = Disable , 1 = Enable
    cam_sensor->set_saturation(cam_sensor, 0);                  // -2 to 2
    cam_sensor->set_special_effect(cam_sensor, 0);              // (0 - No Effect, 1 - Negative, 2 - Grayscale, 3 - Red Tint, 4 - Green Tint, 5 - Blue Tint, 6 - Sepia)
    cam_sensor->set_vflip(cam_sensor, 0);                       // 0 = Disable , 1 = Enable
    cam_sensor->set_wb_mode(cam_sensor, 3);                     // 0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home
    cam_sensor->set_whitebal(cam_sensor, 1);                    // 0 = Disable , 1 = Enable
    cam_sensor->set_wpc(cam_sensor, 0);                         // 0 = Disable , 1 = Enable
}

static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
{
    if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
        esp_wifi_connect();
    } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
        esp_wifi_connect();
    } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
        ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
        ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
    }
}

void wifi_init_sta()
{
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }

    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));

    ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, NULL));
    ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL, NULL));

    // Initialize default station as network interface instance (esp-netif)
    esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
    assert(sta_netif);

    // Initialize and start WiFi
    wifi_config_t wifi_config = {
        .sta = {
            .ssid = WIFI_SSID,
            .password = WIFI_PASS,
            .scan_method = WIFI_FAST_SCAN,
            .sort_method = WIFI_CONNECT_AP_BY_SIGNAL,
            .threshold.rssi = -127,
            .threshold.authmode = WIFI_AUTH_OPEN,
        },
    };
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
    ESP_ERROR_CHECK(esp_wifi_start());
}

esp_err_t capture_handler(httpd_req_t *req)
{
    camera_fb_t *fb = esp_camera_fb_get();
    if (!fb) {
        ESP_ERROR_CHECK(httpd_resp_send_404(req));
        return ESP_FAIL;
    }

    httpd_resp_set_type(req, "image/jpeg");
    httpd_resp_send(req, (const char *)fb->buf, fb->len);

    esp_camera_fb_return(fb);

    return ESP_OK;
}

static void start_webserver(void)
{
    httpd_uri_t capture_uri = {
        .uri = "/cam",
        .method = HTTP_GET,
        .handler = capture_handler,
        .user_ctx = NULL
    };
    httpd_config_t config = HTTPD_DEFAULT_CONFIG();
    httpd_handle_t server = NULL;
    if (httpd_start(&server, &config) == ESP_OK) {
        httpd_register_uri_handler(server, &capture_uri);
    }
}

void app_main(void)
{
    camera_setup();
    wifi_init_sta();
    start_webserver();
}

I have spent days trying to solve it with no luck. Can’t find anything on Google either.
I suspect I’m missing something very basic?!

Any help is really appreciated!

TIA!

Hi there, & Welcome,
Is the PSram enabled?, check the tools options in the IDE. can you lower the frame rate/size
XGA to Lower?
In the Demo I posted on here, I was able to take more than one, Look at that post check the compiler output see if yours is the same.
HTH
GL :slight_smile: PJ