BLYNK
HOME       📲 GETTING STARTED       📗 DOCS       ❓HELP CENTER       👉 SKETCH BUILDER

WM Config Portal using BlynkSimpleEsp32/8266_WM.h

Happy to test and suggest. Thanks so much.

1 Like

Dear @thorathome

Just to warn :wink: you to spare some time to test new release soon :wink:

These features are done and tested OK

  1. Config Portal title, either
  • Hostname defined in defines.h and configurable such as Master-Controller, or
  • BoardName got via ConfigPortal, or
  • default undistinguishable names.
  1. Configurable pre-loaded default Config Portal values, including dynamic parameters. You can select either to load default pre-defined Credentials or “blank”
  2. Examples are redesigned to separate Credentials / Defines / Code so that you can change Credentials quickly for each device.

A real test screen to show Title and all the default Credentials are loaded onto Config Portal

Will add

  1. DoubleResetDetector to force starting ConfigPortal. DONE.
  2. Update README. Can you help write and update this?
  3. What else do you think?
  4. Your contribution will be noted in v1.0.13 (lucky number for me)

Will post v1.0.13 within today.

With all the work you are doing @khoih, I would be happy to write a Readme for/with you.

Give me the week to draft something. I’ll post it here along with my demo code which I now use as a starting template for new Blynk ESP32/8266 projects. If you think it’s helpful, you can use it.

Again, I find your software very helpful and quite usable. Thank you for your time and dedication. It made it easier for me to get started with Blynk.

2 Likes

Dear @thorathome

Just update and post v1,0,13 on GitHub, thanks to your enhancement requests.

I’ve also updated the README, but a hasty job with certainly many problems. Please fix and enhance it.

Your contribution is also noted in that README. Don’t delete it, please.

Have something for you to kill time now. I appreciate it and also would like bugs found and killed :slight_smile:

More enhancement requests always needed.

On it. Will have to learn how to contribute to Github! Still a newbie there. If I create a fork, are you able to evaluate and bring it into the master?

Yes, you can fork, then make pull request (PR) or just show me the link I’ll go there and get it.

But IMHO, testing, enhancement suggesting and bug finding / killing are more important and have higher priority.

I also updated the relating topic on this forum

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

