ESP32 Chapter 11: Data Input on HTML Form ESP32 Web Server

Christovito Hidajat
7 min readApr 25, 2020

Hello and Welcome!

In the past few months, we have been the witnesses of how beneficial an ESP32 board is, and trust me, there are still lots of other things this little thing can do. To be honest, after all these projects, I come up with a thought that it is kind of mindblowing how rapid technology grows, particularly in the shape of a small yet unquestionably sophisticated microcontrollers. Time flies, and it is necessary for us to keep up with modern-technology changes in order to survive, don’t you think?

Speaking of which, there is yet another sophisticated feature of the ESP32, which is data input and value-saving on HTML Form in ESP32 Web Server. This project is even made easier because we require only the ESP32 board. In order to make you understand more, you can read randomnerdtutorials.com to make it easier to overview the project.

Handling Input Fields

The first part of this project is to handle input fields on web page with HTML form. Here is the code.

#include <Arduino.h>
#ifdef ESP32
#include <WiFi.h>
#include <AsyncTCP.h>
#else
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#endif
#include <ESPAsyncWebServer.h>
AsyncWebServer server(80);// REPLACE WITH YOUR NETWORK CREDENTIALS
const char* ssid = "THALIA";
const char* password = "********";
const char* PARAM_INPUT_1 = "input1";
const char* PARAM_INPUT_2 = "input2";
const char* PARAM_INPUT_3 = "input3";
// HTML web page to handle 3 input fields (input1, input2, input3)
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html><head>
<title>ESP Input Form</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head><body>
<form action="/get">
input1: <input type="text" name="input1">
<input type="submit" value="Submit">
</form><br>
<form action="/get">
input2: <input type="text" name="input2">
<input type="submit" value="Submit">
</form><br>
<form action="/get">
input3: <input type="text" name="input3">
<input type="submit" value="Submit">
</form>
</body></html>)rawliteral";
void notFound(AsyncWebServerRequest *request) {
request->send(404, "text/plain", "Not found");
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("WiFi Failed!");
return;
}
Serial.println();
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
// Send web page with input fields to client
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html);
});
// Send a GET request to <ESP_IP>/get?input1=<inputMessage>
server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputMessage;
String inputParam;
// GET input1 value on <ESP_IP>/get?input1=<inputMessage>
if (request->hasParam(PARAM_INPUT_1)) {
inputMessage = request->getParam(PARAM_INPUT_1)->value();
inputParam = PARAM_INPUT_1;
}
// GET input2 value on <ESP_IP>/get?input2=<inputMessage>
else if (request->hasParam(PARAM_INPUT_2)) {
inputMessage = request->getParam(PARAM_INPUT_2)->value();
inputParam = PARAM_INPUT_2;
}
// GET input3 value on <ESP_IP>/get?input3=<inputMessage>
else if (request->hasParam(PARAM_INPUT_3)) {
inputMessage = request->getParam(PARAM_INPUT_3)->value();
inputParam = PARAM_INPUT_3;
}
else {
inputMessage = "No message sent";
inputParam = "none";
}
Serial.println(inputMessage);
request->send(200, "text/html", "HTTP GET request sent to your ESP on input field (" + inputParam + ") with value: " + inputMessage + "<br><a href=\"/\">Return to Home Page</a>");
});
server.onNotFound(notFound);
server.begin();
}
void loop() {

}

Don’t forget to change some credentials needed. Upload this code to the board, open Serial Monitor, and you should see the ESP32 IP address.

Copy this IP Address to any web browser, and you should see a HTML web page like this below.

The web page display three input fields: input1, input2, and input3, where each field has a “Submit” button. When we enter a value to the fields and press the “Submit” button, the value is sent to the ESP and updates the variable. Take a closer look at this example below.

Supposedly we input a value of “18218043” on the input1 field and press Submit, the value “18218043” will be sent to the ESP and the input1’s value will be updated.

Notice that not only the value is updated, but also the URL link changes.

Saving Input Fields to SPIFFS

The second part is to save the value inserted to the fields permanently on SPIFFS. Take a look at this code below.

