ESP32 Can't Connect to Blynk Cloud Despite Working WiFi

Hi guys.
I am working on a project that requires me to connect to Blynk.Edgent, Firebase, and display the UI simultaneously. I am using ESP32 to program, and the LCD TFT I am using is the ILI9811. I have researched and found anything that related to my project, but i found nothing. So here I am.
The project involves collecting data from the fine dust sensor PMS5003, temperature, and humidity SHT31, displaying it on the screen, and pushing it to Firebase. However, I am unable to connect to Blynk cloud, even though I have already accessed the Wi-Fi network, and the Wi-Fi is running smoothly and the framework is Arduino btw.

At first, I suspected that the Wi-Fi connection with ESP32 was the problem. However, I tested it with ThingSpeak, and it ran smoothly without any delay. The ESP32 can connect to the ThingSpeak cloud.

Next, I tested to run the Blynk.Edgent alone, and it ran okay. The ESP32 can access the Blynk Cloud, and I can configure the Blynk configuration through my app Blynk on my iPhone. I still kept the RTOS configuration when I tested.

However, I am unable to understand why when I added the code of the UI with the Blynk.Edgent code, the expected result did not appear.

Note: I used lgvl library for the UI code, and Squareline studio to design the UI.

I will upload the code if you guy would like to take a look:

/*Don't forget to set Sketchbook location in File/Preferencesto the path of your UI project (the parent foder of this INO file)*/
#define BLYNK_PRINT Serial
#define APP_DEBUG

#include "BlynkEdgent.h"
#include <lvgl.h>
#include <TFT_eSPI.h>
#include <ui.h>
#include <PMserial.h>
#include <Wire.h>
#include "Wire.h"
#include "SHT31.h"
#include "ThingSpeak.h"   // always include thingspeak header file after other header files and custom macros
#include <WiFiManager.h>  // Include the WiFiManager library
#include <Arduino.h>
#include <WiFi.h>
#include <FirebaseESP32.h>
#include <addons/TokenHelper.h>
#include <addons/RTDBHelper.h>

/* Config UART pins with PMS5003 */
#if !defined(PMS_RX) && !defined(PMS_TX)
constexpr auto PMS_RX = 16;
constexpr auto PMS_TX = 17;

#ifndef ESP32
SerialPM pms(PMS5003, PMS_RX, PMS_TX);  // PMSx003, RX, TX
SerialPM pms(PMS5003, PMS_RX, PMS_TX);  // PMSx003, RX, TX

/* Define ADC pin to read battery current */
#define BAT_LV1 2     // Power supply PIN for screen
#define BUTTON_PIN 0  // Button PIN
#define LEDA 14

/* Define address for SHT31 */
#define SHT31_ADDRESS 0x44

/* Define the API_KEY and DATABASE_URL for Firebase */
#define API_KEY ""
#define DATABASE_URL ""

/* define cores for CPU */
static const BaseType_t pro_cpu = 0;
static const BaseType_t app_cpu = 1;

/* Init tasks and task handle */
static TaskHandle_t taskReadValues;
static TaskHandle_t taskDisplayValueToScreen;
static TaskHandle_t taskButtonFunctions;
static TaskHandle_t taskRunUI;
static TaskHandle_t taskWifi;
static TaskHandle_t taskSendDataToFirebase;
static TaskHandle_t taskBlynkRun;
static TaskHandle_t taskBlynkInit;

void TaskReadValues(void *pvParameters);
void TaskDisplayValueToScreen(void *pvParameters);
void TaskButtonFunctions(void *pvParameters);
void TaskRunUI(void *pvParameters);
void TaskWifi(void *pvParameters);
void TaskSendDataToFirebase(void *pvParameters);
void TaskBlynkRun(void *pvParameters);
void TaskBlynkInit(void *pvParameters);

void ui_screen_1_reset();
void getAQIFromPM25();
int calculateAQI(float I_high, float I_low, float C_high, float C_low, float C);

/* Init variables for Sending data to firebase*/
FirebaseData fbdo;
FirebaseAuth auth;
FirebaseConfig config;
unsigned long sendDataPrevMillis = 0;
bool isSignup = false;
unsigned long count = 0;
unsigned long dataMillis = 0;

/* Init pms values, battery values and sh31 values */
int pms_pm1p0, pms_pm2p5, pms_pm10;  // pms values
float battery_Value;                 // battery voltage
bool screenState = false;            // Screen state
float battery_Percentage;            // % battery
int temp;                            // temperature
int humi;                            // humidity

