ESP32 is a device with integrated WiFi and BLE. It is kind of a boon for the IoT projects. Just give your SSID, password and IP configurations and integrate the things into the cloud. But, managing the IP settings and user credentials can be a headache to the user.
What if the User wants to change the WiFi credentials?
What if the user wants to switch the DHCP/static IP settings?
Flashing the ESP32 everytime is not reliable and not even the solution for these problems. Here in this tutorial we will be going to demonstrate.
- How to create a captive portal.
- Hosting a web form from theESP32.
- Reading and Writing from SPIFFS ESP32.
- Creating a Soft Access Point and connecting to a station.
A captive portal is a web page that is displayed to newly connected users t before they are granted broader access to network resources. Here we are serving three web pages to select between DHCP and Static IP Settings. we can define the IP address to ESP in two ways.
- DHCP IP address- it is a way to dynamically assign the IP address to the device. The ESP's default IP address is 192.168.4.1
- Static IP address- assigning a permanent IP Adress to our network device. to provide the static IP to the device we need to define the IP address, gateway address, and subnet mask.
In the first webpage, the User is provided with the radio buttons to select between DHCP and Static IP settings. In the next webpage, we have to provide the IP related information to proceed further.
HTML CodeThe HTML code for web pages can be found in this Github repository.
You can use any IDE or text editor like Sublime or notepad++ to make HTML web pages.
- First Create an HTML webpage containing two radio buttons to choose between DHCP and Static IP Settings.
- Now create the button to submit your response
- Give some name to radio buttons. The ESP Web server class will take these names as arguments and get the response of the radio buttons using these arguments
- Now insert a ' SUBMIT ' button to send the response to the device.
- In the other web pages, we have text boxes. Give the name value and Input type to the text box and add a submit button to ' SUBMIT ' submit the response.
- Create a ' RESET ' button to reset the content of the text field.
//Radio Button
<div id="radio_select">
<input type="radio" name = "configure" value="dhcp" id="radio_dhcp">DHCP Setting<div>
<p>
<input type="radio" name = "configure" value="dhcp" id="radio_static">Static IP Setting</p>
//Input Text Boxes
<p>
<input maxlength="30px" type='text' name="ipv4static" placeholder='ip Address' style="width: 400px; padding: 5px 10px ;" required></p>
<p><input maxlength="30px" type = "text" name="gateway" placeholder = "gateway address" style="width: 400px; padding: 5px 10px ;" required></p>
<p><input maxlength="30px" type = "text" name="subnet" placeholder= "subnet mask" style="width: 400px; padding: 5px 10px ;" required></p>
<p><INPUT type="submit">
<style>
input[type="submit"]
{background-color: #3498DB;
border: none;
color: white;
padding:15px 48px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;}
//Reset Button
<INPUT type = "reset">
<style>
input[type="reset"]
{ background-color: #3498DB;
border: none;
color: white;
padding:15px 48px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;}
</style>
Serving web pages from ESP 32 device is great fun. It can be anything fromshowing the temperature data in the webpage,turning the led's from the custom webpage or storing the User WiFi credentials through a webpage. For this purpose, ESP 32 uses WebServer Class to server web pages.
- First, Create an instance of WebServer class at port 80(HTTP port).
- Now set up the ESP device as softAP. Give the SSID and passkey and assign a static IP to the device.
- Begin the server.
//*********SSID and Pass for AP**************/
const char *ssidAP = "give SSID";const char *passAP = "pass key";
//*********Static IPConfig**************/IPAddress ap_local_IP(192,168,1,77);
IPAddress ap_gateway(192,168,1,254);
IPAddress ap_subnet(255,255,255,0);//*********SoftAP Config**************/ WiFi.mode(WIFI_AP); Serial.println(WiFi.softAP(ssidAP,passAP) ? "soft-AP setup": "Failed to connect"); delay(100);
Serial.println(WiFi.softAPConfig(ap_local_IP, ap_gateway, ap_subnet)? "Configuring Soft AP" : "Error in Configuration");
Serial.println(WiFi.softAPIP());//begin the server server.begin();
- Create and serve the URL using different callbacks.
- and handle the client asynchronously using handleClient.
server.on("/", handleRoot);
server.on("/dhcp", handleDHCP);
server.on("/static", handleStatic);
// handle the responses
server.handleClient();
- To access the web pages. Connect to the AP that you have just created, listed within your WiFi networks. Now, go to the browser, Enter the IP configured by you in the last step and access the webpage.
- Web server class takes the name given to inputs( 'text', 'button', 'radiobutton'etc.) as arguments. It saves the responses of these inputs as arguments and we can get the values or check them using args(), arg(),hasArg() methods.
if(server.args()>0){ for(int i=0; i<=server.args();i++){ Serial.println(String(server.argName(i))+'\t' + String(server.arg(i))); }if(server.hasArg("ipv4static") && server.hasArg("gateway") && server.hasArg("subnet")){ staticSet();
}else if(server.arg("ipv4")!= ""){
dhcpSetManual();
}else{
dhcpSetDefault();
}
Static IP ConfigurationSo far we have understood how to connect to AP and how to get the values from the input fields of webpage.
In this step, we will configure the Static IP
- Select the Static IP Setting and click on Submit button. You will be redirected to the next page.
- In the next page enter the static IP address, gateway address and subnet Mask this page will be served at "/static" which is handled by handleStatic callback method.
- Get the value of text fields using server.arg() method.
String ipv4static = String(server.arg("ipv4static"));String gateway = String(server.arg("gateway"));String subnet = String(server.arg("subnet"));
- Now, these values are in Strings and we need to convert these values in IP Address type.
- First, convert the values into char array.
ipv4static.toCharArray(ipv4Arr,sizeof(ipv4static)+2);
gateway.toCharArray(gatewayArr,sizeof(gateway)+2);
subnet.toCharArray(subnetArr,sizeof(subnet)+2);
- And parse the String values into bytes.
- Create an IP address type of object and setup an Access Point using these static IP credentials
- You can find the Access Point in the available WiFi Networks list.
byte ip[4];parseBytes(ipv4Arr,'.', ip, 4, 10);void parseBytes(const char* str, char sep, byte* bytes, int maxBytes, int base) {for (int i = 0; i < maxBytes; i++)
{ bytes[i] = strtoul(str, NULL, base);
// Convert byte
str = strchr(str, sep);
// Find next separator
if (str == NULL || *str == '\0') {
break;
// No more separators, exit
}
str++; // Point to next character after separator }}ip0 = (uint8_t)ip[0];ip1 = (uint8_t)ip[1];
ip2 = (uint8_t)ip[2];
ip3 = (uint8_t)ip[3];
IPAddress ap_local(ip0,ip1,ip2,ip3);
ap_localWeb_IP = ap_local;WiFi.disconnect(true);WiFi.mode(WIFI_AP);
Serial.println(WiFi.softAP(ssidAPWeb) ? "Setting up SoftAP" : "error setting up");Serial.println(WiFi.softAPConfig(ap_localWeb_IP, ap_gate, ap_net) ? "Configuring softAP" : "kya yaar not connected");
DHCP SettingsIn this step, we will configure the DHCP Settings
- Select the DHCP Settings from the index page and click on "Submit"
- You will be redirected to the next page. In the next page enter the IP address or select choose default and click on the "Submit" button to submit the response. This page will be served at "/dhcp" which is handled by handleDHCP callback method. Get the value of text fields using server.arg() method. When clicked in choose default checkbox. the 192.168.4.1 IP will be given to the device.
- Now setUp an Acess point using WiFi.softAP() the device will dynamically assign the fixed IP 192.168.4.1.
WiFi.disconnect(false);WiFi.enableAP(false); InitAP(); isConnected = false;void InitAP(){WiFi.enableAP(true);
WiFi.mode(WIFI_AP);
Serial.println(WiFi.softAP(ssidDhcpWeb) ? "SoftAP setup" : "Error Setting UP AP" ); delay(100);
Serial.println(WiFi.softAPConfig(ap_dhcp, ap_gateway, ap_subnet)? "Configuring Soft AP" : "Error in Configuration");
Serial.println(WiFi.softAPIP());
}
Read and Write From SPIFFSSPIFFSSerial Peripheral Interface Flash File System, or SPIFFS for short. It's a light-weight file system for microcontrollers with an SPI flash chip. The onboard flash chip of the ESP32 has plenty of space for your web pages. We have also stored our webpage in Flash System. There are a few steps we need to follow to upload data to spiffs
- Download the ESP 32 SPIFFS data upload tool: https://github.com/me-no-dev/arduino-esp32fs-plugi...
- In your Arduino sketchbook directory, create tools directory if it doesn't exist yet
- Unpack the tool into tools directory (the path will look like /Arduino/tools/ESP32FS/tool/esp32fs.jar)
- Restart Arduino IDE
- Open a sketch (or create a new one and save it)
- Go to sketch directory (choose Sketch > Show Sketch Folder)
- Create a directory named data and any files you want in the file system there. We have uploaded our HTML page with name webform.html
- Make sure you have selected a board, port, and closed Serial Monitor
- Select Tools > ESP8266 Sketch Data Upload. This should start uploading the files into the ESP8266 flash file system. When done, IDE status bar will display SPIFFS Image Uploaded message.
void handleDHCP(){File file = SPIFFS.open("/page_dhcp.html", "r");
server.streamFile(file,"text/html");
file.close();}void handleStatic(){
File file = SPIFFS.open("/page_static.html", "r");
server.streamFile(file,"text/html");
file.close();
}
Writing to SPIFFSHere we are writing the saved setting to the SPIFFS so that users should not have to go through these steps whenever device resets.
- Convert the arguments received from the webpage to JSON objects
- Write this JSON to the.txt file saved in SPIFFS.
String ipv4static = String(server.arg("ipv4static"));String gateway = String(server.arg("gateway"));
String subnet = String(server.arg("subnet"));
root["statickey"]="staticSet";
root["staticIP"] = ipv4static;
root["gateway"] = gateway;
root["subnet"] = subnet;
String JSONStatic;
char JSON[120];
root.printTo(Serial);
root.prettyPrintTo(JSONStatic);
JSONStatic.toCharArray(JSON,sizeof(JSONStatic)+2);
File fileToWrite = SPIFFS.open("/ip_set.txt", FILE_WRITE);
if(!fileToWrite){
Serial.println("Error opening SPIFFS"); }
if(fileToWrite.print(JSON)){
Serial.println("--File Written");
}else{
Serial.println("--Error Writing File"); }
fileToWrite.close();
}
Overall CodeThe Over code for HTML and ESP32 can be found in this GitHub repository.
Comments