"Failed to get the frame on time!" after a while working fine.

brigei
Posts: 5
Joined: Fri Dec 30, 2022 8:12 pm

"Failed to get the frame on time!" after a while working fine.

Postby brigei » Sun Jan 08, 2023 9:43 pm

Hi,

I have a script that in the loop does some kind of "motion detection". Later I plan to take a high-res pic and send it to a server if a motion is detected. Beside this I want to have the possibility to connect via a Webserver. The part in the loop works fine already. When I connect via the Webserver it works fine at the beginning but after taking about 40-50 frames I get this error and the esp32 reboots:

[E][camera.c:1483] esp_camera_fb_get(): Failed to get the frame on time!
Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.

The Webserver on its own seems to work fine. When I comment out everything in the loop function and insert the then missing "Config(LOW)" in the setup function the stream goes on and on without any problems.

Here is my code:

Code: Select all

#include "esp_camera.h"
#include <WiFi.h>
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include <FS.h>
#include "esp_timer.h"
#include "Arduino.h"
#include "fb_gfx.h"
#include "esp_http_server.h"
#include <img_converters.h>
#include <Preferences.h>

#define led 33
#define PART_BOUNDARY "123456789000000000000987654321"
#define LOW     1
#define HIGH    2

uint mode;
bool wechsel = false;
bool reset = true;
uint timestamp = 0;
camera_fb_t * fb = NULL;
byte foto[19200];
uint count = 0;

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

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

static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY;
static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";
static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n";

httpd_handle_t stream_httpd = NULL;

static esp_err_t stream_handler(httpd_req_t *req){
  esp_err_t res = ESP_OK;
  size_t _jpg_buf_len = 0;
  uint8_t * _jpg_buf = NULL;
  char * part_buf[64];
  float fps = 0;

  res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE);
  if(res != ESP_OK){
    return res;
  }

  while(true){

    if(fb != NULL){
      esp_camera_fb_return(fb);
      fb = NULL;
    }    
    
    fb = esp_camera_fb_get();

    if (mode == 2){
      _jpg_buf_len = fb->len;
      _jpg_buf = fb->buf;
    }
    
    else if (mode == 1){
      //Frame vergleichen und manipulieren
      if (!fmt2jpg(fb->buf, fb->len, fb->width, fb->height, fb->format, 10, &_jpg_buf, &_jpg_buf_len)){
      Serial.println("Fehler beim Convertieren.");
      }
    }
    
    if(res == ESP_OK){
      size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, _jpg_buf_len);
      res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen);
    }
    if(res == ESP_OK){
      res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len);
    }
    if(res == ESP_OK){
      res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));
    }

    if (mode == 1){
      free(_jpg_buf);
    }

    esp_camera_fb_return(fb);
    fb = NULL;
    _jpg_buf = NULL;

    if(res != ESP_OK){
      break;
    }

    fps = 1000/(millis()-timestamp);
    timestamp = millis();
    if (fps >= 10){
      Serial.printf("Mode %d / FPS: %2.2f\n",mode, fps);
    }
    else{
      Serial.printf("Mode %d / FPS:  %2.2f\n",mode, fps);
    }
    

  }

  return res;
}

void startCameraServer(){
  httpd_config_t config = HTTPD_DEFAULT_CONFIG();
  config.server_port = 80;

  httpd_uri_t index_uri = {
    .uri       = "/",
    .method    = HTTP_GET,
    .handler   = stream_handler,
    .user_ctx  = NULL
  };
  
  Serial.printf("Starting web server on port: '%d'\n", config.server_port);
  if (httpd_start(&stream_httpd, &config) == ESP_OK) {
    httpd_register_uri_handler(stream_httpd, &index_uri);
  }
}

void Config(int quality){

  camera_config_t config;
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer = LEDC_TIMER_0;
  config.pin_d0 = 5;
  config.pin_d1 = 18;
  config.pin_d2 = 19;
  config.pin_d3 = 21;
  config.pin_d4 = 36;
  config.pin_d5 = 39;
  config.pin_d6 = 34;
  config.pin_d7 = 35;
  config.pin_xclk = 0;
  config.pin_pclk = 22;
  config.pin_vsync = 25;
  config.pin_href = 23;
  config.pin_sscb_sda = 26;
  config.pin_sscb_scl = 27;
  config.pin_pwdn = 32;
  config.pin_reset = -1;
  config.xclk_freq_hz = 20000000;
  config.jpeg_quality = 10;
  config.fb_count = 2;

  if (quality == 1){
    config.pixel_format = PIXFORMAT_GRAYSCALE;
    config.frame_size = FRAMESIZE_QQVGA;
    Serial.println("Set Quality LOW");
  }
  else if (quality == 2){
    config.pixel_format = PIXFORMAT_JPEG;
    config.frame_size = FRAMESIZE_UXGA;
    Serial.println("Set Quality HIGH");
  }
  else{
    Serial.println("Undefinierte Qualtity bei Config.");
    return;
  }

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

  sensor_t * s = esp_camera_sensor_get();

  if (quality == 1){
    s->set_framesize(s, FRAMESIZE_QQVGA);
  }

  else if (quality == 2){
    s->set_framesize(s, FRAMESIZE_UXGA);
  }

  s->set_vflip(s, 0);
  s->set_hmirror(s, 0);
  s->set_lenc(s, 0);
  s->set_raw_gma(s, 0);
  s->set_sharpness(s, -2);
  s->set_denoise(s, 1);
  //s->set_special_effect(s, 2);

  return;
}

void ResetCam ()
{
 esp_camera_deinit();
 digitalWrite(32,LOW);
 delay (1);
 digitalWrite(32,HIGH);
 delay (10);
 digitalWrite(32,LOW);
}

void StartWlan(){

  WiFi.begin(ssid, password);
  Serial.print("WLAN Verbindungsaufbau...");
  while (WiFi.status() != WL_CONNECTED) 
  {
      Serial.print(".");
      delay(200);
  } 
  Serial.println();
  Serial.println("Verbunden");
  Serial.print("IP-Adresse: ");
  Serial.println(WiFi.localIP());

}

bool motionDetection(const byte foto[],const uint8_t *fb){
  
  size_t diff = 0;
  count ++;

  for (int i = 0; i < 19200; i++){
    if (abs(foto[i]-fb[i])>3){
      diff++;
    }
  }

  Serial.print(".");
  if (count == 50){
    count = 0;
    Serial.println();
  }
  //Serial.printf("Pixeldifferenz: %d\n", diff);

  if (diff > 800){
    //return true;
    //Serial.println("BEWEGUNG!!!!");
    return true;
  }

  else{
    //Serial.println(".....");
    return false;
  }
}

void setup() 
{

  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); // prevent brownouts by silencing them
  
  Serial.begin(115200);
  Serial.setDebugOutput(true);
  Serial.println();
  pinMode(led, OUTPUT);
  StartWlan();
  startCameraServer();
  mode = 1;
  timestamp = millis();
  delay(1000);    // Für initiale Vergleichsfotoerstellung
}

void loop() 
{

  if (mode == 1){

// ########### Camerainitialisierung falls notwendig ###########

    if (reset == true){
      Config(LOW);
      reset = false;
    }

// ########### Neues Vergleichsfoto jede Sekunde erstellen ###########

    fb = esp_camera_fb_get();

    if (millis() - timestamp > 1000){
      for (int i = 0; i < fb->len; i++){
        foto[i] = fb->buf[i];
      }

      esp_camera_fb_return(fb);
      fb = NULL;
      fb = esp_camera_fb_get();
      timestamp = millis();
    }

// ########### MOTION DETECTION ###########

    if (timestamp > 5000){
      if (motionDetection(foto, fb->buf) == true){
        esp_camera_fb_return(fb);
        fb = NULL;
        Serial.println("Motion Detection true.");
        ResetCam();
        mode = 2;
        reset = true;
      }
    }

    if (fb != NULL){
      esp_camera_fb_return(fb);
      fb = NULL;
    }

  }

  if (mode == 2){
    Config(HIGH);
    //saveFoto("/file_HQ.jpg");
    //sendFTP();
    ResetCam();
    mode = 1;
    reset = true;
  }
  
}

And here the serial monitor output:

Code: Select all

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:10944
load:0x40080400,len:6388
entry 0x400806b4

WLAN Verbindungsaufbau..................................................................
Verbunden
IP-Adresse: 10.0.0.61
Starting web server on port: '80'
Set Quality LOW
Camera initialisiert.
..................................................
..................................................
..................................................
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
Mode 1 / FPS: 12.00
[E][camera.c:1483] esp_camera_fb_get(): Failed to get the frame on time!
Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC      : 0x400d1271  PS      : 0x00060b30  A0      : 0x800d32fc  A1      : 0x3ffb1f90  
A2      : 0x3ffc73f0  A3      : 0x3ffc73f8  A4      : 0x3ffbdbbc  A5      : 0x00000000  
A6      : 0x00000003  A7      : 0x00060a23  A8      : 0x00001388  A9      : 0x3ffb1f70  
A10     : 0x3ffc28f0  A11     : 0x00000320  A12     : 0x3ffc28ec  A13     : 0x000000dc  
A14     : 0x00000000  A15     : 0x3ffb0060  SAR     : 0x0000000a  EXCCAUSE: 0x0000001c  
EXCVADDR: 0x00000000  LBEG    : 0x4008d629  LEND    : 0x4008d639  LCOUNT  : 0xfffffffb  

ELF file SHA256: 0000000000000000

Backtrace: 0x400d1271:0x3ffb1f90 0x400d32f9:0x3ffb1fb0 0x4008fd4e:0x3ffb1fd0

Rebooting...
Greetings.

xien551
Posts: 69
Joined: Wed Feb 02, 2022 4:04 am

Re: "Failed to get the frame on time!" after a while working fine.

Postby xien551 » Mon Jan 09, 2023 4:44 am

Below is my understanding, maybe helpful or not,

1.You have start a web server on your ESP-cam
2.run the cam and do the motion dectection
3. if motion is detected, change the cam to high-reselution
4. your esp is collapsed after ~50 frame getting cycles. If the motion is detected or not?
5. You have put all the code in a loop. And this is not suggested. Try task.
6. For Ai-think esp32-cam and the official code with web server and cam, if the frame resolution is too high, the server would almost not work but just give black.

brigei
Posts: 5
Joined: Fri Dec 30, 2022 8:12 pm

Re: "Failed to get the frame on time!" after a while working fine.

Postby brigei » Mon Jan 09, 2023 7:57 am

Hi,

1, 2 and 3 is the normal process when i don‘t connect via web browser to the esp.

4 -> doesn‘t have anything to do with the loop function and the motion detection. Because the process with the high resolution after a motion is detected is so short, it‘s hardly this configuration (high res) when it comes to the http_stream. So the config for the webserver is in low resolution and therefore with the converting process grayscale to jpg.

5 -> so you mean to put the http handler in the loop function as well?

6-> like i said to point 5 the resolution is low. It‘s in qqvga so 160x120.

Greetings.

brigei
Posts: 5
Joined: Fri Dec 30, 2022 8:12 pm

Re: "Failed to get the frame on time!" after a while working fine.

Postby brigei » Mon Jan 09, 2023 6:44 pm

Ahhh and another thing. When i connect via Webbrowser only the http-server is aktive any more. The loop-function doesn't get executed any longer. I tested this with a simple print command in the loop section. Is this behavier correct?

Who is online

Users browsing this forum: No registered users and 33 guests