/* Define for change screen tasks */
const unsigned long longPressTime = 2000;  // how long the button needs to be pressed for long press (in milliseconds)
bool screenToggled = false;                // whether the SCREEN has been toggled
int lastButtonState = HIGH;                // the previous reading from the input pin
int counter = 1;                           // counter for the number of button presses
unsigned long buttonPressTime;             // when the button was pressed
bool resetWifiState = false;
int timeout = 120;  // seconds to run for

/*Change to your screen resolution*/
static const uint16_t screenWidth = 320;
static const uint16_t screenHeight = 240;

static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[screenWidth * screenHeight / 10];

TFT_eSPI tft = TFT_eSPI(screenWidth, screenHeight); /* TFT instance */
SHT31 sht;
WiFiManager wm;
WiFiClient client;

/* Display flushing */
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
  uint32_t w = (area->x2 - area->x1 + 1);
  uint32_t h = (area->y2 - area->y1 + 1);

  tft.setAddrWindow(area->x1, area->y1, w, h);
  tft.pushColors((uint16_t *)&color_p->full, w * h, true);


/*Read the touchpad*/
void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data) {
  uint16_t touchX = 0, touchY = 0;

  bool touched = false;  //tft.getTouch( &touchX, &touchY, 600 );

  if (!touched) {
    data->state = LV_INDEV_STATE_REL;
  } else {
    data->state = LV_INDEV_STATE_PR;

    /*Set the coordinates*/
    data->point.x = touchX;
    data->point.y = touchY;

    Serial.print("Data x ");

    Serial.print("Data y ");

void setup() {
  Serial.begin(115200); /* prepare for possible serial debug */
  tft.begin();        /* TFT init */
  tft.setRotation(1); /* Landscape orientation, flipped */

  lv_disp_draw_buf_init(&draw_buf, buf, NULL, screenWidth * screenHeight / 10);

  /*Initialize the display*/
  static lv_disp_drv_t disp_drv;
  /*Change the following line to your display resolution*/
  disp_drv.hor_res = screenWidth;
  disp_drv.ver_res = screenHeight;
  disp_drv.flush_cb = my_disp_flush;
  disp_drv.draw_buf = &draw_buf;

  /*Initialize the (dummy) input device driver*/
  static lv_indev_drv_t indev_drv;
  indev_drv.type = LV_INDEV_TYPE_POINTER;
  indev_drv.read_cb = my_touchpad_read;

  ui_init();            // UI Screen init
  ui_screen_1_reset();  // Reset all values in UI Screen
  pms.init();           // init PMS5003
  sht.begin(SHT31_ADDRESS);  // init SHT31

  /* Init pins */
  // pinMode(BAT_LV1, OUTPUT);
  pinMode(LEDA, OUTPUT);
  digitalWrite(LEDA, HIGH);

  /* Init tasks */

  Serial.print("HEAP size left: ");
  // Task funct - taks name - stack size - parameters - task handle - core to run on
  xTaskCreatePinnedToCore(TaskRunUI, "RunningUI", 10000, NULL, 5, &taskRunUI, app_cpu);
  xTaskCreatePinnedToCore(TaskButtonFunctions, "TurnOnOff_or_ChangeScreen_or_Configwifi", 10000, NULL, 4, &taskButtonFunctions, app_cpu);
  xTaskCreatePinnedToCore(TaskDisplayValueToScreen, "DisplayValueToScreen", 8000, NULL, 4, &taskDisplayValueToScreen, app_cpu);
  xTaskCreatePinnedToCore(TaskReadValues, "ReadValues", 5000, NULL, 3, &taskReadValues, app_cpu);
  // xTaskCreatePinnedToCore(TaskWifi, "Wifi", 10000, NULL, 2, &taskWifi, app_cpu);
  xTaskCreatePinnedToCore(TaskBlynkInit, "BlynkInit", 5000, NULL, 2, &taskBlynkInit, pro_cpu);
  xTaskCreatePinnedToCore(TaskBlynkRun, "BlynkRun", 10000, NULL, 1, &taskBlynkRun, pro_cpu);
  xTaskCreatePinnedToCore(TaskSendDataToFirebase, "ConnectSendDataToFirebase", 10000, NULL, 1, &taskSendDataToFirebase, app_cpu);

  Serial.println("Setup done");
  vTaskDelete(NULL);  // delete setup and loop after setup is done

void loop() {
  // Do nothing in loop

void TaskRunUI(void *pvParameters) {
  while (1) {
    lv_timer_handler(); /* let the GUI do its work */
    vTaskDelay(10 / portTICK_PERIOD_MS);
void TaskBlynkInit(void *pvParameters) {
  vTaskDelete(NULL);  // delete after done
void TaskBlynkRun(void *pvParameters) {
  while (1) {;
    vTaskDelay(100 / portTICK_PERIOD_MS);
void TaskSendDataToFirebase(void *pvParameters) {
  config.api_key = API_KEY;
  /* Assign the RTDB URL (required) */
  config.database_url = DATABASE_URL;

  /* Assign the callback function for the long running token generation task */
  config.token_status_callback = tokenStatusCallback;  // see addons/TokenHelper.h

  // Comment or pass false value when WiFi reconnection will control by your code or third party library e.g. WiFiManager

  // Since v4.4.x, BearSSL engine was used, the SSL buffer need to be set.
  // Large data transmission may require larger RX buffer, otherwise connection issue or data read time out can be occurred.
  fbdo.setBSSLBufferSize(4096 /* Rx buffer size in bytes from 512 - 16384 */, 1024 /* Tx buffer size in bytes from 512 - 16384 */);

  // Or use legacy authenticate method
  // config.database_url = DATABASE_URL;
  config.signer.tokens.legacy_token = "";

  // Please make sure the device free Heap is not lower than 80 k for ESP32 and 10 k for ESP8266,
  // otherwise the SSL connection will fail.
  config.timeout.serverResponse = 1 * 1000;  // config the server respone back is 1 sec
  Firebase.begin(&config, &auth);
  while (1) {
    String pms_pm1p0_value = (String)pms_pm1p0;
    String pms_pm2p5_value = (String)pms_pm2p5;
    String pms_pm10_value = (String)pms_pm10;
    int aqi_value = getAQIFromPM25(pms.pm25);
    String celsius_value = (String)temp;
    String rh_value = (String)humi;
    if ((millis() - dataMillis > 5000) && Firebase.ready()) {
      dataMillis = millis();
      // Serial.printf("Set int... %s\n", Firebase.setInt(fbdo, "/test", count++) ? "ok" : fbdo.errorReason().c_str());
      Serial.printf("Set str... %s\n", Firebase.setString(fbdo, "/temp", celsius_value) ? "ok" : fbdo.errorReason().c_str());
      Serial.printf("Set str... %s\n", Firebase.setString(fbdo, "/pm1p0", pms_pm1p0_value) ? "ok" : fbdo.errorReason().c_str());
      Serial.printf("Set str... %s\n", Firebase.setString(fbdo, "/pm2p5", pms_pm2p5_value) ? "ok" : fbdo.errorReason().c_str());
      Serial.printf("Set str... %s\n", Firebase.setString(fbdo, "/pm10", pms_pm10_value) ? "ok" : fbdo.errorReason().c_str());
      Serial.printf("Set int... %s\n", Firebase.setInt(fbdo, "/aqi", aqi_value) ? "ok" : fbdo.errorReason().c_str());
      Serial.printf("Set str... %s\n", Firebase.setString(fbdo, "/humi", rh_value) ? "ok" : fbdo.errorReason().c_str());
    vTaskDelay(200 / portTICK_PERIOD_MS);

void ui_screen_1_reset() {
  lv_label_set_text(ui_pm2p5ValueLabel, "0");               // update pm2.5 label to 0
  lv_label_set_text(ui_pm1p0ValueLabel, "0");               // update pm1.0 label to 0
  lv_label_set_text(ui_pm10ValueLabel, "0");                // update pm10 label to 0
  lv_slider_set_value(ui_aqiSlider, 0, LV_ANIM_OFF);        // update aqi slider value to 0
  lv_label_set_text(ui_aqiValueLabel, "0");                 // update aqi label to 0
  lv_label_set_text(ui_batteryPercentageValueLabel1, "0");  // update battery label value to 0
  lv_slider_set_value(ui_batterySlider1, 0, LV_ANIM_OFF);   // update battery slider value to 0

void TaskButtonFunctions(void *pvParameters) {
  while (1) {
    // read the state of the pushbutton value:
    int currentButtonState = digitalRead(BUTTON_PIN);
    // check for button press
    if (lastButtonState == HIGH && currentButtonState == LOW) {
      buttonPressTime = millis();
      screenToggled = false;
      resetWifiState = false;
    // check for long press
    else if (currentButtonState == LOW && !screenToggled && millis() - buttonPressTime > longPressTime) {
      digitalWrite(LEDA, !digitalRead(LEDA));  // toggle the LED
      screenToggled = true;

    } else if (currentButtonState == LOW && !resetWifiState && digitalRead(LEDA) != LOW && millis() - buttonPressTime > 5000) {  // when the screen is off, you can not reset the wifi
      // digitalWrite(LEDA, !digitalRead(LEDA));  // toggle the LED
      resetWifiState = true;
      // wm.resetSettings();

      // set configportal timeout
      wm.setConfigPortalTimeout(120);  // set the timeout for 30secs

      if (!wm.startConfigPortal("AirSensor")) {

        Serial.println("failed to connect and hit timeout");
        vTaskDelay(5000 / portTICK_PERIOD_MS);
        // //reset and try again, or maybe put it to deep sleep
        // delay(5000);
        vTaskDelay(5000 / portTICK_PERIOD_MS);

      //if you get here you have connected to the WiFi
      Serial.println("connected...yeey :)");
    // check for button release
    else if (lastButtonState == LOW && currentButtonState == HIGH) {
      if (!screenToggled) {
        if (counter == 1) {
          _ui_screen_change(&ui_airSensorScreen2, LV_SCR_LOAD_ANIM_FADE_ON, 400, 0, &ui_airSensorScreen2_screen_init);
        } else {
          _ui_screen_change(&ui_airSensorScreen1, LV_SCR_LOAD_ANIM_FADE_ON, 400, 0, &ui_airSensorScreen1_screen_init);
        //reset the counter
        counter = 3 - counter;
    // save the current state as the last state,
    // for next time through the loop
    lastButtonState = currentButtonState;
    // delay a little bit to avoid bouncing
    vTaskDelay(50 / portTICK_PERIOD_MS);

void TaskDisplayValueToScreen(void *pvParameters) {
  while (1) {
    String pms_pm1p0_label_value = (String)pms_pm1p0;
    String pms_pm2p5_label_value = (String)pms_pm2p5;
    String pms_pm10_label_value = (String)pms_pm10;
    int aqi_Slider_Value = getAQIFromPM25(pms.pm25);
    String aqi_label_value = (String)aqi_Slider_Value;
    String battery_percentage_label_value = (String)((int)battery_Percentage);
    int battery_slider_value = (int)(battery_Percentage);
    String celsius_label_value = (String)temp;
    String rh_label_value = (String)humi;

    /* Screen 1 */
    lv_label_set_text(ui_pm1p0ValueLabel, pms_pm1p0_label_value.c_str());                        // update pm1.0 label value in screen 1
    lv_label_set_text(ui_pm2p5ValueLabel, pms_pm2p5_label_value.c_str());                        // update pm2.5 label value in screen 1
    lv_label_set_text(ui_pm10ValueLabel, pms_pm10_label_value.c_str());                          // update pm10 label value in screen 1
    lv_slider_set_value(ui_aqiSlider, aqi_Slider_Value, LV_ANIM_OFF);                            // update aqi slider value in screen 1
    lv_label_set_text(ui_aqiValueLabel, aqi_label_value.c_str());                                // update aqi label value in screen 1
    lv_label_set_text(ui_batteryPercentageValueLabel1, battery_percentage_label_value.c_str());  // update battery label value in screen 1
    lv_slider_set_value(ui_batterySlider1, battery_slider_value, LV_ANIM_OFF);                   // update battery slider value in screen 1

    /* Screen 2 */
    lv_label_set_text(ui_batteryPercentageValueLabel2, battery_percentage_label_value.c_str());  // update battery label value in screen 2
    lv_slider_set_value(ui_batterySlider2, battery_slider_value, LV_ANIM_OFF);                   // update battery slider value in screen 2
    lv_label_set_text(ui_degreeCelsiusValueLabel, celsius_label_value.c_str());                  // update celsius label value in screen 2
    lv_label_set_text(ui_rhValueLabel, rh_label_value.c_str());                                  // update humindity label value in screen 2
    lv_label_set_text(ui_soundValueLabel, "100");                                                // update noise label value in screen 2
    lv_label_set_text(ui_tvocValueLabel, "0.000");                                               // update tvoc label value in screen 2
    vTaskDelay(100 / portTICK_PERIOD_MS);

void TaskReadValues(void *pvParameters) {
  while (1) {;;
    // if (pms) {

    /* Read pms */
    pms_pm1p0 = pms.pm01;
    pms_pm2p5 = pms.pm25;
    pms_pm10 = pms.pm10;
    // }
    /* Read battery's voltage */
    int battery = analogRead(BAT_LV1);
    float battery_Test = (3.41111 * (float)battery) / 4095;
    float battery_Test_2 = (battery_Test / 2700) * 3700;
    float baterry_V_Max = 4.2;
    battery_Percentage = round((battery_Test_2 / baterry_V_Max) * 100);
    /* Read sht values */
    float t = sht.getTemperature();
    float h = sht.getHumidity();
    temp = (int)round(t);
    humi = (int)round(h);

    vTaskDelay(50 / portTICK_PERIOD_MS);

// Function to calculate AQI
int calculateAQI(float I_high, float I_low, float C_high, float C_low, float C) {
  return ((I_high - I_low) / (C_high - C_low)) * (C - C_low) + I_low;
// Function that get the AQI from PM2.5
int getAQIFromPM25(float pm25) {
  if (pm25 <= 12.0) {
    return calculateAQI(50, 0, 12.0, 0.0, pm25);
  } else if (pm25 <= 35.4) {
    return calculateAQI(100, 51, 35.4, 12.1, pm25);
  } else if (pm25 <= 55.4) {
    return calculateAQI(150, 101, 55.4, 35.5, pm25);
  } else if (pm25 <= 150.4) {
    return calculateAQI(200, 151, 150.4, 55.5, pm25);
  } else if (pm25 <= 250.4) {
    return calculateAQI(300, 201, 250.4, 150.5, pm25);
  } else if (pm25 <= 350.4) {
    return calculateAQI(400, 301, 350.4, 250.5, pm25);
  } else if (pm25 <= 500.4) {
    return calculateAQI(500, 401, 500.4, 350.5, pm25);
  } else {
    // PM2.5 value is off the charts; return -1 to indicate error
    return -1;

A few questions/comments…

  1. why are you using the Edgent example sketch as the basis for your project? Which Edgent features do you need?

  2. why do you have WiFiManager in your list of #invlude libraries?

  3. you’ve removed BlynkEdgent.begin() from your void setup and from your void loop, so your device will never connect to or maintain a connection to the Blynk server or be able to use any of the Edgent functionality.

TBH, with a sketch of this complexity, I wouldn’t be using the Edgent sketch as the starting point. If you need dynamic provisioning then why are you using WiFiManager? If you want Edgent for the Blynk.Air OTA functionality then there are far simpler ways to achieve this.


Dear Pete,

Thank you for your reply. I apologize for the confusion, the code I uploaded here is another version of my code (the version using Wifimanager).

  • The reason I’m using Edgent example sketch is that I want to control, display real-time value, OTA and hard-code WiFi credentials. That’s why I want to use Blynk.Edgent.
  • I used to test my project with Wifimanager to dynamically change WiFi configuration. It’s not relevant to the current issue, so you can ignore it.
  • I used freeRTOS for the Blynk.Edgent because I want the Blynk.Edgent to run separately from the other tasks, like a stand-alone task. As I mentioned in the topic, I did test to use freeRTOS in the example sketch before, and it worked fine. But when I used it in my project, the esp32 could not connect to the blynk cloud. I don’t understand why this happens.
  • To be honest, the main thing I want is to have an app and its functions for my project. And Blynk has all the things I need. So that’s why I’m trying to use it.


Is this a typo, do you really mean you want to hard-code your credentials?

Posting that code might be useful. I don’t personally use freeRTOS, but the way you’re doing it looks very odd.

Posting tour serial monitor output using the freeRTOS Blynk Edgent sketch and the sketch posted initially may be useful, although you really need to clean-up your initial sketch to remove the rubbish. I’d also suggest moving all of your other #includes below this line…


Dear Pete,

Thank you for your reply once again. I appreciate your feedback and suggestions. I would like to clarify some points regarding my project and its objectives and rationale for using each component.

  • Firstly, by “hard-code WiFi credentials”, I mean that I want to avoid having to re-upload the code every time I change my WiFi SSID and password. I want to be able to reconfigure the device and the WiFi settings easily and dynamically. That’s why I’m using the Blynk.Edgent library, which includes the Wifimanager feature.

  • Secondly, the main thing I want here is to have an app for my project, and I’m not proficient in mobile programming, so Blynk is my perfect choice for me. For the UI code, I’m using Squareline Studio to design the UI for my project, and lvgl example for the template for my UI code. You can take a look at Squareline Studio right :point_right: here, and I learned the tutorial :point_right: here.

  • Thirdly, the reason why I’m using freeRTOS for each function is because I want to optimize the code and eliminate delays for my device in each function. For example, if I combine the code in the task TaskSendDataToFirebase and the code in the task TaskUI, the UI display will be delayed. Or in this situation: If I put the code BlynkEdgent.begin(); in the setup(), the program will be stuck in a loop of waiting for the configuration of Blynk to start first, and only then, the screen can turn on and display. That’s not what I want. Therefore, I put the code BlynkEdgent.begin(); and; into a separate task.

  • Lastly, I’ve cleaned my code and removed unnecessary code and moved all of my other #includes below #include “BlynkEdgent.h” as you suggested.

I hope this explains my project better and I look forward to hearing from you again. I welcome your questions and feedback. Please let me know if there is anything in my code or explanations that can be improved or clarified.


Hard coding literally means that the credential are written into your code (sketch) and uploaded to the device. You want to avoid hard-coding and have dynamic provisioning instead.

WiFiManager and Blynk Edgent are very different. They achieve the same result as far as WiFi credentials are concerned, but Edgent also dynamically provisions the Blynk Auth token, which WiFi manager can’t do.
With Edgent the WiFi and Auth token data is stored in EEPROM.
Never try to mix Edgent and WiFi manager, it won’t work.

I understand the reasoning, it’s the implementation I’m questioning. From my understanding, the Blynk functionality only works if it’s pinned to Core0, and you aren’t specifying cores.
Also, if you want to access the WiFi connection created by Blynk from the other core then I think you’re going to have problems. Dual core programming with Blynk is normally used to allow non-WiFi function to run on the other core, so as not to interrupt the stuff that the Blynk library needs to do in the background.

That was part of what I suggested, but it’s not much use without the rest of it.


Dear Pete,

Thank you for your clarification. I did not try to mix the WifiManager code with the Blynk.Edgent code, it was my mistake that I did not comment out the WifiManager code and caused the confusion. I did try to create and put all Blynk.Edgent tasks into core 0, but it still did not work at all. However, somehow the network connection still worked. Here are the screenshots of the serial monitor output and the task list:


Please don’t post screenshots of serial output, they are virtually unreadable.

Instead, copy and paste the text and post it with triple backticks - the same as when posting code - and add narrative as text where necessary.


Dear Pete,
Sorry about posting the screenshoots of serial output only. Here is the update of the reply.
Well as i said, I did try to create and put all Blynk.Edgent tasks into core 0, but it still did not work at all. However, somehow the network connection still worked.

  • Here is the config of my tasks:
  xTaskCreatePinnedToCore(TaskRunUI, "RunningUI", 10000, NULL, 5, &taskRunUI, app_cpu);
  xTaskCreatePinnedToCore(TaskButtonFunctions, "TurnOnOff_or_ChangeScreen_or_Configwifi", 10000, NULL, 4, &taskButtonFunctions, app_cpu);
  xTaskCreatePinnedToCore(TaskDisplayValueToScreen, "DisplayValueToScreen", 8000, NULL, 4, &taskDisplayValueToScreen, app_cpu);
  xTaskCreatePinnedToCore(TaskReadValues, "ReadValues", 5000, NULL, 3, &taskReadValues, app_cpu);
  // xTaskCreatePinnedToCore(TaskWifi, "Wifi", 10000, NULL, 2, &taskWifi, app_cpu);
  xTaskCreatePinnedToCore(TaskBlynkInit, "BlynkInit", 5000, NULL, 2, &taskBlynkInit, pro_cpu);
  xTaskCreatePinnedToCore(TaskBlynkRun, "BlynkRun", 10000, NULL, 1, &taskBlynkRun, pro_cpu);
  xTaskCreatePinnedToCore(TaskSendDataToFirebase, "ConnectSendDataToFirebase", 10000, NULL, 1, &taskSendDataToFirebase, app_cpu);

The app_cpu is core 1 and the pro_cpu is core 0.
The Serial show that:
Set str... ok Set str... ok Set str... ok Set str... ok Set int... ok Set str... ok
It’s mean that the data send to Firebase is okay, also the network connection too.
But meanwhile, though the network connection is okay. The Serial still shows
[2880090] Connecting to [2880226] Secure connection failed
It’s mean that I could not connect to Blynk server.


Okay, I’m going to step away from this topic because you’re not providing information that allows me to see code and serial output for your working Blynk Edgent setup and code and corresponding serial output for your non-working setup - despite me asking you for this.

Good luck with your project.