Problem connecting my ESP32 to Blynk using the Blynk.config() method

Hello Blynk community

I am using an ESP32 (wroom flavour) dev board and I am having a bit of a problem connecting it to Blynk using the Blynk.config()-Blynk.connect() method. I adapted Khoih’s ConfigOnSwitch example code to produce the following sketch:

#if !( defined(ESP8266) || defined(ESP32) )
  #error This code is intended to run only on the ESP8266 and ESP32 boards ! Please check your Tools->Board setting.
#endif
// Use from 0 to 4. Higher number, more debugging messages and memory usage.
#define _WIFIMGR_LOGLEVEL_    4
//For ESP32, To use ESP32 Dev Module, QIO, Flash 4MB/80MHz, Upload 921600
//Ported to ESP32
#include <esp_wifi.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>


//Functions and variables definitions required to achieve WiFi Manager 
#define ESP_getChipId()   ((uint32_t)ESP.getEfuseMac())  
#define LED_ON      HIGH
#define LED_OFF     LOW
// SSID and PW for Config Portal
String ssid = "ESP_" + String(ESP_getChipId(), HEX);
const char* password = "your_password";
// SSID and PW for your Router
String Router_SSID;
String Router_Pass;
IPAddress stationIP   = IPAddress(192, 168, 2, 114);
IPAddress gatewayIP   = IPAddress(192, 168, 2, 1);
IPAddress netMask     = IPAddress(255, 255, 255, 0);
IPAddress dns1IP      = gatewayIP;
IPAddress dns2IP      = IPAddress(8, 8, 8, 8);
// Use false if you don't like to display Available Pages in Information Page of Config Portal
// Comment out or use true to display Available Pages in Information Page of Config Portal
// Must be placed before #include <ESP_WiFiManager.h>
#define USE_AVAILABLE_PAGES     false
#include <ESP_WiFiManager.h>              //https://github.com/khoih-prog/ESP_WiFiManager
const int PIN_LED = 2; // On board LED to be replaced by external RGB LED D4.


void ConnectToWifiNetwork();
bool WebServerFlag=0;
bool ResetSettings=0;         
byte ReconnectedToNetwork=0;        //Used to determine if the controller was disconnected and then reconnected to the network
byte StoredCredentialsAvailable=1;

//For Blynk connection
byte BlynkCounter=0;
void CheckBlynkConnection();
byte SwitchLED=0;                                                                        
int WifiConnected=0;
char server[] = "blynk-cloud.com";  // URL for Blynk Cloud Server
int port = 8080;
char auth[]="XXXXXXXXXXXXXX";
char ssid0[50];     
char pass0[50];     
void MainFunction();
BlynkTimer timer1;
int len=50;


void setup()
{
  
  //Initialize the LED digital pin as an output.
  pinMode(PIN_LED, OUTPUT);
  //Initialise pin D18 as input to trigger WifiManager code
  pinMode(18, INPUT_PULLUP);
  
  Serial.begin(115200);
  Serial.println("\nWifi manager code: ConfigOnSwitchV5 includes ping test");
  delay(1000);
  ConnectToWifiNetwork();
  timer1.setInterval(300L, MainFunction);
  
}


void loop()
{ 
  Blynk.run();
  timer1.run();

}

void MainFunction(){

  Serial.println("MainFunction executed");
  check_status();
  //GPIO used to request new wifi credentials ...... "A" 
  if (digitalRead(18)==LOW) { 

    Serial.println("ESP32 has been disconnected from the current network and therefore from Blynk.\nRequesting WiFi Manager web portal\nWifi credentials are still be saved and will be erased upon successful connection to a new Wifi network");
    Blynk.disconnect();             //Disconnect from Blynk
    WiFi.disconnect(true);          //Disconnect from current wifi network
    ReconnectedToNetwork=0;         //Normalise it incase new network connection was requested when the old one was disconnected
    StoredCredentialsAvailable=0;
    ConnectToWifiNetwork();
    
  }
  //delay(1000);
  
}