#include <Arduino.h>
#ifdef ESP32
#include <WiFi.h>
#include <AsyncTCP.h>
#include <SPIFFS.h>
#else
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <Hash.h>
#include <FS.h>
#endif
#include <ESPAsyncWebServer.h>
AsyncWebServer server(80);// REPLACE WITH YOUR NETWORK CREDENTIALS
const char* ssid = "THALIA";
const char* password = "********";
const char* PARAM_STRING = "inputString";
const char* PARAM_INT = "inputInt";
const char* PARAM_FLOAT = "inputFloat";
// HTML web page to handle 3 input fields (inputString, inputInt, inputFloat)
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html><head>
<title>ESP Input Form</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script>
function submitMessage() {
alert("Saved value to ESP SPIFFS");
setTimeout(function(){ document.location.reload(false); }, 500);
}
</script></head><body>
<form action="/get" target="hidden-form">
inputString (current value %inputString%): <input type="text" name="inputString">
<input type="submit" value="Submit" onclick="submitMessage()">
</form><br>
<form action="/get" target="hidden-form">
inputInt (current value %inputInt%): <input type="number " name="inputInt">
<input type="submit" value="Submit" onclick="submitMessage()">
</form><br>
<form action="/get" target="hidden-form">
inputFloat (current value %inputFloat%): <input type="number " name="inputFloat">
<input type="submit" value="Submit" onclick="submitMessage()">
</form>
<iframe style="display:none" name="hidden-form"></iframe>
</body></html>)rawliteral";
void notFound(AsyncWebServerRequest *request) {
request->send(404, "text/plain", "Not found");
}
String readFile(fs::FS &fs, const char * path){
Serial.printf("Reading file: %s\r\n", path);
File file = fs.open(path, "r");
if(!file || file.isDirectory()){
Serial.println("- empty file or failed to open file");
return String();
}
Serial.println("- read from file:");
String fileContent;
while(file.available()){
fileContent+=String((char)file.read());
}
Serial.println(fileContent);
return fileContent;
}
void writeFile(fs::FS &fs, const char * path, const char * message){
Serial.printf("Writing file: %s\r\n", path);
File file = fs.open(path, "w");
if(!file){
Serial.println("- failed to open file for writing");
return;
}
if(file.print(message)){
Serial.println("- file written");
} else {
Serial.println("- write failed");
}
}
// Replaces placeholder with stored values
String processor(const String& var){
//Serial.println(var);
if(var == "inputString"){
return readFile(SPIFFS, "/inputString.txt");
}
else if(var == "inputInt"){
return readFile(SPIFFS, "/inputInt.txt");
}
else if(var == "inputFloat"){
return readFile(SPIFFS, "/inputFloat.txt");
}
return String();
}
void setup() {
Serial.begin(115200);
// Initialize SPIFFS
#ifdef ESP32
if(!SPIFFS.begin(true)){
Serial.println("An Error has occurred while mounting SPIFFS");
return;
}
#else
if(!SPIFFS.begin()){
Serial.println("An Error has occurred while mounting SPIFFS");
return;
}
#endif
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("WiFi Failed!");
return;
}
Serial.println();
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
// Send web page with input fields to client
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html, processor);
});
// Send a GET request to <ESP_IP>/get?inputString=<inputMessage>
server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputMessage;
// GET inputString value on <ESP_IP>/get?inputString=<inputMessage>
if (request->hasParam(PARAM_STRING)) {
inputMessage = request->getParam(PARAM_STRING)->value();
writeFile(SPIFFS, "/inputString.txt", inputMessage.c_str());
}
// GET inputInt value on <ESP_IP>/get?inputInt=<inputMessage>
else if (request->hasParam(PARAM_INT)) {
inputMessage = request->getParam(PARAM_INT)->value();
writeFile(SPIFFS, "/inputInt.txt", inputMessage.c_str());
}
// GET inputFloat value on <ESP_IP>/get?inputFloat=<inputMessage>
else if (request->hasParam(PARAM_FLOAT)) {
inputMessage = request->getParam(PARAM_FLOAT)->value();
writeFile(SPIFFS, "/inputFloat.txt", inputMessage.c_str());
}
else {
inputMessage = "No message sent";
}
Serial.println(inputMessage);
request->send(200, "text/text", inputMessage);
});
server.onNotFound(notFound);
server.begin();
}
void loop() {
// To access your stored values on inputString, inputInt, inputFloat
String yourInputString = readFile(SPIFFS, "/inputString.txt");
Serial.print("*** Your inputString: ");
Serial.println(yourInputString);

int yourInputInt = readFile(SPIFFS, "/inputInt.txt").toInt();
Serial.print("*** Your inputInt: ");
Serial.println(yourInputInt);

float yourInputFloat = readFile(SPIFFS, "/inputFloat.txt").toFloat();
Serial.print("*** Your inputFloat: ");
Serial.println(yourInputFloat);
delay(5000);
}

Upload the code to the board, and by repeating the same steps as the steps in part 1, open the web browser. You will see a slightly similar HTML web page display as below.

The big difference is that there are placeholders added to each of the input fields to show the current values. The three input fields also requires different type of values: String, Integer, and Float.

Now, try to input data to each of the input fields. When you input a value in a field, a message saying “Saved value to ESP SPIFFS” will appear.

After inputting three different values for each data field, you can see that the current values shown on the web page change, as well as updated in the Arduino IDE Serial Monitor.

Supposedly we want to change again the value of “Patrick Segara” to “Christovito”, the current value on the web page will change…

…and the Arduino IDE Serial Monitor as well.

What do you say? Basic? Advanced? Mindblowing? Well, mine is simply just “cool”. But if you still want to dig deeper, the next project of ESP32 may well satisfy you. See you very soon!

Christovito Hidajat
18218043

--

--