From 75f7437273a9adfdeeb8907550e675cd523831fe Mon Sep 17 00:00:00 2001 From: David Hawley Date: Wed, 26 Feb 2025 01:05:50 +0900 Subject: [PATCH 1/7] Add callback to allow Static IP per SSID Callback before WiFi.begin allows user to configure selected SSID --- libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp | 4 +++- libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp index bcd433e1b1..10a497ae22 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp @@ -329,9 +329,10 @@ wl_status_t ESP8266WiFiMulti::connectWiFiMulti(uint32_t connectTimeoutMs) if (ssid == entry.ssid) { DEBUG_WIFI_MULTI("[WIFIM] Connecting %s\n", ssid.c_str()); + if(SSID_selected_callback) SSID_selected_callback(ssid.c_str()); // Connect to WiFi WiFi.begin(ssid, entry.passphrase, channel, bssid); - + // Wait for status change if (waitWiFiConnect(connectTimeoutMs) == WL_CONNECTED) { return WL_CONNECTED; @@ -350,6 +351,7 @@ wl_status_t ESP8266WiFiMulti::connectWiFiMulti(uint32_t connectTimeoutMs) if (!connectSkipIndex[i]) { DEBUG_WIFI_MULTI("[WIFIM] Try hidden connect %s\n", entry.ssid); + if(SSID_selected_callback) SSID_selected_callback(entry.ssid); // Connect to WiFi WiFi.begin(entry.ssid, entry.passphrase); diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h index 3c77df02d4..9aec43fb91 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h @@ -56,6 +56,7 @@ struct WifiAPEntry { }; typedef std::vector WifiAPlist; +typedef void (*SSID_selected_callback_t)(const char * ssid); class ESP8266WiFiMulti { @@ -65,6 +66,7 @@ class ESP8266WiFiMulti bool addAP(const char *ssid, const char *passphrase = NULL); bool existsAP(const char *ssid, const char *passphrase = NULL); + void on_SSID_Selected(SSID_selected_callback_t cb) { SSID_selected_callback = cb;}; wl_status_t run(uint32_t connectTimeoutMs=WIFI_CONNECT_TIMEOUT_MS); @@ -73,6 +75,7 @@ class ESP8266WiFiMulti private: WifiAPlist _APlist; bool _firstRun; + SSID_selected_callback_t SSID_selected_callback = NULL; bool APlistAdd(const char *ssid, const char *passphrase = NULL); bool APlistExists(const char *ssid, const char *passphrase = NULL); From 3be48750bfc877a719e12178c1c84c6d1fb6bbbf Mon Sep 17 00:00:00 2001 From: David Hawley Date: Tue, 4 Mar 2025 00:31:25 +0900 Subject: [PATCH 2/7] Renamed callback, and added to WiFiMulti example --- .../examples/WiFiMulti/WiFiMulti.ino | 18 ++++++++++++++++++ libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp | 4 ++-- libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h | 4 ++-- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/libraries/ESP8266WiFi/examples/WiFiMulti/WiFiMulti.ino b/libraries/ESP8266WiFi/examples/WiFiMulti/WiFiMulti.ino index fe93d98a43..714a5f5638 100644 --- a/libraries/ESP8266WiFi/examples/WiFiMulti/WiFiMulti.ino +++ b/libraries/ESP8266WiFi/examples/WiFiMulti/WiFiMulti.ino @@ -8,6 +8,7 @@ - Connect to WiFi with strongest signal (RSSI) - Fall back to connect to next WiFi when a connection failed or lost - Fall back to connect to hidden SSID's which are not reported by WiFi scan + - Static IP assigned depending on which SSID is connected To enable debugging output, select in the Arduino iDE: - Tools | Debug Port: Serial @@ -21,6 +22,8 @@ ESP8266WiFiMulti wifiMulti; // WiFi connect timeout per AP. Increase when connecting takes longer. const uint32_t connectTimeoutMs = 5000; +SSID_selected_callback_t connectedToSSID(char *ssid); + void setup() { // Don't save WiFi configuration in flash - optional WiFi.persistent(false); @@ -35,9 +38,24 @@ void setup() { wifiMulti.addAP("ssid_from_AP_1", "your_password_for_AP_1"); wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2"); wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3"); + + wifiMulti.onSsidSelected(connectedToSSID); + // More is possible } +SSID_selected_callback_t connectedToSSID(char *ssid) +{ + // On connecting the second WiFi, assign static IP using config(...). + // For other SSID (if config has not already been called) DHCP will be used. + if(strcmp(ssid, "ssid_from_AP_2") == 0) { + IPAddress ip2(192,168,1,123); + IPAddress gw2(192,168,1,1); + IPAddress subnet2(255,255,255,0); + WiFi.config(ip2, gw2, subnet2); + } +} + void loop() { // Maintain WiFi connection if (wifiMulti.run(connectTimeoutMs) == WL_CONNECTED) { diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp index 10a497ae22..7d2ca8f9e8 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp @@ -329,7 +329,7 @@ wl_status_t ESP8266WiFiMulti::connectWiFiMulti(uint32_t connectTimeoutMs) if (ssid == entry.ssid) { DEBUG_WIFI_MULTI("[WIFIM] Connecting %s\n", ssid.c_str()); - if(SSID_selected_callback) SSID_selected_callback(ssid.c_str()); + if(_onSsidSelected) _onSsidSelected(ssid.c_str()); // Connect to WiFi WiFi.begin(ssid, entry.passphrase, channel, bssid); @@ -351,7 +351,7 @@ wl_status_t ESP8266WiFiMulti::connectWiFiMulti(uint32_t connectTimeoutMs) if (!connectSkipIndex[i]) { DEBUG_WIFI_MULTI("[WIFIM] Try hidden connect %s\n", entry.ssid); - if(SSID_selected_callback) SSID_selected_callback(entry.ssid); + if(_onSsidSelected) _onSsidSelected(entry.ssid); // Connect to WiFi WiFi.begin(entry.ssid, entry.passphrase); diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h index 9aec43fb91..c352739c0f 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h @@ -66,7 +66,7 @@ class ESP8266WiFiMulti bool addAP(const char *ssid, const char *passphrase = NULL); bool existsAP(const char *ssid, const char *passphrase = NULL); - void on_SSID_Selected(SSID_selected_callback_t cb) { SSID_selected_callback = cb;}; + void onSsidSelected(SSID_selected_callback_t cb) { _onSsidSelected = cb;}; wl_status_t run(uint32_t connectTimeoutMs=WIFI_CONNECT_TIMEOUT_MS); @@ -75,7 +75,7 @@ class ESP8266WiFiMulti private: WifiAPlist _APlist; bool _firstRun; - SSID_selected_callback_t SSID_selected_callback = NULL; + SSID_selected_callback_t _onSsidSelected = NULL; bool APlistAdd(const char *ssid, const char *passphrase = NULL); bool APlistExists(const char *ssid, const char *passphrase = NULL); From eebaaf864534bb15618dea06155d53c086a4fd80 Mon Sep 17 00:00:00 2001 From: Maxim Prokhorov Date: Mon, 10 Mar 2025 22:53:12 +0300 Subject: [PATCH 3/7] re-reviewed - callback has no return type - private types for the wifimulti class - explici WiFi.config(0U, 0U, 0U); for other APs - formatting, whitespace, uppercase SSID --- .../examples/WiFiMulti/WiFiMulti.ino | 24 +++++++++---------- .../ESP8266WiFi/src/ESP8266WiFiMulti.cpp | 14 ++++++++--- libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h | 21 ++++++++-------- 3 files changed, 33 insertions(+), 26 deletions(-) diff --git a/libraries/ESP8266WiFi/examples/WiFiMulti/WiFiMulti.ino b/libraries/ESP8266WiFi/examples/WiFiMulti/WiFiMulti.ino index 714a5f5638..15ec9fba7c 100644 --- a/libraries/ESP8266WiFi/examples/WiFiMulti/WiFiMulti.ino +++ b/libraries/ESP8266WiFi/examples/WiFiMulti/WiFiMulti.ino @@ -8,7 +8,7 @@ - Connect to WiFi with strongest signal (RSSI) - Fall back to connect to next WiFi when a connection failed or lost - Fall back to connect to hidden SSID's which are not reported by WiFi scan - - Static IP assigned depending on which SSID is connected + - Static IP assigned depending on which SSID is connected To enable debugging output, select in the Arduino iDE: - Tools | Debug Port: Serial @@ -22,8 +22,6 @@ ESP8266WiFiMulti wifiMulti; // WiFi connect timeout per AP. Increase when connecting takes longer. const uint32_t connectTimeoutMs = 5000; -SSID_selected_callback_t connectedToSSID(char *ssid); - void setup() { // Don't save WiFi configuration in flash - optional WiFi.persistent(false); @@ -39,21 +37,23 @@ void setup() { wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2"); wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3"); - wifiMulti.onSsidSelected(connectedToSSID); + wifiMulti.onSSIDSelected(connectedToSSID); // More is possible } -SSID_selected_callback_t connectedToSSID(char *ssid) -{ - // On connecting the second WiFi, assign static IP using config(...). - // For other SSID (if config has not already been called) DHCP will be used. - if(strcmp(ssid, "ssid_from_AP_2") == 0) { - IPAddress ip2(192,168,1,123); - IPAddress gw2(192,168,1,1); - IPAddress subnet2(255,255,255,0); +void connectedToSSID(const char *ssid) { + // On connecting to the second AP, assign static IP using config(...). + if (strcmp(ssid, "ssid_from_AP_2") == 0) { + IPAddress ip2(192, 168, 1, 123); + IPAddress gw2(192, 168, 1, 1); + IPAddress subnet2(255, 255, 255, 0); WiFi.config(ip2, gw2, subnet2); + return; } + + // For other SSID DHCP will be used. + Wifi.config(0U, 0U, 0U); } void loop() { diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp index 7d2ca8f9e8..a052d85c7f 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp @@ -329,10 +329,14 @@ wl_status_t ESP8266WiFiMulti::connectWiFiMulti(uint32_t connectTimeoutMs) if (ssid == entry.ssid) { DEBUG_WIFI_MULTI("[WIFIM] Connecting %s\n", ssid.c_str()); - if(_onSsidSelected) _onSsidSelected(ssid.c_str()); + // User-defined callback + if (_onSSIDSelected) { + _onSSIDSelected(entry.ssid); + } + // Connect to WiFi WiFi.begin(ssid, entry.passphrase, channel, bssid); - + // Wait for status change if (waitWiFiConnect(connectTimeoutMs) == WL_CONNECTED) { return WL_CONNECTED; @@ -351,7 +355,11 @@ wl_status_t ESP8266WiFiMulti::connectWiFiMulti(uint32_t connectTimeoutMs) if (!connectSkipIndex[i]) { DEBUG_WIFI_MULTI("[WIFIM] Try hidden connect %s\n", entry.ssid); - if(_onSsidSelected) _onSsidSelected(entry.ssid); + // User-defined callback + if (_onSSIDSelected) { + _onSSIDSelected(entry.ssid); + } + // Connect to WiFi WiFi.begin(entry.ssid, entry.passphrase); diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h index c352739c0f..9d57345d27 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h @@ -50,32 +50,31 @@ #define WIFI_SCAN_TIMEOUT_MS 5000 #endif -struct WifiAPEntry { - char *ssid; - char *passphrase; -}; - -typedef std::vector WifiAPlist; -typedef void (*SSID_selected_callback_t)(const char * ssid); - class ESP8266WiFiMulti { public: + using SSIDSelectedCallback = void (*)(const char *ssid); + ESP8266WiFiMulti(); ~ESP8266WiFiMulti(); bool addAP(const char *ssid, const char *passphrase = NULL); bool existsAP(const char *ssid, const char *passphrase = NULL); - void onSsidSelected(SSID_selected_callback_t cb) { _onSsidSelected = cb;}; + void onSSIDSelected(SSIDSelectedCallback callback) { _onSSIDSelected = callback; } wl_status_t run(uint32_t connectTimeoutMs=WIFI_CONNECT_TIMEOUT_MS); void cleanAPlist(); int count() { return _APlist.size(); } private: - WifiAPlist _APlist; + struct WifiAPEntry { + char *ssid; + char *passphrase; + }; + + std::vector _APlist; bool _firstRun; - SSID_selected_callback_t _onSsidSelected = NULL; + SSIDSelectedCallback _onSSIDSelected = NULL; bool APlistAdd(const char *ssid, const char *passphrase = NULL); bool APlistExists(const char *ssid, const char *passphrase = NULL); From 7336fe8c323b21f55faa677d6dd9a1d933f02cd8 Mon Sep 17 00:00:00 2001 From: Maxim Prokhorov Date: Mon, 10 Mar 2025 23:04:48 +0300 Subject: [PATCH 4/7] typo --- libraries/ESP8266WiFi/examples/WiFiMulti/WiFiMulti.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/ESP8266WiFi/examples/WiFiMulti/WiFiMulti.ino b/libraries/ESP8266WiFi/examples/WiFiMulti/WiFiMulti.ino index 15ec9fba7c..34f1a85ed6 100644 --- a/libraries/ESP8266WiFi/examples/WiFiMulti/WiFiMulti.ino +++ b/libraries/ESP8266WiFi/examples/WiFiMulti/WiFiMulti.ino @@ -53,7 +53,7 @@ void connectedToSSID(const char *ssid) { } // For other SSID DHCP will be used. - Wifi.config(0U, 0U, 0U); + WiFi.config(0U, 0U, 0U); } void loop() { From 9c347d245d73c68a0d00062f3df5c3c9068397bc Mon Sep 17 00:00:00 2001 From: Maxim Prokhorov Date: Tue, 10 Feb 2026 12:52:46 +0300 Subject: [PATCH 5/7] doc --- doc/esp8266wifi/station-examples.rst | 31 ++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/doc/esp8266wifi/station-examples.rst b/doc/esp8266wifi/station-examples.rst index 6af6f1f80e..330ef2b0b6 100644 --- a/doc/esp8266wifi/station-examples.rst +++ b/doc/esp8266wifi/station-examples.rst @@ -14,6 +14,7 @@ Table of Contents - `Prepare Access Points <#prepare-access-points>`__ - `Try it Out <#try-it-out>`__ - `Can we Make it Simpler? <#can-we-make-it-simpler>`__ +- `Per-SSID configuration`__ - `Conclusion <#conclusion>`__ Introduction @@ -195,6 +196,36 @@ After uploading the sketch and opening the serial monitor, the messages will loo dhcp client start... ip:192.168.1.10,mask:255.255.255.0,gw:192.168.1.9 + +Per-SSID configuration +~~~~~~~~~~~~~~~~~~~~~~~ + +Whenever network SSID is selected by the 'ESP8266WiFiMulti', it can be instructed to call a user function before connection is attempted. + +For example, to allow static IP configuration, declare the following function + +.. code:: cpp + + void onSSIDSelected(const char *ssid) { + if (strcmp(ssid, "sensor-net-2") == 0) { + IPAddress ip(10, 0, 0, 2); + IPAddress gw(10, 0, 0, 1); + IPAddress subnet(255, 255, 255, 0); + WiFi.config(ip, gw, subnet); + return; + } + + // revert to DHCP configuration + WiFi.config(0U, 0U, 0U); + } + +Then, register it after ``addAP(...)`` lines + +.. code:: cpp + + wifiMulti.onSSIDSelected(onSSIDSelected); + + Conclusion ~~~~~~~~~~ From 7c135e918ba2d2da65c0fdfd1e8b5f8b47be60c5 Mon Sep 17 00:00:00 2001 From: Maxim Prokhorov Date: Tue, 10 Feb 2026 12:57:48 +0300 Subject: [PATCH 6/7] callback happens before WiFi.begin() --- .../ESP8266WiFi/examples/WiFiMulti/WiFiMulti.ino | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/libraries/ESP8266WiFi/examples/WiFiMulti/WiFiMulti.ino b/libraries/ESP8266WiFi/examples/WiFiMulti/WiFiMulti.ino index 34f1a85ed6..54bef3f8ea 100644 --- a/libraries/ESP8266WiFi/examples/WiFiMulti/WiFiMulti.ino +++ b/libraries/ESP8266WiFi/examples/WiFiMulti/WiFiMulti.ino @@ -8,7 +8,7 @@ - Connect to WiFi with strongest signal (RSSI) - Fall back to connect to next WiFi when a connection failed or lost - Fall back to connect to hidden SSID's which are not reported by WiFi scan - - Static IP assigned depending on which SSID is connected + - Connect to WiFi using a static IP configuration To enable debugging output, select in the Arduino iDE: - Tools | Debug Port: Serial @@ -37,13 +37,14 @@ void setup() { wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2"); wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3"); - wifiMulti.onSSIDSelected(connectedToSSID); + // Register custom SSID callback + wifiMulti.onSSIDSelected(onSSIDSelected); - // More is possible + // Insert more sketch code } -void connectedToSSID(const char *ssid) { - // On connecting to the second AP, assign static IP using config(...). +void onSSIDSelected(const char *ssid) { + // Before connecting to the second AP, assign static IP using config(...). if (strcmp(ssid, "ssid_from_AP_2") == 0) { IPAddress ip2(192, 168, 1, 123); IPAddress gw2(192, 168, 1, 1); @@ -52,7 +53,7 @@ void connectedToSSID(const char *ssid) { return; } - // For other SSID DHCP will be used. + // Make sure that DHCP is used for other networks. WiFi.config(0U, 0U, 0U); } From ebf438b2eef95afe8f010dc632ba957ee87b3cd8 Mon Sep 17 00:00:00 2001 From: Maxim Prokhorov Date: Tue, 10 Feb 2026 13:14:40 +0300 Subject: [PATCH 7/7] sphinx link fix --- doc/esp8266wifi/station-examples.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/esp8266wifi/station-examples.rst b/doc/esp8266wifi/station-examples.rst index 330ef2b0b6..5a4dd38dab 100644 --- a/doc/esp8266wifi/station-examples.rst +++ b/doc/esp8266wifi/station-examples.rst @@ -14,7 +14,7 @@ Table of Contents - `Prepare Access Points <#prepare-access-points>`__ - `Try it Out <#try-it-out>`__ - `Can we Make it Simpler? <#can-we-make-it-simpler>`__ -- `Per-SSID configuration`__ +- `Per-SSID configuration <#per-ssid-configuration>`__ - `Conclusion <#conclusion>`__ Introduction @@ -198,7 +198,7 @@ After uploading the sketch and opening the serial monitor, the messages will loo Per-SSID configuration -~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~ Whenever network SSID is selected by the 'ESP8266WiFiMulti', it can be instructed to call a user function before connection is attempted.