//Checks the device's connection to the network and Blynk
void heartBeatPrint(void){
  
  if(WiFi.status() == WL_CONNECTED){
    if(ReconnectedToNetwork==1){
      Serial.println("Reconnected to network");
      ReconnectedToNetwork=0;
      SetupBlynkConnection();                             //Since the device has been reconnected to the network try to connect to blynk
      
    }
    else if(ReconnectedToNetwork==0){
      Serial.println("Still connected to wifi network");
      if(!Blynk.connected()){
        SetupBlynkConnection();  
      }
    }
    CheckBlynkConnection();                               //Check if the device is connected to Blynk via the current network

  }
  else{

    Serial.println("Connection failed. ESP32 is no longer connected to wifi network and is therefore disconnected from Blynk"); 
    Blynk.disconnect();          //Disconnect from blynk
    ReconnectedToNetwork=1;     
    WiFi.begin(Router_SSID.c_str(), Router_Pass.c_str()); //Try to reconnect to network
    
  }
  
}

//Determines how often to check devices network and blynk connection status
void check_status()
{
  static ulong checkstatus_timeout = 0;

  #define HEARTBEAT_INTERVAL    10000L                                      
  //Print hearbeat every HEARTBEAT_INTERVAL seconds.
  if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0))
  {
    heartBeatPrint();
    checkstatus_timeout = millis() + HEARTBEAT_INTERVAL;
  }
}

//Responsible for launching the WiFi manager and connect the ESP32 to the network with entered/stored credentials  
void ConnectToWifiNetwork(){

  Serial.println("ConnectToWifiNetwork() executed");
  ESP_WiFiManager ESP_wifiManager("ConfigOnSwitch");

  ESP_wifiManager.setDebugOutput(true);


  //Erases stored Wifi credentials 
  if(ResetSettings==1){
    resetSettings();                    
    ResetSettings=0;                            //Variable used to control the erasing of stored Wifi credentials
    delay(1000);                              
  }

  ESP_wifiManager.setMinimumSignalQuality(-1);
  ESP_wifiManager.setSTAStaticIPConfig(stationIP, gatewayIP, netMask, dns1IP, dns2IP);                             

  
  Serial.println("Checking if stored credentials are available");
  Router_SSID = ESP_wifiManager.WiFi_SSID();
  Router_Pass = ESP_wifiManager.WiFi_Pass();  
  if(Router_SSID==""){
    Serial.println("Router_SSID=='' therefore request new Wifi credentials via the Web portal");
    StoredCredentialsAvailable=0;
  }
  
  Serial.println("Stored: SSID = " + Router_SSID + ", Pass = " + Router_Pass);

  //SSID to uppercase
  ssid.toUpperCase();

  if (StoredCredentialsAvailable == 0){
     
   
    Serial.println("Requesting new WiFi credentials now");
    Serial.println("Opening configuration portal.");
    digitalWrite(PIN_LED, LED_ON); // Turn led on as we are in configuration mode.

    //Access point
    //and goes into a blocking loop awaiting configuration
    if (!ESP_wifiManager.startConfigPortal((const char *) ssid.c_str(), password)){

      if(WiFi.status() == WL_NO_SSID_AVAIL){

        Serial.println("In access point mode-The network requested is offline\nKeeping stored wifi credentials and continuing with program");
        Serial.println("Wifi.status result=" + String(WiFi.status()));
        StoredCredentialsAvailable=1;                                   
        
      }
      else{
        Serial.println("Failed to connect to WiFi network. Please check credentials and try again.");
        Serial.println("Wifi.status result=" + String(WiFi.status()));
        resetSettings();
        StoredCredentialsAvailable=0;                 //Request new Wifi credentials when "ConnectToWifiNetwork()" executes
        digitalWrite(PIN_LED, LED_OFF);               //Turn led off and it will turn back on when it runs the web portal again
        ESP.restart();                                //Restarts the ESP32 so that WiFi credentails can be requested again using the WiFi config portal
      }
    }
    else{
      Serial.println("Connection to Wifi network is successful in access point mode");
    }
  }

  digitalWrite(PIN_LED, LED_OFF); // Turn led off as we are not in configuration mode.

  //This 'if' statement was implemented to prevent the execution of this code again after initial startup
  if(WebServerFlag==0){
    
    #define WIFI_CONNECT_TIMEOUT        10000L  
    #define WHILE_LOOP_DELAY            200L
    #define WHILE_LOOP_STEPS            (WIFI_CONNECT_TIMEOUT / ( 3 * WHILE_LOOP_DELAY ))
    WebServerFlag=1;
  
  }
  unsigned long startedAt = millis();  startedAt = millis();

  while ( (WiFi.status() != WL_CONNECTED) && (millis() - startedAt < WIFI_CONNECT_TIMEOUT ) )
  {
    WiFi.mode(WIFI_STA);
    WiFi.persistent (true);

    //Connect to selected network using aquired/stored Wifi credentials
    Serial.print("Connecting to ");
    Serial.println(Router_SSID);
    WiFi.config(stationIP, gatewayIP, netMask);
    WiFi.begin(Router_SSID.c_str(), Router_Pass.c_str());

    int WifiCounter = 0;
    while ((!WiFi.status() || WiFi.status() >= WL_DISCONNECTED) && WifiCounter++ < WHILE_LOOP_STEPS)
    {
      delay(WHILE_LOOP_DELAY);
    }
  }

  Serial.print("After waiting ");
  Serial.print((millis() - startedAt) / 1000);
  Serial.print(" secs to connect to network, connection result: ");

  if (WiFi.status() == WL_CONNECTED){
    
    Serial.print("Connected. Local IP: ");
    Serial.println(WiFi.localIP());
    StoredCredentialsAvailable=1;

    //Store new credentials in global string variables
    Router_SSID = ESP_wifiManager.WiFi_SSID();       
    Router_Pass = ESP_wifiManager.WiFi_Pass();
       
    //Configures the connection to Blynk but does not connect to Blynk until Blynk.connect() or Blynk.run() is executed
    Serial.println("Blynk.config will be executed");
    //Blynk.config(auth);                                 //Since the ESP32 is connected to a network configure a connection for Blynk only once here in the program...... "B"
    delay(2000);
    SetupBlynkConnection(); 
    
  }
  else if(WiFi.status() == WL_NO_SSID_AVAIL){// If Wifi network saved is offline when the ESP32 is restarted then dont disconnect/erase the network or request a new credentials

    Serial.println("\nIn station mode-The network requested is offline\nKeeping stored Wifi credentials and continuing with program");
    StoredCredentialsAvailable=1;
    
  }
  else{
    Serial.println("Failed to connect to selected network. Network password has changed. Please update password credentials or select another network. Stored credentials have been erased");
    Serial.println(ESP_wifiManager.getStatus(WiFi.status()));
    StoredCredentialsAvailable=0;
    ResetSettings=1;
    ConnectToWifiNetwork();
  }
}


