feat: added wifi scanning
This commit is contained in:
parent
72706c37a4
commit
25cf7c8284
|
@ -1,190 +0,0 @@
|
|||
#include <Arduino.h> //not needed in the arduino ide
|
||||
|
||||
// Captive Portal
|
||||
#include <AsyncTCP.h> //https://github.com/me-no-dev/AsyncTCP using the latest dev version from @me-no-dev
|
||||
#include <DNSServer.h>
|
||||
#include <ESPAsyncWebServer.h> //https://github.com/me-no-dev/ESPAsyncWebServer using the latest dev version from @me-no-dev
|
||||
#include <esp_wifi.h> //Used for mpdu_rx_disable android workaround
|
||||
|
||||
// Pre reading on the fundamentals of captive portals https://textslashplain.com/2022/06/24/captive-portals/
|
||||
|
||||
const char *ssid = "captive"; // FYI The SSID can't have a space in it.
|
||||
// const char * password = "12345678"; //Atleast 8 chars
|
||||
const char *password = NULL; // no password
|
||||
|
||||
#define MAX_CLIENTS 4 // ESP32 supports up to 10 but I have not tested it yet
|
||||
#define WIFI_CHANNEL 6 // 2.4ghz channel 6 https://en.wikipedia.org/wiki/List_of_WLAN_channels#2.4_GHz_(802.11b/g/n/ax)
|
||||
|
||||
const IPAddress localIP(4, 3, 2, 1); // the IP address the web server, Samsung requires the IP to be in public space
|
||||
const IPAddress gatewayIP(4, 3, 2, 1); // IP address of the network should be the same as the local IP for captive portals
|
||||
const IPAddress subnetMask(255, 255, 255, 0); // no need to change: https://avinetworks.com/glossary/subnet-mask/
|
||||
|
||||
const String localIPURL = "http://4.3.2.1"; // a string version of the local IP with http, used for redirecting clients to your webpage
|
||||
|
||||
const char index_html[] PROGMEM = R"=====(
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>ESP32 WiFi Setup</title>
|
||||
<style>
|
||||
body {background-color:#06cc13;}
|
||||
h1 {color: white;}
|
||||
h2 {color: white;}
|
||||
</style>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
</head>
|
||||
<body>
|
||||
<h1>WiFi Setup</h1>
|
||||
<form action="/setup" method="post">
|
||||
<label for="ssid">SSID:</label><br>
|
||||
<input type="text" id="ssid" name="ssid"><br>
|
||||
<label for="password">Password:</label><br>
|
||||
<input type="password" id="password" name="password"><br><br>
|
||||
<input type="submit" value="Connect">
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
)=====";
|
||||
|
||||
DNSServer dnsServer;
|
||||
AsyncWebServer server(80);
|
||||
|
||||
void setUpDNSServer(DNSServer &dnsServer, const IPAddress &localIP) {
|
||||
// Define the DNS interval in milliseconds between processing DNS requests
|
||||
#define DNS_INTERVAL 30
|
||||
|
||||
// Set the TTL for DNS response and start the DNS server
|
||||
dnsServer.setTTL(3600);
|
||||
dnsServer.start(53, "*", localIP);
|
||||
}
|
||||
|
||||
void startSoftAccessPoint(const char *ssid, const char *password, const IPAddress &localIP, const IPAddress &gatewayIP) {
|
||||
// Define the maximum number of clients that can connect to the server
|
||||
#define MAX_CLIENTS 4
|
||||
// Define the WiFi channel to be used (channel 6 in this case)
|
||||
#define WIFI_CHANNEL 6
|
||||
|
||||
// Set the WiFi mode to access point and station
|
||||
WiFi.mode(WIFI_MODE_AP);
|
||||
|
||||
// Define the subnet mask for the WiFi network
|
||||
const IPAddress subnetMask(255, 255, 255, 0);
|
||||
|
||||
// Configure the soft access point with a specific IP and subnet mask
|
||||
WiFi.softAPConfig(localIP, gatewayIP, subnetMask);
|
||||
|
||||
// Start the soft access point with the given ssid, password, channel, max number of clients
|
||||
WiFi.softAP(ssid, password, WIFI_CHANNEL, 0, MAX_CLIENTS);
|
||||
|
||||
// Disable AMPDU RX on the ESP32 WiFi to fix a bug on Android
|
||||
esp_wifi_stop();
|
||||
esp_wifi_deinit();
|
||||
wifi_init_config_t my_config = WIFI_INIT_CONFIG_DEFAULT();
|
||||
my_config.ampdu_rx_enable = false;
|
||||
esp_wifi_init(&my_config);
|
||||
esp_wifi_start();
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS); // Add a small delay
|
||||
}
|
||||
|
||||
void setUpWebserver(AsyncWebServer &server, const IPAddress &localIP) {
|
||||
//======================== Webserver ========================
|
||||
// WARNING IOS (and maybe macos) WILL NOT POP UP IF IT CONTAINS THE WORD "Success" https://www.esp8266.com/viewtopic.php?f=34&t=4398
|
||||
// SAFARI (IOS) IS STUPID, G-ZIPPED FILES CAN'T END IN .GZ https://github.com/homieiot/homie-esp8266/issues/476 this is fixed by the webserver serve static function.
|
||||
// SAFARI (IOS) there is a 128KB limit to the size of the HTML. The HTML can reference external resources/images that bring the total over 128KB
|
||||
// SAFARI (IOS) popup browser has some severe limitations (javascript disabled, cookies disabled)
|
||||
|
||||
// Required
|
||||
server.on("/connecttest.txt", [](AsyncWebServerRequest *request) { request->redirect("http://logout.net"); }); // windows 11 captive portal workaround
|
||||
server.on("/wpad.dat", [](AsyncWebServerRequest *request) { request->send(404); }); // Honestly don't understand what this is but a 404 stops win 10 keep calling this repeatedly and panicking the esp32 :)
|
||||
|
||||
// Background responses: Probably not all are Required, but some are. Others might speed things up?
|
||||
// A Tier (commonly used by modern systems)
|
||||
server.on("/generate_204", [](AsyncWebServerRequest *request) { request->redirect(localIPURL); }); // android captive portal redirect
|
||||
server.on("/redirect", [](AsyncWebServerRequest *request) { request->redirect(localIPURL); }); // microsoft redirect
|
||||
server.on("/hotspot-detect.html", [](AsyncWebServerRequest *request) { request->redirect(localIPURL); }); // apple call home
|
||||
server.on("/canonical.html", [](AsyncWebServerRequest *request) { request->redirect(localIPURL); }); // firefox captive portal call home
|
||||
server.on("/success.txt", [](AsyncWebServerRequest *request) { request->send(200); }); // firefox captive portal call home
|
||||
server.on("/ncsi.txt", [](AsyncWebServerRequest *request) { request->redirect(localIPURL); }); // windows call home
|
||||
|
||||
// B Tier (uncommon)
|
||||
// server.on("/chrome-variations/seed",[](AsyncWebServerRequest *request){request->send(200);}); //chrome captive portal call home
|
||||
// server.on("/service/update2/json",[](AsyncWebServerRequest *request){request->send(200);}); //firefox?
|
||||
// server.on("/chat",[](AsyncWebServerRequest *request){request->send(404);}); //No stop asking Whatsapp, there is no internet connection
|
||||
// server.on("/startpage",[](AsyncWebServerRequest *request){request->redirect(localIPURL);});
|
||||
|
||||
// return 404 to webpage icon
|
||||
server.on("/favicon.ico", [](AsyncWebServerRequest *request) { request->send(404); }); // webpage icon
|
||||
|
||||
// Serve Basic HTML Page
|
||||
server.on("/", HTTP_ANY, [](AsyncWebServerRequest *request) {
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/html", index_html);
|
||||
response->addHeader("Cache-Control", "public,max-age=31536000"); // save this file to cache for 1 year (unless you refresh)
|
||||
request->send(response);
|
||||
Serial.println("Served Basic HTML Page");
|
||||
});
|
||||
|
||||
server.on("/setup", HTTP_POST, [](AsyncWebServerRequest *request) {
|
||||
String ssid;
|
||||
String password;
|
||||
if (request->hasParam("ssid", true) && request->hasParam("password", true)) {
|
||||
ssid = request->getParam("ssid", true)->value();
|
||||
password = request->getParam("password", true)->value();
|
||||
// Now connect to the WiFi network using the provided credentials
|
||||
WiFi.begin(ssid.c_str(), password.c_str());
|
||||
// You may want to add some logic to check if the connection was successful
|
||||
// and respond accordingly
|
||||
request->send(200, "text/plain", "Connecting to " + ssid);
|
||||
} else {
|
||||
request->send(400, "text/plain", "Invalid request");
|
||||
}
|
||||
});
|
||||
|
||||
// the catch all
|
||||
server.onNotFound([](AsyncWebServerRequest *request) {
|
||||
request->redirect(localIPURL);
|
||||
Serial.print("onnotfound ");
|
||||
Serial.print(request->host()); // This gives some insight into whatever was being requested on the serial monitor
|
||||
Serial.print(" ");
|
||||
Serial.print(request->url());
|
||||
Serial.print(" sent redirect to " + localIPURL + "\n");
|
||||
});
|
||||
}
|
||||
|
||||
void setup() {
|
||||
// Set the transmit buffer size for the Serial object and start it with a baud rate of 115200.
|
||||
Serial.setTxBufferSize(1024);
|
||||
Serial.begin(115200);
|
||||
|
||||
// Wait for the Serial object to become available.
|
||||
while (!Serial)
|
||||
;
|
||||
|
||||
// Print a welcome message to the Serial port.
|
||||
Serial.println("\n\nCaptive Test, V0.5.0 compiled " __DATE__ " " __TIME__ " by CD_FER"); //__DATE__ is provided by the platformio ide
|
||||
Serial.printf("%s-%d\n\r", ESP.getChipModel(), ESP.getChipRevision());
|
||||
|
||||
startSoftAccessPoint(ssid, password, localIP, gatewayIP);
|
||||
|
||||
setUpDNSServer(dnsServer, localIP);
|
||||
|
||||
setUpWebserver(server, localIP);
|
||||
server.begin();
|
||||
|
||||
Serial.print("\n");
|
||||
Serial.print("Startup Time:"); // should be somewhere between 270-350 for Generic ESP32 (D0WDQ6 chip, can have a higher startup time on first boot)
|
||||
Serial.println(millis());
|
||||
Serial.print("\n");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
dnsServer.processNextRequest(); // I call this atleast every 10ms in my other projects (can be higher but I haven't tested it for stability)
|
||||
delay(DNS_INTERVAL); // seems to help with stability, if you are doing other things in the loop this may not be needed
|
||||
|
||||
// Check WiFi connection status
|
||||
if (WiFi.status() == WL_CONNECTED) {
|
||||
// If connected, you might want to do something, like printing the IP address
|
||||
Serial.println("Connected to WiFi!");
|
||||
Serial.println("IP Address: " + WiFi.localIP().toString());
|
||||
Serial.println("SSID " + WiFi.SSID());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,260 @@
|
|||
#include <Arduino.h> //not needed in the arduino ide
|
||||
|
||||
// Captive Portal
|
||||
#include <AsyncTCP.h> //https://github.com/me-no-dev/AsyncTCP using the latest dev version from @me-no-dev
|
||||
#include <DNSServer.h>
|
||||
#include <ESPAsyncWebServer.h> //https://github.com/me-no-dev/ESPAsyncWebServer using the latest dev version from @me-no-dev
|
||||
#include <esp_wifi.h> //Used for mpdu_rx_disable android workaround
|
||||
|
||||
// Pre reading on the fundamentals of captive portals https://textslashplain.com/2022/06/24/captive-portals/
|
||||
|
||||
const char *ssid = "captive"; // FYI The SSID can't have a space in it.
|
||||
// const char * password = "12345678"; //Atleast 8 chars
|
||||
const char *password = NULL; // no password
|
||||
|
||||
#define MAX_CLIENTS 4 // ESP32 supports up to 10 but I have not tested it yet
|
||||
#define WIFI_CHANNEL 6 // 2.4ghz channel 6 https://en.wikipedia.org/wiki/List_of_WLAN_channels#2.4_GHz_(802.11b/g/n/ax)
|
||||
|
||||
const IPAddress localIP(4, 3, 2, 1); // the IP address the web server, Samsung requires the IP to be in public space
|
||||
const IPAddress gatewayIP(4, 3, 2, 1); // IP address of the network should be the same as the local IP for captive portals
|
||||
const IPAddress subnetMask(255, 255, 255, 0); // no need to change: https://avinetworks.com/glossary/subnet-mask/
|
||||
|
||||
const String localIPURL = "http://4.3.2.1"; // a string version of the local IP with http, used for redirecting clients to your webpage
|
||||
|
||||
String generateHTMLWithSSIDs()
|
||||
{
|
||||
String html = "<!DOCTYPE html><html><body><h2>Select Wi-Fi Network</h2><form action='/submit' method='POST'><label for='ssid'>SSID:</label><select id='ssid' name='ssid'>";
|
||||
|
||||
int n = WiFi.scanComplete();
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
html += "<option value='" + WiFi.SSID(i) + "'>" + WiFi.SSID(i) + "</option>";
|
||||
}
|
||||
|
||||
html += "</select><br><label for='password'>Password:</label><input type='password' id='password' name='password'><br><input type='submit' value='Connect'></form></body></html>";
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
const char index_html[] PROGMEM = R"=====(
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>ESP32 WiFi Setup</title>
|
||||
<style>
|
||||
body {background-color:#06cc13;}
|
||||
h1 {color: white;}
|
||||
h2 {color: white;}
|
||||
</style>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
</head>
|
||||
<body>
|
||||
<h1>WiFi Setup</h1>
|
||||
<form action="/submit" method="post">
|
||||
<label for="ssid">SSID:</label><br>
|
||||
<input type="text" id="ssid" name="ssid"><br>
|
||||
<label for="password">Password:</label><br>
|
||||
<input type="password" id="password" name="password"><br><br>
|
||||
<input type="submit" value="Connect">
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
)=====";
|
||||
|
||||
DNSServer dnsServer;
|
||||
AsyncWebServer server(80);
|
||||
|
||||
void setUpDNSServer(DNSServer &dnsServer, const IPAddress &localIP)
|
||||
{
|
||||
// Define the DNS interval in milliseconds between processing DNS requests
|
||||
#define DNS_INTERVAL 30
|
||||
|
||||
// Set the TTL for DNS response and start the DNS server
|
||||
dnsServer.setTTL(3600);
|
||||
dnsServer.start(53, "*", localIP);
|
||||
}
|
||||
|
||||
void startSoftAccessPoint(const char *ssid, const char *password, const IPAddress &localIP, const IPAddress &gatewayIP)
|
||||
{
|
||||
// Define the maximum number of clients that can connect to the server
|
||||
#define MAX_CLIENTS 4
|
||||
// Define the WiFi channel to be used (channel 6 in this case)
|
||||
#define WIFI_CHANNEL 6
|
||||
|
||||
// Set the WiFi mode to access point and station
|
||||
// WiFi.mode(WIFI_MODE_AP);
|
||||
|
||||
// Define the subnet mask for the WiFi network
|
||||
const IPAddress subnetMask(255, 255, 255, 0);
|
||||
|
||||
// Configure the soft access point with a specific IP and subnet mask
|
||||
WiFi.softAPConfig(localIP, gatewayIP, subnetMask);
|
||||
|
||||
// Start the soft access point with the given ssid, password, channel, max number of clients
|
||||
WiFi.softAP(ssid, password, WIFI_CHANNEL, 0, MAX_CLIENTS);
|
||||
|
||||
// Disable AMPDU RX on the ESP32 WiFi to fix a bug on Android
|
||||
esp_wifi_stop();
|
||||
esp_wifi_deinit();
|
||||
wifi_init_config_t my_config = WIFI_INIT_CONFIG_DEFAULT();
|
||||
my_config.ampdu_rx_enable = false;
|
||||
esp_wifi_init(&my_config);
|
||||
esp_wifi_start();
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS); // Add a small delay
|
||||
}
|
||||
|
||||
void connectToWifi(String ssid, String password)
|
||||
{
|
||||
WiFi.begin(ssid.c_str(), password.c_str());
|
||||
|
||||
// Wait for connection to establish
|
||||
int attempts = 0;
|
||||
while (WiFi.status() != WL_CONNECTED && attempts < 20)
|
||||
{
|
||||
delay(1000);
|
||||
Serial.print(".");
|
||||
attempts++;
|
||||
}
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
{
|
||||
Serial.println("Connected to Wi-Fi");
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("Failed to connect to Wi-Fi. Check credentials.");
|
||||
}
|
||||
}
|
||||
|
||||
void setUpWebserver(AsyncWebServer &server, const IPAddress &localIP)
|
||||
{
|
||||
//======================== Webserver ========================
|
||||
// WARNING IOS (and maybe macos) WILL NOT POP UP IF IT CONTAINS THE WORD "Success" https://www.esp8266.com/viewtopic.php?f=34&t=4398
|
||||
// SAFARI (IOS) IS STUPID, G-ZIPPED FILES CAN'T END IN .GZ https://github.com/homieiot/homie-esp8266/issues/476 this is fixed by the webserver serve static function.
|
||||
// SAFARI (IOS) there is a 128KB limit to the size of the HTML. The HTML can reference external resources/images that bring the total over 128KB
|
||||
// SAFARI (IOS) popup browser has some severe limitations (javascript disabled, cookies disabled)
|
||||
|
||||
// Required
|
||||
server.on("/connecttest.txt", [](AsyncWebServerRequest *request)
|
||||
{ request->redirect("http://logout.net"); }); // windows 11 captive portal workaround
|
||||
server.on("/wpad.dat", [](AsyncWebServerRequest *request)
|
||||
{ request->send(404); }); // Honestly don't understand what this is but a 404 stops win 10 keep calling this repeatedly and panicking the esp32 :)
|
||||
|
||||
// Background responses: Probably not all are Required, but some are. Others might speed things up?
|
||||
// A Tier (commonly used by modern systems)
|
||||
server.on("/generate_204", [](AsyncWebServerRequest *request)
|
||||
{ request->redirect(localIPURL); }); // android captive portal redirect
|
||||
server.on("/redirect", [](AsyncWebServerRequest *request)
|
||||
{ request->redirect(localIPURL); }); // microsoft redirect
|
||||
server.on("/hotspot-detect.html", [](AsyncWebServerRequest *request)
|
||||
{ request->redirect(localIPURL); }); // apple call home
|
||||
server.on("/canonical.html", [](AsyncWebServerRequest *request)
|
||||
{ request->redirect(localIPURL); }); // firefox captive portal call home
|
||||
server.on("/success.txt", [](AsyncWebServerRequest *request)
|
||||
{ request->send(200); }); // firefox captive portal call home
|
||||
server.on("/ncsi.txt", [](AsyncWebServerRequest *request)
|
||||
{ request->redirect(localIPURL); }); // windows call home
|
||||
|
||||
// B Tier (uncommon)
|
||||
// server.on("/chrome-variations/seed",[](AsyncWebServerRequest *request){request->send(200);}); //chrome captive portal call home
|
||||
// server.on("/service/update2/json",[](AsyncWebServerRequest *request){request->send(200);}); //firefox?
|
||||
// server.on("/chat",[](AsyncWebServerRequest *request){request->send(404);}); //No stop asking Whatsapp, there is no internet connection
|
||||
// server.on("/startpage",[](AsyncWebServerRequest *request){request->redirect(localIPURL);});
|
||||
|
||||
// return 404 to webpage icon
|
||||
server.on("/favicon.ico", [](AsyncWebServerRequest *request)
|
||||
{ request->send(404); }); // webpage icon
|
||||
|
||||
// Serve Basic HTML Page
|
||||
server.on("/", HTTP_ANY, [](AsyncWebServerRequest *request)
|
||||
{
|
||||
String htmlContent = index_html;
|
||||
Serial.printf("wifi scan complete: %d . WIFI_SCAN_RUNNING: %d", WiFi.scanComplete(), WIFI_SCAN_RUNNING);
|
||||
if(WiFi.scanComplete() > 0) {
|
||||
// Scan complete, process results
|
||||
Serial.println("done scanning wifi");
|
||||
htmlContent = generateHTMLWithSSIDs();
|
||||
// WiFi.scanNetworks(true); // Start a new scan in async mode
|
||||
}
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/html", htmlContent);
|
||||
response->addHeader("Cache-Control", "public,max-age=31536000"); // save this file to cache for 1 year (unless you refresh)
|
||||
request->send(response);
|
||||
Serial.println("Served Basic HTML Page"); });
|
||||
|
||||
// the catch all
|
||||
server.onNotFound([](AsyncWebServerRequest *request)
|
||||
{
|
||||
request->redirect(localIPURL);
|
||||
Serial.print("onnotfound ");
|
||||
Serial.print(request->host()); // This gives some insight into whatever was being requested on the serial monitor
|
||||
Serial.print(" ");
|
||||
Serial.print(request->url());
|
||||
Serial.print(" sent redirect to " + localIPURL + "\n"); });
|
||||
|
||||
server.on("/submit", HTTP_POST, [](AsyncWebServerRequest *request)
|
||||
{
|
||||
String ssid;
|
||||
String password;
|
||||
|
||||
// Check if SSID parameter exists and assign it
|
||||
if(request->hasParam("ssid", true)) {
|
||||
ssid = request->getParam("ssid", true)->value();
|
||||
}
|
||||
|
||||
// Check if Password parameter exists and assign it
|
||||
if(request->hasParam("password", true)) {
|
||||
password = request->getParam("password", true)->value();
|
||||
}
|
||||
|
||||
// Attempt to connect to the Wi-Fi network with these credentials
|
||||
connectToWifi(ssid, password);
|
||||
|
||||
// Redirect user or send a response back
|
||||
request->send(200, "text/plain", "Attempting to connect to " + ssid); });
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Set the transmit buffer size for the Serial object and start it with a baud rate of 115200.
|
||||
Serial.setTxBufferSize(1024);
|
||||
Serial.begin(115200);
|
||||
|
||||
// Wait for the Serial object to become available.
|
||||
while (!Serial)
|
||||
;
|
||||
|
||||
WiFi.mode(WIFI_AP_STA);
|
||||
|
||||
// Print a welcome message to the Serial port.
|
||||
Serial.println("\n\nCaptive Test, V0.5.0 compiled " __DATE__ " " __TIME__ " by CD_FER"); //__DATE__ is provided by the platformio ide
|
||||
Serial.printf("%s-%d\n\r", ESP.getChipModel(), ESP.getChipRevision());
|
||||
|
||||
startSoftAccessPoint(ssid, password, localIP, gatewayIP);
|
||||
|
||||
setUpDNSServer(dnsServer, localIP);
|
||||
|
||||
WiFi.scanNetworks(true);
|
||||
|
||||
setUpWebserver(server, localIP);
|
||||
server.begin();
|
||||
|
||||
Serial.print("\n");
|
||||
Serial.print("Startup Time:"); // should be somewhere between 270-350 for Generic ESP32 (D0WDQ6 chip, can have a higher startup time on first boot)
|
||||
Serial.println(millis());
|
||||
Serial.print("\n");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
dnsServer.processNextRequest(); // I call this atleast every 10ms in my other projects (can be higher but I haven't tested it for stability)
|
||||
delay(DNS_INTERVAL); // seems to help with stability, if you are doing other things in the loop this may not be needed
|
||||
|
||||
// Check WiFi connection status
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
{
|
||||
// If connected, you might want to do something, like printing the IP address
|
||||
Serial.println("Connected to WiFi!");
|
||||
Serial.println("IP Address: " + WiFi.localIP().toString());
|
||||
Serial.println("SSID " + WiFi.SSID());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue