Failed connection when using esp_camera

I am running Blynk v1.3.2 on an ESP32 and using the esp_camera library in the Arduino IDE. In the application, I am doing a frame grab off the camera and encoding it in base64. Whenever the camera code is enabled, I get the “Secure connection failed” error from Blynk. Without the camera enabled, Blynk connects and data is sent correctly. I would also note the following in the console log at startup:

E (3502) gpio: gpio_install_isr_service(449): GPIO isr service already installed

I have looked through the forum and found successful cases of camera capture on the ESP32 with Blynk, but can not seem to nail down this issue. The code and console log are below. Could this be an ISR issue between Blynk and the esp_camera library?

Thanks!

//-----------------------------------------------------------------------------
//-- DEFINES ------------------------------------------------------------------
//-----------------------------------------------------------------------------

//-- Blynk IoT ----------------------------------------------------------------
/* Fill in information from your Blynk Template here */
/* Read more: https://bit.ly/BlynkInject */
#define BLYNK_TEMPLATE_ID "<MY_ID>"
#define BLYNK_TEMPLATE_NAME "<MY_NAME"
#define BLYNK_FIRMWARE_VERSION        "0.1.13"
#define BLYNK_PRINT Serial
#define BLYNK_DEBUG
#define APP_DEBUG

// Uncomment your board, or configure a custom board in Settings.h
#define ENABLE_CAM
#define USE_ESP32_DEV_MODULE

//-- Camera -------------------------------------------------------------------
#define CAMERA_MODEL_M5STACK_ESP32CAM // No PSRAM

//-----------------------------------------------------------------------------
//-- INCLUDES -----------------------------------------------------------------
//-----------------------------------------------------------------------------

#ifdef ENABLE_CAM
  // Camera
  #include "esp_camera.h"
  #include "camera_index.h"
  #include "camera_pins.h"
  #include <base64.h>
  #include <libb64/cencode.h>
#endif

// Blynk IoT Service
#include "BlynkEdgent.h"

//-----------------------------------------------------------------------------
//-- GLOBALS- -----------------------------------------------------------------
//-----------------------------------------------------------------------------
BlynkTimer timerBlynk;

//-----------------------------------------------------------------------------
//-- Function Definitions -----------------------------------------------------
//-----------------------------------------------------------------------------

//-- Timer Callback -----------------------------------------------------------
void timerCallback()
{
  int   valD = 0;
  float valC = 0.0;
  float valT = 0.0;
  float valH = 0.0; 
  float valP = 0.0;
  int   valPV = 0;
  int   valPC = 0;
  float valPP = 0;

#ifdef ENABLE_CAM
  // Camera Variables
  camera_fb_t *fb = NULL;
  esp_err_t res = ESP_OK;

  // Read Camera
  fb = esp_camera_fb_get();
  delay(100);  
  if (!fb)
  {
    Serial.println("Camera capture failed");
    ESP.restart();
  }
  else
  {
    BLYNK_LOG("[APP] ESP HEAP: %d", ESP.getFreeHeap());
    BLYNK_LOG("[APP] ESP IMAGE:");
    String base64image = base64::encode(fb->buf, fb->len);
    Serial.println(base64image);
    esp_camera_fb_return(fb);
  }
#endif

  // You can send any value at any time.
  // Please don't send more that 10 values per second.
  // Bundle the data into a group with a single timestamp
  Blynk.beginGroup();
  Blynk.virtualWrite(V0, valD);
  Blynk.virtualWrite(V1, valC);
  Blynk.virtualWrite(V2, valT);
  Blynk.virtualWrite(V3, valH);
  Blynk.virtualWrite(V4, valP);
  Blynk.virtualWrite(V5, valPV);
  Blynk.virtualWrite(V6, valPC);
  Blynk.virtualWrite(V7, valPP);
  Blynk.endGroup();

  // Print to Serial Log
  BLYNK_LOG("[APP] DATA: %.1f %d %.1f %.1f %.1f %d %d %.1f", valC, valD, valT, valH, valP, valPV, valPC, valPP);

}

//-----------------------------------------------------------------------------
//-- SETUP --------------------------------------------------------------------
//-----------------------------------------------------------------------------
void setup()
{
  //-- Config GPIO -----------------------------------------------------------
  pinMode(LED_BUILTIN, OUTPUT);
  // Flash LED
  digitalWrite(LED_BUILTIN, HIGH);
  delay(300);
  digitalWrite(LED_BUILTIN, LOW);
  delay(300);
  digitalWrite(LED_BUILTIN, HIGH);

  //-- Init I2C Bus -----------------------------------------------------------
  //Wire.begin();

  //-- Init Debug Serial Port -------------------------------------------------
  Serial.begin(115200);
  delay(100);
  BLYNK_LOG("[APP] LOG Serial UP");

#ifdef ENABLE_CAM
  //-- Startup Camera ---------------------------------------------------------
  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_sccb_sda = SIOD_GPIO_NUM;
  config.pin_sccb_scl = SIOC_GPIO_NUM;
  config.pin_pwdn = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;
  config.xclk_freq_hz = 20000000;
  config.frame_size = FRAMESIZE_VGA;
  config.pixel_format = PIXFORMAT_JPEG; 
  config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
  config.fb_location = CAMERA_FB_IN_DRAM;
  config.jpeg_quality = 12;
  config.fb_count = 1;

  // Camera Init
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    BLYNK_LOG("[APP] Camera init failed with error 0x%x\n", err);
    ESP.restart();
  }
  else
  {
    BLYNK_LOG("[APP] Camera UP");
  }

  camera_fb_t *fb = NULL;
  esp_err_t res = ESP_OK;

  // Read Camera
  fb = esp_camera_fb_get();
  delay(100);  
  if (!fb)
  {
    BLYNK_LOG("Camera capture failed");
    ESP.restart();
  }
  else
  {
    BLYNK_LOG("[APP] ESP HEAP: %d", ESP.getFreeHeap());
    BLYNK_LOG("[APP] ESP IMAGE:");
    String base64image = base64::encode(fb->buf, fb->len);
    Serial.println(base64image);
    esp_camera_fb_return(fb);
  }
#endif

  //-- Blynk.io ---------------------------------------------------------------
  BlynkEdgent.begin();

  //-- Data Polling timerBlynk ------------------------------------------------
  // Setup a function to be called every 5 seconds
  timerBlynk.setInterval(5000L, timerCallback);
}


//-----------------------------------------------------------------------------
//-- MAIN LOOP ----------------------------------------------------------------
//-----------------------------------------------------------------------------
void loop() 
{ 
  //-- Blynk.io Handler -------------------------------------------------------
  BlynkEdgent.run();
  timerBlynk.run(); // Initiates Blynktimer
}

From the console:

[748] [APP] LOG Serial UP
[1542] [APP] Camera UP
[1777] [APP] ESP HEAP: 147364
[1777] [APP] ESP IMAGE:
<BASE64_DATA_STRING_HERE>
E (3502) gpio: gpio_install_isr_service(449): GPIO isr service already installed
[3531]
___ __ __
/ _ )/ /_ _____ / /__
/ _ / / // / _ / '/
/
//_, /////_
/
__/ v1.3.2 on ESP32

#StandWithUkraine StandWithUkraine | #StandWithUkraine banner and related documents

Device: Blynk <DEV_NAME>
Firmware: 0.1.13 (build Jan 29 2024 19:05:48)
Token: G6O6 - •••• - •••• - ••••
Platform: ESP32 @ 240MHz
Chip rev: 3
SDK: v4.4.5
Flash: 16384K
Free mem: 98404

[3573] INIT => CONNECTING_NET
[3584] Connecting to WiFi: <MY_SSID>
[4992] Using Dynamic IP: 192.168.12.229
[4992] CONNECTING_NET => CONNECTING_CLOUD
[5002] Connecting to blynk.cloud:443
[5536] Secure connection failed
[10006] Connecting to blynk.cloud:443
[10451] Secure connection failed

50060] Connecting to blynk.cloud:443
[50387] Secure connection failed
[54998] Timeout
[55099] [APP] ESP HEAP: 95764
[55099] [APP] ESP IMAGE:
<BASE64_DATA_STRING_HERE>
56661] [APP] DATA: 0.0 0 0.0 0.0 0.0 0 0 0.0
[56681] Connecting to blynk.cloud:443
[57043] Secure connection failed

An Update:
The ISR Service error/warning is due to both Blynk and ESP_Camera setting up a GPIO interrupt on the user reset button. If this comes up, it may or may not be an issue as long as the user button GPIO pins don’t conflict.

Regarding the “Secure connection failed” error, it appears to be caused by some RAM/Heap issue. I changed the camera config.frame_size from FRAMESIZE_VGA to FRAMESIZE_QVGA and now Blynk connects successfully with “Certificate OK”.

I am still not quite sure what the root cause of the conflict is. Even with Debug output enabled, I don’t see anything obvious.

When you post serial monitor output you should use triple backticks at the beginning and end - the same way as you did when posting your sketch - rather than using blockquotes.

Is there a reason why you chose to use the Blynk Edgent example as the basis for this sketch?
Are there particular pieces of Edgent functionality that you require?

Pete.

I require provisioning and OTA for my application using a device Template (PRO Plan). I believe the proper way to do this is using Edgent. Is that correct?

If you need dynamic provisioning then you need to use Edgent.
You can do Blynk.Air OTA without Edgent.

Pete.