The next task in this project is to set up what's called a "Captive Portal" - that's a screen that pops up as soon as a device connects to the wifi.
When the device tries to connect with the ESP32’s WiFi, it tries to send a request to a specific URL. The ESP32’s DNS server redirects it to the Soft AP IP address of ESP32. On this IP, the captive request handler takes care of displaying the webpage, and the Async Web Server (set up using setupServer()), handles all the incoming requests.
Here is the device screen.
I need to change the landing screen code to match what I was getting in the previous version.
#include <DNSServer.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include "ESPAsyncWebServer.h"
DNSServer dnsServer;
AsyncWebServer server(80);
String user_name;
String proficiency;
bool name_received = false;
bool proficiency_received = false;
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html><head>
<title>Captive Portal Demo</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head><body>
<h1>Welcome to The Internet</h1>
<br><br>
<form action="/get">
<br>
Name: <input type="text" name="name">
<br>
ESP32 Proficiency:
<select name = "proficiency">
<option value=Beginner>Beginner</option>
<option value=Advanced>Advanced</option>
<option value=Pro>Pro</option>
</select>
<input type="submit" value="Submit">
</form>
</body></html>)rawliteral";
class CaptiveRequestHandler : public AsyncWebHandler {
public:
CaptiveRequestHandler() {}
virtual ~CaptiveRequestHandler() {}
bool canHandle(AsyncWebServerRequest *request){
//request->addInterestingHeader("ANY");
return true;
}
void handleRequest(AsyncWebServerRequest *request) {
request->send_P(200, "text/html", index_html);
}
};
void setupServer(){
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html);
Serial.println("Client Connected");
});
server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputMessage;
String inputParam;
if (request->hasParam("name")) {
inputMessage = request->getParam("name")->value();
inputParam = "name";
user_name = inputMessage;
Serial.println(inputMessage);
name_received = true;
}
if (request->hasParam("proficiency")) {
inputMessage = request->getParam("proficiency")->value();
inputParam = "proficiency";
proficiency = inputMessage;
Serial.println(inputMessage);
proficiency_received = true;
}
request->send(200, "text/html", "The values entered by you have been successfully sent to the device <br><a href=\"/\">Return to Home Page</a>");
});
}
void setup() {
// put your setup code here, to run once:
//your other setup stuff...
Serial.begin(115200);
Serial.println();
Serial.println("Setting up AP Mode");
WiFi.mode(WIFI_AP);
WiFi.softAP("The_Internet");
Serial.print("AP IP address: ");Serial.println(WiFi.softAPIP());
Serial.println("Setting up Async WebServer");
setupServer();
Serial.println("Starting DNS Server");
dnsServer.start(53, "*", WiFi.softAPIP());
server.addHandler(new CaptiveRequestHandler()).setFilter(ON_AP_FILTER);//only when requested from AP
//more handlers...
server.begin();
Serial.println("All Done!");
}
void loop(){
dnsServer.processNextRequest();
if(name_received && proficiency_received){
Serial.print("Hello ");Serial.println(user_name);
Serial.print("You have stated your proficiency to be ");Serial.println(proficiency);
name_received = false;
proficiency_received = false;
Serial.println("We'll wait for the next client now");
}
}