ESP32 could not connect to Blynk cloud

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. 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.

Here is the code if you guy would like to take a look:

#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>

/*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_TEMPLATE_ID ""
#define BLYNK_TEMPLATE_NAME ""

#define BLYNK_FIRMWARE_VERSION "0.1.1"

#define BLYNK_PRINT Serial
//#define BLYNK_DEBUG

#define APP_DEBUG

// Uncomment your board, or configure a custom board in Settings.h
#define USE_ESP32_DEV_MODULE
//#define USE_ESP32C3_DEV_MODULE
//#define USE_ESP32S2_DEV_KIT
//#define USE_WROVER_BOARD
//#define USE_TTGO_T7
//#define USE_TTGO_T_OI

#include "BlynkEdgent.h"
void TaskBlynk(void *pvParameters);
/* Config UART pins with PMS5003 */
#if !defined(PMS_RX) && !defined(PMS_TX)
constexpr auto PMS_RX = 16;
constexpr auto PMS_TX = 17;
#endif

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

// Alternative:
//SoftwareSerial SoftSerial1(PMS_RX, PMS_TX);
//SerialPM pms(PMS5003, SoftSerial1);
#else
SerialPM pms(PMS5003, PMS_RX, PMS_TX);  // PMSx003, RX, TX
#endif

/* 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;

/**************************************/

unsigned long myChannelNumber = 2195543;
const char *myWriteAPIKey = "ILTPLDAH60ENRIB6";
int number = 0;

WiFiClient client;
void TaskThingspeak(void *pvParameters);

/**************************************/

/* Init tasks and functions for updating values */
void ui_screen_1_reset();

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 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 baterry_V_Max 3.8f        // battery max voltage

/* 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;

/* 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.startWrite();
  tft.setAddrWindow(area->x1, area->y1, w, h);
  tft.pushColors((uint16_t *)&color_p->full, w * h, true);
  tft.endWrite();

  lv_disp_flush_ready(disp);
}

/*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.println(touchX);

    Serial.print("Data y ");
    Serial.println(touchY);
  }
}

void setup() {
  Serial.begin(115200); /* prepare for possible serial debug */
  lv_init();
  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;
  lv_disp_drv_init(&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;
  lv_disp_drv_register(&disp_drv);

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

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

  /* Init pins */
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  // pinMode(BAT_LV1, OUTPUT);
  pinMode(LEDA, OUTPUT);
  digitalWrite(LEDA, HIGH);
  ThingSpeak.begin(client);  // Initialize ThingSpeak
  delay(100);

  /* Init tasks */

  Serial.print("HEAP size left: ");
  Serial.println(ESP.getFreeHeap());
  // Task funct - taks name - stack size - parameters - task handle - core to run on
  wm.setTitle("Air Sensor");
  xTaskCreatePinnedToCore(TaskRunUI, "RunningUI", 10000, NULL, 5, &taskRunUI, pro_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(TaskSendDataToFirebase, "ConnectSendDataToFirebase", 10000, NULL, 1, &taskSendDataToFirebase, app_cpu);
  xTaskCreate(TaskBlynkRun, "BlynkRun", 10000, NULL, 1, &taskBlynkRun);
  xTaskCreate(TaskBlynkInit, "BlynkInit", 5000, NULL, 2, &taskBlynkInit);

  // xTaskCreate(TaskThingspeak, "Thingspeak", 10240, NULL, 1, NULL);

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

void TaskRunUI(void *pvParameters) {
  while (1) {
    lv_timer_handler(); /* let the GUI do its work */
    vTaskDelay(10 / portTICK_PERIOD_MS);
  }
}
void TaskBlynkInit(void *pvParameters) {
  BlynkEdgent.begin();
  vTaskDelete(NULL); // delete after done
}
void TaskBlynkRun(void *pvParameters) {
  while (1) {
    BlynkEdgent.run();
    vTaskDelay(100 / portTICK_PERIOD_MS);
  }
}
void TaskSendDataToFirebase(void *pvParameters) {
  config.api_key = API_KEY;

  /* Assign the user sign in credentials */
  // auth.user.email = USER_EMAIL;
  // auth.user.password = USER_PASSWORD;

  /* 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
  Firebase.reconnectNetwork(true);

  // 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 = "vC8UozBnsjJD5y4IfmKFLvFW4qcrTECxAlaMaTOT";

  // To connect without auth in Test Mode, see Authentications/TestMode/TestMode.ino

  //////////////////////////////////////////////////////////////////////////////////////////////
  // 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;
  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 > 2000) && 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());
      Serial.println(ESP.getFreeHeap());
    }
    vTaskDelay(200 / portTICK_PERIOD_MS);
  }
}

void loop() {
  // Do nothing in loop
}

void TaskWifi(void *pvParameters) {
  bool res;
  // res = wm.autoConnect(); // auto generated AP name from chipid
  // res = wm.autoConnect("AriSensor"); // anonymous ap
  res = wm.autoConnect("AriSensor", "password");  // password protected ap
  if (!res) {
    Serial.println("Failed to connect");
    // ESP.restart();
  } else {
    //if you get here you have connected to the WiFi
    Serial.println("connected...yeey :)");
  }
  vTaskDelete(NULL);  // delete task after connected
}

void TaskThingspeak(void *pvParameters) {
  while (1) {
    int x = ThingSpeak.writeField(myChannelNumber, 3, number, myWriteAPIKey);
    if (x == 200) {
      Serial.println("Channel update successful.");
    } else {
      Serial.println("Problem updating channel. HTTP error code " + String(x));
    }

    // change the value
    number++;
    if (number > 99) {
      number = 0;
    }
    vTaskDelay(15000 / 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
        ESP.restart();
        // 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) {
    pms.read();
    sht.read();
    // 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;
  }
}

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