//Erases stored Wifi credentials from ESP32 volatile memory (memory that is not erased after ESP32 bootups)
void resetSettings()
{
  LOGINFO(F("Previous settings invalidated"));
  
#ifdef ESP8266  
  WiFi.disconnect(true);
#else
  WiFi.disconnect(true, true);
#endif

  delay(200);
  return;
}



bool SetupBlynkConnection(){

  
  Serial.println("SetupBlynkConnection() executed"); 

  //Using Blynk.begin as follows works perfectly ............ "C"
  /*
  Router_SSID.toCharArray(ssid0, len);
  Router_Pass.toCharArray(pass0, len);
  Serial.println(pass0);
  Serial.println(ssid0);  
  Blynk.begin(auth, ssid0, pass0);
  */

  //Using config as above  and calling Blynk.connect here however does not work unless "ConnectToWifiNetwork()" subroutine executes first ...... "D"
  //Router_SSID.toCharArray(ssid0, len);
  //Router_Pass.toCharArray(pass0, len);
  //Blynk.connectWiFi(ssid0,pass0);
  Blynk.config(auth);
  Blynk.connect(3000); 
  delay(2000);      
      
  if(Blynk.connected()){
      
    Serial.println("Blynk is connected");
    Blynk.virtualWrite(V0,255);                                   
    WifiConnected=1;      
       
  }
  else{
    Serial.println("Blynk is not connected");
  }   
 
  return (Blynk.connected());
}


void CheckBlynkConnection(){
  
  Serial.print("WifiConnected=");
  Serial.println(WifiConnected);
  
  if(!Blynk.connected()){         

    Serial.println("Blynk is not connected according to Blynk.connected()");
    BlynkCounter++;

    //After 2 consecutive 'not connected to Blynk' run Blynk.disconnect to prevent the ESP32 from running slow
    if(BlynkCounter==2){

      WifiConnected=0;
      Blynk.disconnect();
      Serial.println("Blynk disconnect code has been executed");
            
    }

  }
  else
  Serial.println("Blynk is connected"); 

}