Hi @khoih
I have added
bool LOAD_DEFAULT_CONFIG_DATA = false;
early in my sketch, before any of the #includes, am getting error msg:
…\Arduino\My New Sketchbook\libraries\Blynk_Main\src/BlynkSimpleEsp8266_SSL_WM.h:808: undefined reference to `defaultConfig’

I get the same error msg if LOAD_DEFAULT_CONFIG_DATA = true
Your thoughts? Thanks.

Hi @thorathome

There are many changes in the library in v1.0.13, so your code must be changed to follow.

Could you pls have a look at the new examples to see how to restructure the code.

But from the error, I believe that you need to add this code snippet to your sketch (or copy to code directory and add #include “Credentials.h”), even you don’t use LOAD_DEFAULT_CONFIG_DATA

bool LOAD_DEFAULT_CONFIG_DATA = true;
//bool LOAD_DEFAULT_CONFIG_DATA = false;

Blynk_WM_Configuration defaultConfig =
{
  //char header[16], dummy, not used
#if USE_SSL  
  "SSL",
#else
  "NonSSL",
#endif
  //WiFi_Credentials  WiFi_Creds  [NUM_WIFI_CREDENTIALS]
  //WiFi_Creds.wifi_ssid and WiFi_Creds.wifi_pw
  "SSID1", "password1",
  "SSID2", "password2",
  // Blynk_Credentials Blynk_Creds [NUM_BLYNK_CREDENTIALS];
  // Blynk_Creds.blynk_server and Blynk_Creds.blynk_token
  "account.ddns.net",     "token",
  "account.duckdns.org",  "token1", 
  //int  blynk_port;
#if USE_SSL
  9443,
#else
  8080,
#endif
  //char board_name     [24];
  "Air-Control",
  //int  checkSum, dummy, not used
  0
};

This is your code modified to eliminate that error

#define SERIAL_SPEED 230400
#define PROGRAM_NAME "AAA-Blynk WiFiMgr Demo_ESP32_ESP8266"
// Uses ESP32 and ESP8266 to select compile choices


//BLYNK Stuff here
#define BLYNK_PRINT Serial

#define USE_SSL true // to easily select SSL or not
//#define USE_SSL false // to easily select SSL or not

#define USE_WM true   // to easily select WiFi Manager or not
//#define USE_WM false   // to easily select WiFi Manager or not

// REMEMBER: not using _WM means we manage our own initial WiFi connection


#if USE_WM
  #define USE_SPIFFS false  // Choosing EEPROM over SPIFFS here

  #if (!USE_SPIFFS)
    // EEPROM_SIZE must be <= 2048 and >= CONFIG_DATA_SIZE (currently 172 bytes)
    #define EEPROM_SIZE    (2 * 1024)
    // EEPROM_START + CONFIG_DATA_SIZE must be <= EEPROM_SIZE
    #define EEPROM_START   512
  #endif

  #define USE_DYNAMIC_PARAMETERS false  // see Github doc
  
  // Force some params in Blynk, only valid for library version 1.0.1 and later
  // (from the Github doc)
  #define TIMEOUT_RECONNECT_WIFI                    10000L
  #define RESET_IF_CONFIG_TIMEOUT                   true
  #define CONFIG_TIMEOUT_RETRYTIMES_BEFORE_RESET    5
#endif


#if USE_SSL
  #ifdef ESP8266
    #if USE_WM
      #include <BlynkSimpleEsp8266_SSL_WM.h>
    #else
      #include <BlynkSimpleEsp8266_SSL.h>
    #endif
  #endif
  #ifdef ESP32
    #if USE_WM
      #include <BlynkSimpleEsp32_SSL_WM.h> 
    #else
      #include <BlynkSimpleEsp32_SSL.h>
    #endif
  #endif
  
#else // NOT using SSL
  #ifdef ESP8266
    #if USE_WM
      #include <BlynkSimpleEsp8266_WM.h>
    #else
      #include <BlynkSimpleEsp8266.h>
    #endif
  #endif
  #ifdef ESP32
    #if USE_WM
      #include <BlynkSimpleEsp32_WM.h>
    #else
      #include <BlynkSimpleEsp32.h>
    #endif
  #endif
#endif


#if USE_WM
  #define USE_DYNAMIC_PARAMETERS false

  MenuItem myMenuItems [] = {};

  uint16_t NUM_MENU_ITEMS = 0;

/////////// Start Default Config Data /////////////

bool LOAD_DEFAULT_CONFIG_DATA = true;
//bool LOAD_DEFAULT_CONFIG_DATA = false;

Blynk_WM_Configuration defaultConfig =
{
  //char header[16], dummy, not used
#if USE_SSL  
  "SSL",
#else
  "NonSSL",
#endif
  //WiFi_Credentials  WiFi_Creds  [NUM_WIFI_CREDENTIALS]
  //WiFi_Creds.wifi_ssid and WiFi_Creds.wifi_pw
  "SSID1", "password1",
  "SSID2", "password2",
  // Blynk_Credentials Blynk_Creds [NUM_BLYNK_CREDENTIALS];
  // Blynk_Creds.blynk_server and Blynk_Creds.blynk_token
  "account.ddns.net",     "token",
  "account.duckdns.org",  "token1", 
  //int  blynk_port;
#if USE_SSL
  9443,
#else
  8080,
#endif
  //char board_name     [24];
  "Air-Control",
  //int  checkSum, dummy, not used
  0
};

/////////// End Default Config Data /////////////
  
#endif // USE_WM



char blynkAuth[] = "<my auth>"; // BLYNK Auth 

char WiFiSSID[] = "<my ssid";  // network SSID (name)
char WiFiPass[] = "<my passcode>";  // network password



BlynkTimer myTimer;
// Blynk timers to blink a heartbeat LED on and off
int heartbeatLEDinterval = 3000; // interval between heartbeats for onboard and Blynk Virtual LED in millisec 
int heartbeatLEDtimerID; 

int heartbeatLEDduration = 750; // duraction of each blink in millisec (set as an interval timer)
int heartbeatLEDdurationTimerID;
bool heartbeatLEDon = false; // this lets me use the same routine for the turn-on timer and the turn-off interval

#define BLYNK_HEARTBEAT_LED V2
WidgetLED heartbeatLED( BLYNK_HEARTBEAT_LED );  // want a blinking LED on the display to show we're live



/* setup
 *  Set up WiFi, Blynk & Blynk timers 
 *  Set up Blue LED on board
 */
void setup() 
{
  Serial.begin ( SERIAL_SPEED );
  delay ( 500 );  
  Serial.println ( "\n\n=======================================" );
  Serial.print ( PROGRAM_NAME ); 
  #if USE_SSL
    Serial.println ( " ** Using SSL ** \n" );  
  #endif
  Serial.println();
  
  connectToLANandBlynk();  

  // Initialize Onboard LED 
  pinMode ( LED_BUILTIN, OUTPUT );  
  digitalWrite ( LED_BUILTIN, LOW ); 
    
  // Set Blynk Virtual LED OFF
  heartbeatLED.off(); // Blynk Virtual LED
  heartbeatLEDblink(); // first heartbeat 
  
  Serial.println ( "\nSetup complete \n" );    
  
} //end setup




void loop()
{
  Blynk.run();
  myTimer.run();  
} 




void connectToLANandBlynk()
{
  // Setup WLAN and Blynk
  Serial.print ( "\nSetting up WLAN and Blynk " );  
  #if USE_WM
    Serial.println ( "WITH WiFiManager" ); 
  #else
    Serial.println ( "WITHOUT WiFiManager" );  
  #endif
  
  #if USE_WM
    Serial.println ( "Starting Blynk.begin (with WM)" );  

    Blynk.setConfigPortal ( "TestPortal", "123" );
    Serial.println ( "Blynk.setConfigPortal(TestPortal, 123);" );  

    Blynk.setConfigPortalIP ( IPAddress ( 192, 168, 220, 1 ) );  
    Blynk.config ( blynkAuth );
    Blynk.begin ( "Blynk-Configurator" ); 
    
  #else//NOT using WM
    Serial.println ( "Starting WiFi.begin (no WM)" );  
    WiFi.begin ( WiFiSSID, WiFiPass );
    Serial.println ( "... waiting a few seconds for WiFi ..." );    
    delay ( 7000 );  // For esp8266, it needs a delay to realize it has connected
    
    // REBOOT if we do not have a good WiFi connection
    if ( WiFi.status() != WL_CONNECTED )
    {
      Serial.println ( "Resetting in a few seconds..." );
      delay ( 3000 );  
      ESP.restart();
    } 
    
    // Configure and launch Blynk
    Blynk.config ( blynkAuth );
    Blynk.connect ( 2500 ); // Don't get stuck hanging for more than 2500 millis.
  #endif // using WM
  
  if ( Blynk.connected() ) Serial.println ( "Blynk connected just fine\n" ); 
  else Serial.println ( "Blynk NOT CONNECTED \n\n" );  

  #if USE_WM
    #if USE_SPIFFS
      Serial.println("\nBlynk using SPIFFS connected. Board Name : " + Blynk.getBoardName());
    #else
      Serial.println("\nBlynk using EEPROM connected. Board Name : " + Blynk.getBoardName());
      Serial.printf("EEPROM size = %d bytes, EEPROM start address = %d / 0x%X\n", EEPROM_SIZE, EEPROM_START, EEPROM_START);
    #endif
  #endif


  Serial.println ( "Setting up Blynk timer" );  
  // Interval timer for heartbeatLED (Blynk LED and onboard LED
  heartbeatLEDtimerID = myTimer.setInterval ( heartbeatLEDinterval, heartbeatLEDblink );  

  Serial.println ( "..Blynk config and timers setup complete\n" );  
} //end connectToBlynk




void heartbeatLEDblink()
/* Blink the on-board LED AND the Virtual Blynk LED
 * First time called, it turne the LEDs on, then sets a timer to turn LED off
 * When the timer triggers, same routine turns the LEDs off
 */
{
  if ( heartbeatLEDon ) // if LED is on, turn it off and vice cersa
  {
    heartbeatLED.off(); // Blynk Virtual LED
    
    digitalWrite ( LED_BUILTIN, LOW ); // On-board LED
    
    Serial.println ( " ..." );
  } else
  {
    heartbeatLED.on();      // Blynk Virtual LED
    
    digitalWrite ( LED_BUILTIN, HIGH );  // On-board LED
    
    // Set the timer to turn off the LEDs in a bit  
    heartbeatLEDdurationTimerID = myTimer.setTimeout ( heartbeatLEDduration, heartbeatLEDblink ); 
    
    Serial.print ( "... heartbeat of " ); Serial.print ( PROGRAM_NAME ); 
    Serial.print ( " WiFi.status() = " ); Serial.print ( WiFi.status() );  
  }
  
  heartbeatLEDon = ! heartbeatLEDon; // flip status
} //end heartbeatLEDblink




// CALLED WHEN CONNECTING TO BLYNK SERVERS
// GETS CALLED IMMEDIATELY ON FIRST CONNECT
// THIS SYNCS UP SLIDER AND PUSHBUTTON WHEN BLYNK CONNECTS - EVEN FOR THE FIRST TIME
BLYNK_CONNECTED()
{
  Serial.println ( "\nBLYNK_CONNECTED..." );  
}

Hi @khoih
Getting there.

I am testing the code as you sent to me. Included below. Thanks for making it easy for me !

It appears the LOAD_DEFAULT_CONFIG_DATA is not doing what I’m expecting.
What I think I see is that the previous values stored in EEPROM are still being used after a new compile and upload.

In this log, you see items [628] – [632] show values that are not in the code. These are PREVIOUS values I loaded from the Config Portal in a previous compile and upload.
They appear to not be overwriting in the new compile and execute.

Additional question: what purpose does Blynk.config ( bklynkAuth ); have in line 197 now? How is the authcode set using WM?

My test code is below. Have fun. (I am.)

Here’s my log…

AAA-Blynk WiFiMgr Demo_ESP32_ESP8266 ** Using SSL ** 
Setting up WLAN and Blynk WITH WiFiManager
Starting Blynk.begin (with WM)
Blynk.setConfigPortal(TestPortal, 123);
[567] 
    ___  __          __
   / _ )/ /_ _____  / /__
  / _  / / // / _ \/  '_/
 /____/_/\_, /_//_/_/\_\
        /___/ v0.6.1 on NodeMCU

[627] Hostname=Blynk-Configurator
[627] CCSum=0x2eea,RCSum=0x2eea
[628] Hdr=SSL_ESP8266,BrdName=Air-Control
[628] SSID=SSID2,PW=password2
[628] SSID1=<my_real_SSID>,PW1=<my_real_pass>
[629] Server=blynk-cloud.com,Token=<my_Blynk_auth_token>
[632] Server1=account.duckdns.org,Token1=token1
[634] Port=9443
[635] ======= End Config Data =======
[637] Connecting MultiWifi...
[3640] WiFi connected after time: 1
[3640] SSID: <my_real_SSID>, RSSI = -54
[3640] Channel: 6, IP address: 192.168.4.56
[3640] bg: WiFi OK. Try Blynk
[3641] 
    ___  __          __
   / _ )/ /_ _____  / /__
  / _  / / // / _ \/  '_/
 /____/_/\_, /_//_/_/\_\
        /___/ v0.6.1 on NodeMCU

[4161] NTP time: Mon Apr 27 21:42:06 2020
[4161] Connecting to blynk-cloud.com:9443
[5017] Certificate OK
[5035] Ready (ping: 2ms).

BLYNK_CONNECTED...
[5120] Connected to Blynk Server = blynk-cloud.com, Token = <my_Blynk_auth_token>
[5120] bg: WiFi+Blynk OK
Blynk connected just fine


Blynk using EEPROM connected. Board Name : Air-Control
EEPROM size = 2048 bytes, EEPROM start address = 512 / 0x200
Setting up Blynk timer
..Blynk config and timers setup complete

... heartbeat of AAA-Blynk WiFiMgr Demo_ESP32_ESP8266 WiFi.status() = 3
Setup complete

end of log

Hers’s my code:

#define SERIAL_SPEED 230400
#define PROGRAM_NAME "AAA-Blynk WiFiMgr Demo_ESP32_ESP8266"
// Uses ESP32 and ESP8266 to select compile choices


//BLYNK Stuff here
#define BLYNK_PRINT Serial

#define USE_SSL true // to easily select SSL or not
//#define USE_SSL false // to easily select SSL or not

#define USE_WM true   // to easily select WiFi Manager or not
//#define USE_WM false   // to easily select WiFi Manager or not
// REMEMBER: not using _WM means we manage our own initial WiFi connection


#if USE_WM
  #define USE_SPIFFS false  // Choosing EEPROM over SPIFFS here

  #if (!USE_SPIFFS)
    // EEPROM_SIZE must be <= 2048 and >= CONFIG_DATA_SIZE (currently 172 bytes)
    #define EEPROM_SIZE    (2 * 1024)
    // EEPROM_START + CONFIG_DATA_SIZE must be <= EEPROM_SIZE
    #define EEPROM_START   512
  #endif

  #define USE_DYNAMIC_PARAMETERS false  // see Github doc
  
  // Force some params in Blynk, only valid for library version 1.0.1 and later
  // (from the Github doc)
  #define TIMEOUT_RECONNECT_WIFI                    10000L
  #define RESET_IF_CONFIG_TIMEOUT                   true
  #define CONFIG_TIMEOUT_RETRYTIMES_BEFORE_RESET    5
#endif


#if USE_SSL
  #ifdef ESP8266
    #if USE_WM
      #include <BlynkSimpleEsp8266_SSL_WM.h>
    #else
      #include <BlynkSimpleEsp8266_SSL.h>
    #endif
  #endif
  #ifdef ESP32
    #if USE_WM
      #include <BlynkSimpleEsp32_SSL_WM.h> 
    #else
      #include <BlynkSimpleEsp32_SSL.h>
    #endif
  #endif
  
#else // NOT using SSL
  #ifdef ESP8266
    #if USE_WM
      #include <BlynkSimpleEsp8266_WM.h>
    #else
      #include <BlynkSimpleEsp8266.h>
    #endif
  #endif
  #ifdef ESP32
    #if USE_WM
      #include <BlynkSimpleEsp32_WM.h>
    #else
      #include <BlynkSimpleEsp32.h>
    #endif
  #endif
#endif


#if USE_WM
  #define USE_DYNAMIC_PARAMETERS false

  MenuItem myMenuItems [] = {};

  uint16_t NUM_MENU_ITEMS = 0;

/////////// Start Default Config Data /////////////

bool LOAD_DEFAULT_CONFIG_DATA = true;
//bool LOAD_DEFAULT_CONFIG_DATA = false;

Blynk_WM_Configuration defaultConfig =
{
  //char header[16], dummy, not used
#if USE_SSL  
  "SSL",
#else
  "NonSSL",
#endif
  //WiFi_Credentials  WiFi_Creds  [NUM_WIFI_CREDENTIALS]
  //WiFi_Creds.wifi_ssid and WiFi_Creds.wifi_pw
  "SSID2", "password2",
  "Baloney", "Baloney",
  // Blynk_Credentials Blynk_Creds [NUM_BLYNK_CREDENTIALS];
  // Blynk_Creds.blynk_server and Blynk_Creds.blynk_token
  "account.duckdns.org",  "token1", 
  "blynk-cloud.com",     "<my_Blynk_auth_token>",
  //int  blynk_port;
#if USE_SSL
  9443,
#else
  8080,
#endif
  //char board_name     [24];
  "Air-Control",
  //int  checkSum, dummy, not used
  0
};

/////////// End Default Config Data /////////////
  
#endif // USE_WM



char blynkAuth[] = "<my auth>"; // BLYNK Auth 

char WiFiSSID[] = "<my ssid";  // network SSID (name)
char WiFiPass[] = "<my passcode>";  // network password



BlynkTimer myTimer;
// Blynk timers to blink a heartbeat LED on and off
int heartbeatLEDinterval = 3000; // interval between heartbeats for onboard and Blynk Virtual LED in millisec 
int heartbeatLEDtimerID; 

int heartbeatLEDduration = 750; // duraction of each blink in millisec (set as an interval timer)
int heartbeatLEDdurationTimerID;
bool heartbeatLEDon = false; // this lets me use the same routine for the turn-on timer and the turn-off interval

#define BLYNK_HEARTBEAT_LED V2
WidgetLED heartbeatLED( BLYNK_HEARTBEAT_LED );  // want a blinking LED on the display to show we're live



/* setup
 *  Set up WiFi, Blynk & Blynk timers 
 *  Set up Blue LED on board
 */
void setup() 
{
  Serial.begin ( SERIAL_SPEED );
  delay ( 500 );  
  Serial.println ( "\n\n=======================================" );
  Serial.print ( PROGRAM_NAME ); 
  #if USE_SSL
    Serial.println ( " ** Using SSL ** \n" );  
  #endif
  Serial.println();
  
  connectToLANandBlynk();  

  // Initialize Onboard LED 
  pinMode ( LED_BUILTIN, OUTPUT );  
  digitalWrite ( LED_BUILTIN, LOW ); 
    
  // Set Blynk Virtual LED OFF
  heartbeatLED.off(); // Blynk Virtual LED
  heartbeatLEDblink(); // first heartbeat 
  
  Serial.println ( "\nSetup complete \n" );    
  
} //end setup




void loop()
{
  Blynk.run();
  myTimer.run();  
} 




void connectToLANandBlynk()
{
  // Setup WLAN and Blynk
  Serial.print ( "\nSetting up WLAN and Blynk " );  
  #if USE_WM
    Serial.println ( "WITH WiFiManager" ); 
  #else
    Serial.println ( "WITHOUT WiFiManager" );  
  #endif
  
  #if USE_WM
    Serial.println ( "Starting Blynk.begin (with WM)" );  

    Blynk.setConfigPortal ( "TestPortal", "12345678" );
    Serial.println ( "Blynk.setConfigPortal(TestPortal, 123);" );  

    Blynk.setConfigPortalIP ( IPAddress ( 192, 168, 220, 1 ) );  
    Blynk.config ( blynkAuth );
    Blynk.begin ( "Blynk-Configurator" ); 
    
  #else//NOT using WM
    Serial.println ( "Starting WiFi.begin (no WM)" );  
    WiFi.begin ( WiFiSSID, WiFiPass );
    Serial.println ( "... waiting a few seconds for WiFi ..." );    
    delay ( 7000 );  // For esp8266, it needs a delay to realize it has connected
    
    // REBOOT if we do not have a good WiFi connection
    if ( WiFi.status() != WL_CONNECTED )
    {
      Serial.println ( "Resetting in a few seconds..." );
      delay ( 3000 );  
      ESP.restart();
    } 
    
    // Configure and launch Blynk
    Blynk.config ( blynkAuth );
    Blynk.connect ( 2500 ); // Don't get stuck hanging for more than 2500 millis.
  #endif // using WM
  
  if ( Blynk.connected() ) Serial.println ( "Blynk connected just fine\n" ); 
  else Serial.println ( "Blynk NOT CONNECTED \n\n" );  

  #if USE_WM
    #if USE_SPIFFS
      Serial.println("\nBlynk using SPIFFS connected. Board Name : " + Blynk.getBoardName());
    #else
      Serial.println("\nBlynk using EEPROM connected. Board Name : " + Blynk.getBoardName());
      Serial.printf("EEPROM size = %d bytes, EEPROM start address = %d / 0x%X\n", EEPROM_SIZE, EEPROM_START, EEPROM_START);
    #endif
  #endif


  Serial.println ( "Setting up Blynk timer" );  
  // Interval timer for heartbeatLED (Blynk LED and onboard LED
  heartbeatLEDtimerID = myTimer.setInterval ( heartbeatLEDinterval, heartbeatLEDblink );  

  Serial.println ( "..Blynk config and timers setup complete\n" );  
} //end connectToBlynk




void heartbeatLEDblink()
/* Blink the on-board LED AND the Virtual Blynk LED
 * First time called, it turne the LEDs on, then sets a timer to turn LED off
 * When the timer triggers, same routine turns the LEDs off
 */
{
  if ( heartbeatLEDon ) // if LED is on, turn it off and vice cersa
  {
    heartbeatLED.off(); // Blynk Virtual LED
    
    digitalWrite ( LED_BUILTIN, LOW ); // On-board LED
    
    Serial.println ( " ..." );
  } else
  {
    heartbeatLED.on();      // Blynk Virtual LED
    
    digitalWrite ( LED_BUILTIN, HIGH );  // On-board LED
    
    // Set the timer to turn off the LEDs in a bit  
    heartbeatLEDdurationTimerID = myTimer.setTimeout ( heartbeatLEDduration, heartbeatLEDblink ); 
    
    Serial.print ( "... heartbeat of " ); Serial.print ( PROGRAM_NAME ); 
    Serial.print ( " WiFi.status() = " ); Serial.print ( WiFi.status() );  
  }
  
  heartbeatLEDon = ! heartbeatLEDon; // flip status
} //end heartbeatLEDblink




// CALLED WHEN CONNECTING TO BLYNK SERVERS
// GETS CALLED IMMEDIATELY ON FIRST CONNECT
BLYNK_CONNECTED()
{
  Serial.println ( "\nBLYNK_CONNECTED..." );  
}

1Q. How can my sketch pre-program default values for the WM Config Portal? It would be nice to not start with blanks everywhere in the Portal.

1A. That’s a good idea for future version. Currently, at the first time without any valid data, the values are cleared to blank so that essential values must be input to be different from blank or ConfigPortal will stay.

Repeating our conversation yesterday: it would be useful to be able to pre-populate the Config Portal fields so we do not start with blanks each time.

In this log, you see items [628] – [632] show values that are not in the code. These are PREVIOUS values I loaded from the Config Portal in a previous compile and upload.
They appear to not be overwriting in the new compile and execute.

I’m afraid that is the idea behind the Config Portal we’d agree on in previous conversation as the stored Cred are still valid and Config Portal not opened.

The default values for Config Portal is uploaded into Config Portal (to save time for you to retype and also permit you to change faster if for too many boards) and replace the old Credentials if and only if the Config Portal is opened and Save is selected.
Otherwise, the default Credentials is not used at all.

If you’d like the default Creds are always loaded and the stored Creds bypassed, that’s a different scenario. It’s can be done easily but I don’t know if this is good use case as this is similar to the hardcoded scenario we’d like to avoid.

Doing so,

  1. Config Portal is not used and
  2. it presents a potential danger as well as inconvenience as you have to always keep the correct (not just dummy) Credentials in the code instead of storing in EEPROM/SPIFFS. In development, whenever you have a blank Creds. Config Portal will open and get the valid Creds. From that moment, you can replace the valid Creds file with the dummy Creds file.

Certainly, If you wish, I’ll try to explore an option to always use the default hardcoded Creds instead of stored and still valid Creds.

In development, DRD comes to rescue. Did you have chance to try DRD? Like it?
Just pressing RESET twice within 10s, Config Portal will come and give you your wish :wink:

Please give this some more thoughts and discuss later.

Additional question: what purpose does Blynk.config ( bklynkAuth ); have in line 197 now? How is the authcode set using WM?

I think Blynk.config ( blynkAuth ); in line 197 is not necessary and must be deleted. I really haven’t looked thru your recent code to see it as we already knew previously

I also killed the Blynk.config line when using _WM. I missed that.

In WM, that Blynk.config ( blynkAuth ); must be called somewhere in the WM code so that Blynk Server is happy.

bool connectMultiBlynk(void)
{
#define BLYNK_CONNECT_TIMEOUT_MS      5000L

 ...
        config(BlynkESP32_WM_config.Blynk_Creds[i].blynk_token,
               BlynkESP32_WM_config.Blynk_Creds[i].blynk_server, 
               BLYNK_SERVER_HARDWARE_PORT);
...

    }

Happy go on searching and exploring :heart_eyes:

Continuing my hunt, @khoih in your software.

I will EMBRACE your philosophy on the Config Portal. It only gets activated when WM cannot connect to Blynk.

Will test DYNAMIC_PARAMETERS next, then DRD.

Glad to see additional interest in your work!

1 Like

Hi @khoih

Having difficulty grabbing the updated values of DYNAMIC_PARAMETERS set in the Config Portal. The updated values from the standard Config Portal fields all work perfectly!

In my code
Lines 89-110 define 4 DYNAMIC_PARAMETERS and give default values.
I am using these parameters to set Virtual pin numbers and widget labels to generalize Sonoff applications.

I am expecting to find the values of these four char variables (controlVpin, controlLabel, heartbeatVpin, heartbeatLabel) to be reset by Config Portal.
The print statements in BLYNK_CONNECTED and in BLYNK_WRITE_DEFAULT show the default values set in the code, do not appear to be changed when modified in the Config Portal.

If I change the values in Config Portal, I do not see these 4 char variables take on the updated values in the runtime program.

Thoughts?

My code:

#define SERIAL_SPEED 230400
#define PROGRAM_NAME "AAA-Blynk WiFiMgr Demo_ESP32_ESP8266"
// Uses ESP32 and ESP8266 to select compile choices


//BLYNK Stuff here
#define BLYNK_PRINT Serial

#define USE_SSL true // to easily select SSL or not
//#define USE_SSL false // to easily select SSL or not

#define USE_WM true   // to easily select WiFi Manager or not
//#define USE_WM false   // to easily select WiFi Manager or not
// REMEMBER: not using _WM means we manage our own initial WiFi connection


#if USE_WM
  #define USE_SPIFFS false  // Choosing EEPROM over SPIFFS here

  #if (!USE_SPIFFS)
    // EEPROM_SIZE must be <= 2048 and >= CONFIG_DATA_SIZE (currently 172 bytes)
    #define EEPROM_SIZE    (2 * 1024)
    // EEPROM_START + CONFIG_DATA_SIZE must be <= EEPROM_SIZE
    #define EEPROM_START   512
  #endif

 
  // Force some params in Blynk, only valid for library version 1.0.1 and later
  // (from the Github doc)
  #define TIMEOUT_RECONNECT_WIFI                    10000L
  #define RESET_IF_CONFIG_TIMEOUT                   true
  #define CONFIG_TIMEOUT_RETRYTIMES_BEFORE_RESET    5
#endif


#if USE_SSL
  #ifdef ESP8266
    #if USE_WM
      #include <BlynkSimpleEsp8266_SSL_WM.h>
    #else
      #include <BlynkSimpleEsp8266_SSL.h>
    #endif
  #endif
  #ifdef ESP32
    #if USE_WM
      #include <BlynkSimpleEsp32_SSL_WM.h> 
    #else
      #include <BlynkSimpleEsp32_SSL.h>
    #endif
  #endif
  
#else // NOT using SSL
  #ifdef ESP8266
    #if USE_WM
      #include <BlynkSimpleEsp8266_WM.h>
    #else
      #include <BlynkSimpleEsp8266.h>
    #endif
  #endif
  #ifdef ESP32
    #if USE_WM
      #include <BlynkSimpleEsp32_WM.h>
    #else
      #include <BlynkSimpleEsp32.h>
    #endif
  #endif
#endif


#if USE_WM
  #define USE_DYNAMIC_PARAMETERS true

  //Defined in <BlynkSimpleEsp8266_WM.h> and <BlynkSimpleEsp8266_SSL_WM.h>
  /**************************************
    #define MAX_ID_LEN                5
    #define MAX_DISPLAY_NAME_LEN      16

    typedef struct
    {
    char id             [MAX_ID_LEN + 1];
    char displayName    [MAX_DISPLAY_NAME_LEN + 1];
    char *pdata;
    uint8_t maxlen;
    } MenuItem;
  ************************************* */

  #if USE_DYNAMIC_PARAMETERS
    // DEFINE THE DYNAMIC PARAMETERS FOR THE CONFIG PORTAL
    #define CONTROL_VPIN_LENGTH 5 
    char controlVpin [ CONTROL_VPIN_LENGTH + 1 ] = "";

    #define CONTROL_LABEL_LENGTH 18
    char controlLabel [ CONTROL_LABEL_LENGTH + 1 ] = "Clr Config Data";

    #define HEARTBEAT_VPIN_LENGTH 5
    char heartbeatVpin [ HEARTBEAT_VPIN_LENGTH + 1 ] = "";  

    #define HEARTBEAT_LABEL_LENGTH 26
    char heartbeatLabel [ HEARTBEAT_LABEL_LENGTH + 1 ] = "WiFi_Mgr_Demo_Heartbeat";  

    // HAVE NOT FIGURED OUT HOW TO CHANGE THESE
    //#define MAX_ID_LEN                6  // is 5 including terminating 0
    //#define MAX_DISPLAY_NAME_LEN      33 // is 16 including terminating 0
    MenuItem myMenuItems [] =
    { // 1234    123456789012345
      { "cvpn", "Ctrl VPin (#)",  controlVpin,    CONTROL_VPIN_LENGTH },
      { "clab", "Ctrl Label",     controlLabel,   CONTROL_LABEL_LENGTH },
      { "hvpn", "Hbeat VPin (#)", heartbeatVpin,  HEARTBEAT_VPIN_LENGTH },
      { "hlab", "Hbeat Label",    heartbeatLabel, HEARTBEAT_LABEL_LENGTH },
    };

    // Automatically calculates the # of menu items
    uint16_t NUM_MENU_ITEMS = sizeof(myMenuItems) / sizeof(MenuItem);  //MenuItemSize;
  #else // not using USE_DYNAMIC_PARAMETERS
    MenuItem myMenuItems [] = {};

    uint16_t NUM_MENU_ITEMS = 0;
  #endif // end USE_DYNAMIC_PARAMETERS    


// IS THIS NOW NECESSARY FOR ANYONE USING DYNAMIC_PARAMETERS?  

  /////////// Start Default Config Data /////////////
  bool LOAD_DEFAULT_CONFIG_DATA = true;
  //bool LOAD_DEFAULT_CONFIG_DATA = false;

  Blynk_WM_Configuration defaultConfig =
  {
    //char header[16], dummy, not used
    #if USE_SSL  
      "SSL",
    #else
      "NonSSL",
    #endif
    //WiFi_Credentials  WiFi_Creds  [NUM_WIFI_CREDENTIALS]
    //WiFi_Creds.wifi_ssid and WiFi_Creds.wifi_pw
    "SSID2", "password2",
    "Baloney", "Baloney",
    // Blynk_Credentials Blynk_Creds [NUM_BLYNK_CREDENTIALS];
    // Blynk_Creds.blynk_server and Blynk_Creds.blynk_token
    "account.duckdns.org",  "token1", 
    "blynk-cloud.com",     "<<my real Blynk auth>>",
    //int  blynk_port;
    #if USE_SSL
      9443,
    #else
      8080,
    #endif
    //char board_name     [24];
    "Air-Control",
    // terminate the list
    //int  checkSum, dummy, not used
    0
    /////////// End Default Config Data /////////////
  };
#endif // USE_WM


#if ! USE_WM
  char blynkAuth[] = "<my auth>"; // BLYNK Auth 

  char WiFiSSID[] = "<my ssid";  // network SSID (name)
  char WiFiPass[] = "<my passcode>";  // network password
#endif


BlynkTimer myTimer;
// Blynk timers to blink a heartbeat LED on and off
int heartbeatLEDinterval = 3000; // interval between heartbeats for onboard and Blynk Virtual LED in millisec 
int heartbeatLEDtimerID; 

int heartbeatLEDduration = 750; // duraction of each blink in millisec (set as an interval timer)
int heartbeatLEDdurationTimerID;
bool heartbeatLEDon = false; // this lets me use the same routine for the turn-on timer and the turn-off interval

#define BLYNK_HEARTBEAT_LED_VPIN V2
WidgetLED heartbeatLED( BLYNK_HEARTBEAT_LED_VPIN );  // want a blinking LED on the display to show we're live

#define BLYNK_RESET_CONFIG_INFO_VPIN V3  // Uses BLYNK_WRITE_DEFAULT 




/* setup
 *  Set up WiFi, Blynk & Blynk timers 
 *  Set up Blue LED on board
 */
void setup() 
{
  Serial.begin ( SERIAL_SPEED );
  delay ( 500 );  
  Serial.println ( "\n\n=======================================" );
  Serial.print ( PROGRAM_NAME ); 
  #if USE_SSL
    Serial.println ( " ** Using SSL ** \n" );  
  #endif
  Serial.println();
  
  connectToLANandBlynk();  

  // Initialize Onboard LED 
  pinMode ( LED_BUILTIN, OUTPUT );  
  digitalWrite ( LED_BUILTIN, LOW ); 
    
  // Set Blynk Virtual LED OFF
  heartbeatLED.off(); // Blynk Virtual LED
  heartbeatLEDblink(); // first heartbeat 
  
  Serial.println ( "\nSetup complete \n" );    
  
} //end setup





void loop()
{
  Blynk.run();
  myTimer.run();  
} 





// BLYNK_WRITE_DEFAULT GETS CALLED WHEN THERE IS NO SPECIFIC BLYNK_WRITE FOR THAT PIN
// This makes it a flexible receiver
BLYNK_WRITE_DEFAULT() 
{
  Serial.print ( "\nRECEIVED BLYNK SIGNAL FROM V");
    
  int writeVpin = request.pin; 
  Serial.print ( writeVpin );
  Serial.println ( ": " );
  // Print all parameter values
  for ( auto i = param.begin(); i < param.end(); ++i ) 
  {
    Serial.print ( "* " ); 
    Serial.println ( i.asString() );
  }
  Serial.println ( "***" );  
  
  if ( writeVpin == BLYNK_RESET_CONFIG_INFO_VPIN )
  {
    Serial.println ( "Yes, we hit the RESET button." );  
    #if USE_WM
      //****************************************
      Serial.println ( "HIT CONFIG DATA RESET BUTTON" );  
      Blynk.clearConfigData();
      //****************************************
    #endif
  }

  Serial.print ( "controlVpin=<" ); Serial.print ( controlVpin ); 
    Serial.print ( ">, label=<" ); Serial.print ( controlLabel ); 
  Serial.print ( ">, heartbeatVpin=<" ); Serial.print ( heartbeatVpin ); 
    Serial.print ( ">, label=<" ); Serial.print ( heartbeatLabel ); Serial.println ( ">" );  
}





void connectToLANandBlynk()
{
  // Setup WLAN and Blynk
  Serial.print ( "\nSetting up WLAN and Blynk " );  
  #if USE_WM
    Serial.println ( "WITH WiFiManager" ); 
  #else
    Serial.println ( "WITHOUT WiFiManager" );  
  #endif
  
  #if USE_WM
    Serial.println ( "Starting Blynk.begin (with WM)" );  

    Blynk.setConfigPortal ( "TestPortal", "123" );
    Serial.println ( "Blynk.setConfigPortal(TestPortal, 123);" );  

    Blynk.setConfigPortalIP ( IPAddress ( 192, 168, 220, 1 ) );  
    //Blynk.config ( blynkAuth );
    Blynk.begin ( "Blynk-Configurator" ); 
    
  #else//NOT using WM
    Serial.println ( "Starting WiFi.begin (no WM)" );  
    WiFi.begin ( WiFiSSID, WiFiPass );
    Serial.println ( "... waiting a few seconds for WiFi ..." );    
    delay ( 7000 );  // For esp8266, it needs a delay to realize it has connected
    
    // REBOOT if we do not have a good WiFi connection
    if ( WiFi.status() != WL_CONNECTED )
    {
      Serial.println ( "Resetting in a few seconds..." );
      delay ( 3000 );  
      ESP.restart();
    } 
    
    // Configure and launch Blynk
    Blynk.config ( blynkAuth );
    Blynk.connect ( 2500 ); // Don't get stuck hanging for more than 2500 millis.
  #endif // using WM
  
  if ( Blynk.connected() ) Serial.println ( "Blynk connected just fine\n" ); 
  else Serial.println ( "Blynk NOT CONNECTED \n\n" );  

  #if USE_WM
    #if USE_SPIFFS
      Serial.println("\nBlynk using SPIFFS connected. Board Name : " + Blynk.getBoardName());
    #else
      Serial.println("\nBlynk using EEPROM connected. Board Name : " + Blynk.getBoardName());
      Serial.printf("EEPROM size = %d bytes, EEPROM start address = %d / 0x%X\n", EEPROM_SIZE, EEPROM_START, EEPROM_START);
    #endif
  #endif


  Serial.println ( "Setting up Blynk timer" );  
  // Interval timer for heartbeatLED (Blynk LED and onboard LED
  heartbeatLEDtimerID = myTimer.setInterval ( heartbeatLEDinterval, heartbeatLEDblink );  

  Serial.println ( "..Blynk config and timers setup complete\n" );  
} //end connectToBlynk




void heartbeatLEDblink()
/* Blink the on-board LED AND the Virtual Blynk LED
 * First time called, it turne the LEDs on, then sets a timer to turn LED off
 * When the timer triggers, same routine turns the LEDs off
 */
{
  if ( heartbeatLEDon ) // if LED is on, turn it off and vice cersa
  {
    heartbeatLED.off(); // Blynk Virtual LED
    
    digitalWrite ( LED_BUILTIN, LOW ); // On-board LED
    
    Serial.println ( " ..." );
  } else
  {
    heartbeatLED.on();      // Blynk Virtual LED
    
    digitalWrite ( LED_BUILTIN, HIGH );  // On-board LED
    
    // Set the timer to turn off the LEDs in a bit  
    heartbeatLEDdurationTimerID = myTimer.setTimeout ( heartbeatLEDduration, heartbeatLEDblink ); 
    
    Serial.print ( "... heartbeat of " ); Serial.print ( PROGRAM_NAME ); 
    Serial.print ( " WiFi.status() = " ); Serial.print ( WiFi.status() );  
  }
  
  heartbeatLEDon = ! heartbeatLEDon; // flip status
} //end heartbeatLEDblink




// CALLED WHEN CONNECTING TO BLYNK SERVERS
// GETS CALLED IMMEDIATELY ON FIRST CONNECT
BLYNK_CONNECTED()
{
  Serial.println ( "\nBLYNK_CONNECTED..." );  

  Serial.print ( "controlVpin=<" ); Serial.print ( controlVpin ); 
    Serial.print ( ">, label=<" ); Serial.print ( controlLabel ); 
  Serial.print ( ">, heartbeatVpin=<" ); Serial.print ( heartbeatVpin ); 
    Serial.print ( ">, label=<" ); Serial.print ( heartbeatLabel ); Serial.println ( ">" );    
}
1 Like

Dear @thorathome

Thanks so much for finding the bug, which is an good example of my coffee-lacking, hasty, sleep-lacking status. :sleepy:

I put a comment / template to add code into, then forget to follow.

Temporarily, please test change the lib codes as follows, in two places, for each of all 4 WM files

From the buggy one

bool getConfigData()
{
  ....
      if (LOAD_DEFAULT_CONFIG_DATA)
      {
        // Load default Credentials and assume it's OK
        //  loadCredentials();    <==== missing this "Load default Credentials" action,  ;-[
        credDataValid = true;   <=== only do this "assume it's OK"  ;-[
      }
      else
      {           
        credDataValid = loadCredentials();  
      }  

to

bool getConfigData()
{

      .....
      if (LOAD_DEFAULT_CONFIG_DATA)
      {
        // Load default Credentials and assume it's OK
        loadCredentials();        // add this line <=====
        credDataValid = true;
      }
      else
      {           
        credDataValid = loadCredentials();  
      }  

That’s why your help is so important and appreciated to find and kill bugs.

PS: I’ll post the fix in Master late today. You can wait or just continue by modifying the code yourself

Already post pre-Release Version v1.0.13a. Pls use it.
You can have more debugging msgs by adding a line in your code as follows:

//BLYNK Stuff here
#define BLYNK_PRINT       Serial
#define BLYNK_WM_DEBUG    3         <====== this line will turn on lots of dbg msgs

Victory @khoih

Thanks for the super quick responses to my bug hunting. I downloaded your zip and installed 1.0.13a using Arduino IDE. All is right with the world. Updated DYNAMIC_PARAMETERS are now accessible.

To get this far, I used your handy Blynk.clearConfigData(); connected to a virtual ‘reset’ button. I hit the reset button which clears the config data, then manually reboot the ESP8266 to get the Config Portal.

I will start tomorrow looking at drd.

And I’ll use #define BLYNK_WM_DEBUG 3

Two “it would be nice” things (of course!)

  1. When I copy the four /src files over to the master Blynk /src folder, Arduino IDE gives me an error message that we have duplicate libraries. If I empty the Blynk_WiFiManager/src folder after copying to the Blynk /src folder, I also get an error message from Arduino IDE that the WiFiManager /src folder is empty. So I left one of the 4 files duplicated in that folder. It Would Be Nice if I didn’t have to screw around with this. No big deal, but it impacts usability.

  2. Even if LOAD_DEFAULT_CONFIG_DATA = false, I still have to specify the
    Blynk_WM_Configuration defaultConfig = { … } data structure. It Would Be Nice if the sketchwriter didn’t have to do all that when LOAD_DEFAULT_CONFIG_DATA = false.

Again, nice work. Back at it tomorrow, I expect.

  1. When I copy the four /src files over to the master Blynk /src folder, Arduino IDE gives me an error message that we have duplicate libraries. If I empty the Blynk_WiFiManager/src folder after copying to the Blynk /src folder, I also get an error message from Arduino IDE that the WiFiManager /src folder is empty. So I left one of the 4 files duplicated in that folder. It Would Be Nice if I didn’t have to screw around with this. No big deal, but it impacts usability.

That’s why you’d better follow the installation guide (still waiting for you to improve)

Installation

The suggested way to install is to:

  1. Navigate to Blynk_WM page.
  2. Download the latest release Blynk_WM-master.zip.
  3. Extract the zip file to Blynk_WM-master directory
  4. Copy whole Blynk_WM-master/src folder to Arduino libraries’ src directory such as ~/Arduino/libraries/Blynk/src so that you can use SSL without compile error

This way you don’t copy the whole directory into ./libraries directory, but just leave Blynk-WM-v1.xx.xx where you downloaded it.

You can also do this another way

Another way is to use Arduino Library Manager.

  1. Search for Blynk_WiFiManager, then select to install the latest version.
  2. You can also use this link arduino-library-badge for more detailed instructions.
  3. Then move the 2 files BlynkSimpleEsp8266_SSL_WM.h and BlynkSimpleEsp32_SSL_WM.h from directory ~/Arduino/libraries/Blynk_WiFiManager/src into Blynk libraries src directory (normally ~/Arduino/libraries/Blynk/src

But the best way can be (not in README yet)

Easier way is to use Arduino Library Manager.

  1. Search for Blynk_WiFiManager, then select to install the latest version.
  2. You can also use this link arduino-library-badge for more detailed instructions.
  3. Then copy the whole ~/Arduino/libraries/Blynk/src/certs directory into ~/Arduino/libraries/Blynk_WiFiManager/src/certs

Just remember to delete the old library directory, if it still exists.

  1. Even if LOAD_DEFAULT_CONFIG_DATA = false, I still have to specify the
    Blynk_WM_Configuration defaultConfig = { … } data structure. It Would Be Nice if the sketchwriter didn’t have to do all that when LOAD_DEFAULT_CONFIG_DATA = false.

You can just, in the sketch, replace the code as follow

// IS THIS NOW NECESSARY FOR ANYONE USING DYNAMIC_PARAMETERS?

/////////// Start Default Config Data /////////////
#define TO_LOAD_DEFAULT_CONFIG_DATA      true

#if TO_LOAD_DEFAULT_CONFIG_DATA

bool LOAD_DEFAULT_CONFIG_DATA = true;

Blynk_WM_Configuration defaultConfig =
{
  //char header[16], dummy, not used
#if USE_SSL
  "SSL",
#else
  "NonSSL",
#endif
  //WiFi_Credentials  WiFi_Creds  [NUM_WIFI_CREDENTIALS]
  //WiFi_Creds.wifi_ssid and WiFi_Creds.wifi_pw
  "SSID2", "password2",
  "Baloney", "Baloney",
  // Blynk_Credentials Blynk_Creds [NUM_BLYNK_CREDENTIALS];
  // Blynk_Creds.blynk_server and Blynk_Creds.blynk_token
  "account.duckdns.org",  "token1",
  "blynk-cloud.com",     "<<my real Blynk auth>>",
  //int  blynk_port;
#if USE_SSL
  9443,
#else
  8080,
#endif
  //char board_name     [24];
  "Air-Control",
  // terminate the list
  //int  checkSum, dummy, not used
  0
  /////////// End Default Config Data /////////////
};

#else

bool LOAD_DEFAULT_CONFIG_DATA = false;

Blynk_WM_Configuration defaultConfig;

#endif    // TO_LOAD_DEFAULT_CONFIG_DATA

or just leave it as dummy one if you don’t need the feature

bool LOAD_DEFAULT_CONFIG_DATA = false;

Blynk_WM_Configuration defaultConfig;

To get this far, I used your handy Blynk.clearConfigData() ; connected to a virtual ‘reset’ button. I hit the reset button which clears the config data, then manually reboot the ESP8266 to get the Config Portal.

Try DRD (pressing RESET, wait for booting, then 1 more RESET within 10s), the Config Portal will run right away.

1 Like

Hi @khoih

All good here. I am using v1.0.13a. DYMANIC_PARAMETERS work as advertised now, thanks.

I have tested DRD and it also certainly works. Very handy feature.

Regarding Blynk_WMManager v1.0.13a, I found Arduino IDE’s Library manager does not know about v1.0.13a. I downloaded the zip file from Github and use Arduino IDE to load it from the zip. I then CUT & PASTEd the entire /src folder from Blynk_WiFiManager over to the Blynk main library as you recommend.

I do get this repeated error message from Arduino IDE. Not sure why. (The <…> notation below is mine.) It is loading 1.0.13a, though, in spite of the error message - everything works.

Invalid version '1.0.13a' for library in: <…>\Arduino\My New Sketchbook\libraries\Blynk_WM-master

Invalid library found in <…>\Arduino\My New Sketchbook\libraries\Blynk_WM-master: no headers files (.h) found in <…>\Arduino\My New Sketchbook\libraries\Blynk_WM-master

I’ll work on the Installation description and other areas that I see. Plus, I want to contribute an example or two, am restructuring my example code now that (I think) I understand how WMManager works.

Powerful tools, these. Thanks for all the work and coffee.

It’s good you’re moving fast and efficiently.

Regarding Blynk_WMManager v1.0.13a, I found Arduino IDE’s Library manager does not know about v1.0.13a

Because this is just a pre-release, not official, just for internal testing. You have to install it manually as you have done.

Invalid library found in <…>\Arduino\My New Sketchbook\libraries\Blynk_WM-master: no headers files (.h) found in <…>\Arduino\My New Sketchbook\libraries\Blynk_WM-master

After cutting / pasting away all the files, you have to delete the library folder or move it elsewhere outside of \Arduino\My New Sketchbook\libraries\ directory, or Arduino will complain as no-source-code "invalid library"

The best way to start is just download Blynk_WM-master or Blynk_WM-1.0.13a to a directory *outside of of \Arduino\My New Sketchbook\libraries* directory. Then cut / copy and paste the same way.

I’ll work on the Installation description and other areas that I see. Plus, I want to contribute an example or two, am restructuring my example code now that (I think) I understand how WMManager works.

Great and I’d appreciate your help and contribution. More examples are always good. Bug findings and killings are absolutely necessary.

Powerful tools, these. Thanks for all the work and coffee.

Thanks and encouraged that you’d like it. Many more improvised Blynk-WM-related libraries are still waiting for your golden touch, certainly if you’re interested.

The current list in Platform.io:

Dear @thorathome

Release v1.0.14 has been published on GitHub.
Besides the bug fix you knew for dynamicParams, the new features in v1.0.14 are:

  1. If dynamicParams data stored in SPIFFS/ EEPROM is invalid, the default dynamicParams from sketch will take over and be loaded into the Config Portal.
  2. If the stored data is invalid, then default data from sketch will be loaded into Config Portal.

Please have a look at this release and help find / kill bugs.

After upgrade Blynk not work.

Is your DDNS account still pointing to your current public IP address?

Pete.