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:
- Establish a wifi connection
- Configure blynk connection using Blynk.config()
- 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.