Now I believe I understand how this method of connecting to Blynk works:

  1. Establish a wifi connection
  2. Configure blynk connection using Blynk.config()
  3. Use Blynk.connect() to connect the ESP32 to Blynk

As far as I can tell the code I have written always ensures that the ESP32 is connected to a Wifi network before it runs step 2 and 3. I have read a few blynk posts (such as here, here and here) that have verified these 3 steps. Here is my findings after running and testing the sketch above:
Situation 1- The ESP32 only connects to Blynk after requesting new WiFi credentials, using code segment A, and executing ConnectToWifiNetwork() . If I switch my router OFF then the ESP32 disconnects from the network and Blynk and upon switching the router ON again the ESP32 connects to the network and to Blynk.
Situation 2- If I have stored credentials on bootup, the ESP32 connects to the network but never connects to Blynk. It does not connect to Blynk on startup or when the subroutine heartBeatPrintexecutes
I have also tried to calling Blynk.connectWiFi(), as shown in the above code segment (segment labelled D), before Blynk.config(auth) reasoning that the only difference between situation 1 and 2 is that the ESP32 connects to Blynk immediately after connect to the network, but this did not work either.

**Update and correction:
Even when I use the Blynk.begin method (code segment C), commented out in the above code, connection still fails in the same manner as described above. I don’t intend on use this method anyway because I want to be prepared for the situation when the ESP32 successfully connects to a network which may not have an internet connection which will cause the ESP32 to hang.

I must be missing something but I am not sure what it is. Any advice or help will be greatly appreciated.

If you’re planning to use WiFiManager and Blynk together on ESP8266/ESP32, it’s better to use another library Blynk_WM, specially designed for that purpose, to save some headache and time

Check these previous posts on this forum

  1. Blynk WiFiManager for ESP8266/ESP32 with Multi-WiFi and Multi-Blynk

  2. WM Config Portal using BlynkSimpleEsp32/8266_WM.h

Hello khoih

Thanks for the reply. I wish I had seen come across your Blynk_WM sooner before I started with the above program. I am hoping for a fix for my adapted version of your example code since I finally have it tweaked and tested to operate according to the logic I wanted. Can you please afford me some advice to try to fix the above code

I have now tried a work around to use Blynk.begin instead of the Blynk.config() by incorporating the Ping() library conducting a simple ping to both google and blynk servers as a as a check to verify that the connected network has an internet connection in am aim to prevent hanging up my ESP32. The ping always fails unless the Wifi Manager code in ConnectToWifiNetwork() executed AFTER requesting new credentials on the web portal i.e. the complete code segment within ConnectToWifiNetwork runs. I do not understand this is the case because when the following example, without the Wifi manager code, everything runs smoothly i.e. if the network credentials I have hardcoded has an internet connection the ping is successful:


#include <WiFi.h>
#include <ESP32Ping.h>
 
const char* ssid = "XXXXXXX";
const char* password =  "XXXXXXXX";
bool success;
void ConnectToNetwork();
void PingNetwork();
void heartBeatPrint();
//const IPAddress remote_ip(8,8,8,8); //IP address for google public DNS server
const IPAddress remote_ip(45,55,96,146); //IP address for blynk servers (found by pinging blynk-cloud.com)

void setup() {
 
  Serial.begin(115200);
  Serial.println("\nPing test code V1");
  ConnectToNetwork();
  delay(2000);
  
}

void heartBeatPrint(void){

  if (WiFi.status() == WL_CONNECTED){
    Serial.println("Still connected to Wifi network");       
    delay(1000);
    PingNetwork();
  }
  else{
    Serial.println("Connection to network failed. Attempting to reconnect to network");        
    ConnectToNetwork();

  }
}

void loop() { 
  
  heartBeatPrint();
  delay(5000);
  
}


void ConnectToNetwork(){

  WiFi.begin(ssid, password);
   
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi network...");
  }
  if(WiFi.status() == WL_CONNECTED){
    Serial.println("Connected to WiFi network.\nNow checking if the network has an internet connection");
    delay(2000);
    PingNetwork();
  } 
}


