In this guide, you’ll learn how to create an ESP32/ESP8266 web server with three input fields to pass values to your ESP using an HTML form. Then, you can use those values as variables in your code. We’ll be using the Arduino IDE to program the boards.
Project Overview
In this tutorial we’ll build an asynchronous web server using the ESPAsyncWebServer library that displays three input fields to pass values that you can use in your code to update variables.
We’ll take a look at two similar examples. The following figure illustrates how the first example works.
You have a web page with three input fields that you can access with any browser in your network. When you type a new value and press the “Submit” button, your ESP will update a variable with the new value.
If you ever needed to update a variable through an ESP web server, you should follow this project. With this method, you avoid hard coding variables because you can create an input field in a web page to update any variable with a new value. This can be specially useful to set threshold values, set SSID/password, change API Keys, etc…
Later, we’ll also show you how to save those variables permanently using SPIFFS and how to access them. Here’s how this second example works.
This web page allows you to enter three types of variables: String, Int and Float. Then, every time you submit a new value, that value is stored in a SPIFFS file. This web page also contains a placeholder to show the current values.
To learn more about building a web server using SPIFFS, you can refer to the next tutorials:
Make sure you check all the prerequisites in this section before continuing with the project in order to compile the code.
1. Install ESP32/ESP8266 Board in Arduino IDE
We’ll program the ESP32 and ESP8266 using Arduino IDE. So, you must have the ESP32 or ESP8266 add-on installed. Follow one of the next tutorials to install the ESP add-on:
These libraries aren’t available to install through the Arduino Library Manager, so you need to copy the library files to the Arduino Installation folder. Alternatively, in your Arduino IDE, you can go to Sketch > Include Library > Add .zip Library and select the libraries you’ve just downloaded.
3. Parts Required
To follow this tutorial you just need an ESP32 or ESP8266 (read ESP32 vs ESP8266). There’s no circuit for this project.
1. ESP32/ESP8266 Handle Input Fields on Web Page with HTML Form
Copy the following code to the Arduino IDE. Then, type your network credentials (SSID and password) to make it work for you.
/*********/*********
Rui Santos
Complete project details at https://RandomNerdTutorials.com/esp32-esp8266-input-data-html-form/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
*********/#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 CREDENTIALSconstchar* ssid ="REPLACE_WITH_YOUR_SSID";constchar* password ="REPLACE_WITH_YOUR_PASSWORD";constchar* PARAM_INPUT_1 ="input1";constchar* PARAM_INPUT_2 ="input2";constchar* PARAM_INPUT_3 ="input3";// HTML web page to handle 3 input fields (input1, input2, input3)constchar 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";voidnotFound(AsyncWebServerRequest *request){
request->send(404,"text/plain","Not found");}voidsetup(){
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>elseif(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>elseif(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();}voidloop(){}
Let’s take a quick look at the code and see how it works.
Including libraries
First, include the necessary libraries. You include different libraries depending on the board you’re using. If you’re using an ESP32, the code loads the following libraries:
First, let’s take a look at the HTML that we need to display the input fields.
In our example, we display three input fields and each field has a “Submit” button. When the user enters data and presses the “Submit” button, that value is sent to the ESP and updates the variable.
The action attribute specifies where to send the data inserted on the form after pressing submit. In this case, it makes an HTTP GET request to /get?input1=value. The value refers to the text you enter in the input field.
Then, we define two input fields: one text field and one submit button.
The following line defines a one line text input field.
input1: <inputtype="text"name="input1">
The type attribute specifies we want a text input field, and the name attribute specifies the name of the input element.
The next line defines a button for submitting the HTML form data.
<inputtype="submit"value="Submit">
In this case, the type attribute specifies you want a submit button, and the value specifies the text on the button.
We create two variables: inputMessage and inputParam to save the input value and the input field.
Then, we need to check whether the HTTP GET request contains the input1, input2, or input3 parameters. These are saved on the PARAM_INPUT_1, PARAM_INPUT_2 and PARAM_INPUT_3 variables.
If the request contains the PARAM_INPUT_1 (i.e. input1), we set the inputMessage to the value inserted in the input1 field.
Now you have the value you’ve just inserted on the first form saved on the inputMessage variable.
Then, set the inputParam variable to PARAM_INPUT_1 so that we know where the input value comes from.
When you submit the form, you get a message saying the value you’ve inserted and in which field. We also display a link to get back to the route URL (Home Page).
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>");
If you make a request on an invalid URL, we call the notFound() function, defined at the beginning of the sketch.
After uploading code to your board, open your Arduino IDE Serial Monitor at a baud rate of 115200 to find the ESP IP address.
Then, open your browser and type the IP address. This web page should load:
For example, type 123456 on input1 field, then press the “Submit” button. A new page should load saying that value 123456 was sent to your ESP:
2. ESP32/ESP8266 Save Input Fields to SPIFFS
Now, let’s proceed to the second example. This example saves the data inserted on the input fields permanently on SPIFFS. We’ve also added placeholders on the web page to show the current values.
Copy the following sketch to Arduino IDE. Then, before uploading type your network credentials (SSID and password).
/*********
Rui Santos
Complete project details at https://RandomNerdTutorials.com/esp32-esp8266-input-data-html-form/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
*********/#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 CREDENTIALSconstchar* ssid ="REPLACE_WITH_YOUR_SSID";constchar* password ="REPLACE_WITH_YOUR_PASSWORD";constchar* PARAM_STRING ="inputString";constchar* PARAM_INT ="inputInt";constchar* PARAM_FLOAT ="inputFloat";// HTML web page to handle 3 input fields (inputString, inputInt, inputFloat)constchar 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";voidnotFound(AsyncWebServerRequest *request){
request->send(404,"text/plain","Not found");}
String readFile(fs::FS &fs,constchar* 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");returnString();}
Serial.println("- read from file:");
String fileContent;while(file.available()){
fileContent+=String((char)file.read());}
Serial.println(fileContent);return fileContent;}voidwriteFile(fs::FS &fs,constchar* path,constchar* 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"){returnreadFile(SPIFFS,"/inputString.txt");}elseif(var =="inputInt"){returnreadFile(SPIFFS,"/inputInt.txt");}elseif(var =="inputFloat"){returnreadFile(SPIFFS,"/inputFloat.txt");}returnString();}voidsetup(){
Serial.begin(115200);// Initialize SPIFFS#ifdef ESP32if(!SPIFFS.begin(true)){
Serial.println("An Error has occurred while mounting SPIFFS");return;}#elseif(!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>elseif(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>elseif(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();}voidloop(){// 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);}
In this example, when you submit the values, a window opens saying the value was saved to SPIFFS, instead of being redirected to another page as in the previous example.
For that, we need to a add a JavaScript function, in this case it’s called submitMessage() that pops an alert message saying the value was saved to SPIFFS. After that pop up, it reloads the web page so that it displays the current values.
<script>functionsubmitMessage(){alert("Saved value to ESP SPIFFS");setTimeout(function(){ document.location.reload(false);},500);}</script>
The forms are also a bit different from the previous ones. Here’s the form for the first input.
<formaction="/get"target="hidden-form">
inputString (current value %inputString%): <inputtype="text"name="inputString"><inputtype="submit"value="Submit"onclick="submitMessage()"></form>
In this case, the target attribute and an <iframe> are used so that you remain on the same page after submitting the form.
The name that shows up for the input field contains a placeholder %inputString% that will then be replaced by the current value of the inputString variable.
The onclick=”submitMessage()” calls the submitMessage() JavaScript function after clicking the “Submit” button.
Read and Write to SPIFFS
Then, we have some functions to read and write from SPIFFS.
The readFile() reads the content from a file:
String readFile(fs::FS &fs,constchar* 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");returnString();}
Serial.println("- read from file:");
String fileContent;while(file.available()){
fileContent+=String((char)file.read());}
Serial.println(fileContent);return fileContent;
The writeFile() writes content to a file:
voidwriteFile(fs::FS &fs,constchar* path,constchar* 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");}}
processor()
The processor() is responsible for searching for placeholders in the HTML text and replacing them with actual values saved on SPIFFS.
After uploading code to your board, open your Arduino IDE Serial Monitor at a baud rate of 115200 to find the ESP IP address.
Open your browser and type the IP address. A similar web page should load (at first your current values will be blank).
Type a String in the first input field and press “Submit”, repeat the same process for the Int and Float input values. Every time you press the Submit button for a field, you’ll see an alert message like this:
Press the “OK” button to reload the web page and see the current values updated.
If you have your Arduino IDE Serial Monitor open, you’ll see that the stored values are being printed over and over again:
For a final project, you can delete all those lines in your loop() that print all stored values every 5 seconds, we just left them on purpose for debugging.
Wrapping Up
In this tutorial you’ve learned how to handle input fields in a web page to update the ESP variable values. You can modify this project to set thresholds, change API Key values, set a PWM value, change a timer, set SSID/password, etc.
沒有留言:
張貼留言