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