void PingNetwork(){

  Serial.println("Pinging google servers...");
  //success = Ping.ping("www.google.com", 3);   //***When no simcard in wifi dongle still able to achieve success ping. So this is not working remove
  //success = Ping.ping(remote_ip);             //Works great!!***It only prints a maximum of 2 times not 5 as the default number of pings is 5 when not explicitly set as below***
  success = Ping.ping(remote_ip,2);             //Works great!!***But maybe change this to 1 so it happens quicker or at the most 2 becuase it only prints maximum 2 times anyway***
  
  //delay(2000);
  if(!success){
    Serial.println("Ping failed");
    return;
  }
  else
    Serial.println("Ping succesful.");

}

I am suspecting that something in my ConnectToWifiNetwork() subroutine or the WiFi manager library code is somehow causing some problem in the background that is causing the ESP32 to fail to connect to the internet even though its connected to the network :slightly_frowning_face:
I have also updated my initial posting to include the variable declarations in the hope someone will be kind enough to run the code and see if they achieve the same results I have and offer a possible fix or at least the area were the root cause of the problem might be.

Update: With reference to the adapted code in my posting. If I by pass the Wifi Manager code by ignoring the ConnectToWifiNetwork() subroutine segment completely and connect using and use hardcoded wifi credentials then the ESP32 connects to the network and I achieve a successful ping and am able to connect to Blynk using the command Blynk.begin(auth, HardCodedSSID,HardcodedPassword)

Why all the delays in your code?

Pete.

Hello Pete, thanks for the reply. The delays have been implemented because I found that the was code running in the background were occurring after other code segments instead of before e.g. sometimes the Wifi manager code responsible for connecting the ESP32 to the network did not complete setting up the connection before the check to see if the ESP32 was connected was executed and the ESP32 would register that it was not connected to a network according to the serial monitor printout

If you want things to work with Blynk then the delays need to go, unless you start doing some multi-threaded coding, which isn’t the approach I’d recommend.

Your description of why the delays are used sounds like a workaround that doesn’t really fix the issue, but which works as part of your current testing. Delays aren’t the answer, and are really just a sloppy fix.

There are a great many other pieces of sloppy coding in the code that is in your original post. Take this as an example…

You call MainFunction every 0.3 seconds and it in turn calls check_status, which contains this line:

As it happens, when the IDE compiles this it will assign the value of 10000 to the constant HEARTBEAT_INTERVAL, so it’s not really doing any harm to have this within the function that called every 0.3 seconds, but it’s far from being good practice.

There are many other examples, but I gave up with the code after encountering a few of them.

Sticking with this code has no benefits that I can see, and it would be better to follow @khoih’s advice and use the correct libraries for the task that you are trying to achieve.

Pete.

Hello Pete

I apologize for the sloppiness. I have left code segments as they were and did not care to refine them since my focus was to get the code functional. I will focus on refining the sloppiness out once I achieve a working program. I doubt removing the delays will solve the current problem since I have narrowed down the issue to be the within the ConnectToWifiNetwork() and since the code ran perfectly fine without the WiFi management code as I mentioned earlier. But you are right delays don’t generally play well with Blynk in the long run so I will remove them.

As I mentioned in my previous post,again, I have finally managed to adapt the example code to operate according to the logic that I needed. It took me a considerable amount of testing and time to get it that way. Aside from the time it would take to start that process over, I encountered compile errors for the stock example I found in the suggested khoih library. All this will take a considerable longer time to resolve especially considering how close I am to achieving an operational program with this code. I hope this elucidates the benefit to you now.

I have continued experimenting and found that commenting out wifi.config() command from ConnectToWifiNetwork solves my problem almost entirely. There does appear to be some unhappiness only under the circumstance where I start the Wifi manager web portal and select the “Exit portal” option- then the problem I am experiencing persists (ESP32 connects to the network but not to the internet and not to Blynk obviously). This is the only instance where my current program fails so I will have to settle for the work around of restarting the ESP32. I think my actual problem is understanding how the ESP32 needs to be configured to enable a successful network, internet and Blynk connection. I will need to look into this in future. Anyway thanks for the suggestion and remarks.

A post was split to a new topic: Problems provisioning board when using Edgent