Input Data on HTML Form

Ichsan Sholeh
ESP32 DEVKIT — AR Tech
10 min readApr 19, 2020

19 April 2020.

Halo! Selamat datang kembali ke tulisan gue yang berbau mata kuliah ‘Sistem Embedded’ huehuehue. Gue seneng bangetbisa nulis dalam jangka waktu yang singkat banget dari tulisan gue sebelumnya huehue. Karena kalo biasanya berjarak sampe 1 minggu lebih, sekarang ini selisih waktunya cuma 3 hari aja huehuehue. Produktif banget gue ya selama karantina ini :).

Seperti yang udah gue pernah mention pada tulisan-tulisan gue sebelumnya, sebenarnya pengerjaan project ini harusnya dikerjakan secara berkelompok 3 orang. Tetapi, karena sudah lebih dari 1 bulan ini kondisi sekarang belum membaik juga, maka tugas ini terpaksa gak bisa dikerjakan secara langsung oleh kelompok gue bersama-sama.

Nah, kalo pada 2 project sebelumnya gue mengerjakan project-nya bareng kelompok gue dengan menggunakan google meet, kali ini pun sama. Gue juga mengerjakan project ini via google meet, tetapi sayangnya salah satu temen gue gak bisa ikutan buat join meet kali ini, alhasil gue cume berdua dan video meet-nya pun di-record.

Oke kayaknya cukup intermezzonya, sekarang mari masuk ke bagian project-nya.

Pada project kali ini sama seperti 2 project sebelumnya, gue gak akan menuliskan tutorial untuk melakukan project ini. Melainkan, gue hanya memberikan gambaran serta menceritakan bagaimana proses pengerjaan pada project kali ini. Oiya, sebelumnya kalo kalian tetap ingin mencoba project kali ini, maka kalian bisa mengikuti tutorialnya di “Input Data on HTML Form ESP32/ESP8266 Web Server using Arduino IDE”. Oke sekarang kita langsung aja!

Overview

Pada project kali ini, gue akan membuat sebuah asynchronous web server dengan menggunakan library ESPAsyncWebServer, yang dapat menampilkan 3 field input untuk mengirimkan nilai tersebut yang dapat digunakan pada kode kita untuk meng-update variabel. Berikut adalah ilustrasinya:

Sumber: https://randomnerdtutorials.com/esp32-esp8266-input-data-html-form/

Pada ilustrasi tersebut, kita mempunyai sebuah web page dengan 3 kotak yang menerima input yang dapat kita akses. Ketika kita mengetik sebuah nilai baru dan menekan tombol ‘Submit’, maka ESP kita akan meng-update variabel tersebut dengan nilai yang baru dimasukkan.

Jika kita membutuhkan untuk melakukan update variabel melalui ESP web server, maka kita dapat menggunakan project ini sebagai dasarnya.

Selanjutnya kita juga dapat menyimpan variabel tersebut secara permanen dengan menggunakan SPIFFS dan mengakses variabel tersebut. Berikut ilustrasinya:

Sumber: https://randomnerdtutorials.com/esp32-esp8266-input-data-html-form/

Pada web page tersebut, kita dapat memasukkan 3 variabel dengan tipe data yang berbeda, yaitu String, Int, dan Float. Selanjutnya, setiap kita melakukan submit nilai baru, maka nilai tersebut akan disimpan pada file SPIFFS. Pada web page ini juga menyimpan sebuah ‘placeholder’ untuk menunjukan nilai yang tersimpan saat ini.

Alat dan Bahan

Nah sebelum ngerjain project gue kali ini, berikut adalah alat-alat yang akan gue gunakan:
1. Laptop
2. ESP32
3. Arduino IDE
4. Kabel micro USB
5. Breadboard
Berikut penampakannya:

(Abaikan DHT11-nya ya hehehe)

Skema Rangkaian

Gaada skema rangkaian khusus pada project kali ini huehue. Karena pada project kali ini, kita hanya memanfaatkan ESP32 aja yang utamanya. Jadi tanpa breadboard pun sebenarnya gak masalah hehe. So, selama bisa connect ESP32nya ke laptop, gaada masalah sama sekali huehue.

1. Ilustrasi Pertama

Pada bagian ini, gue akan menuntaskan terlebih dahulu pengerjaan untuk ilustrasi yang pertama.

Kode Program

Pada project ini, kurang lebih langkah-langkah yang gue lakukan sama dengan langkah-langkah yang ada pada tulisan di “Input Data on HTML Form ESP32/ESP8266 Web Server using Arduino IDE”, Bahkan kode program yang kita gunakan pun bisa dimasukkan hanya dengan sedikit modifikasi huehue. Berikut potongan kode programnya:

/*********
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 CREDENTIALS
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_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() {

}

Pada potongan kode program tersebut, kita harus memodifikasi tterlebih dahulu potongan kode dibawah ini yang disesuaikan dengan jaringan WiFi yang kalian akan gunakan untuk ESP32 ini.

const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

Selanjutnya juga kita dapat mengubah beberapa String yang akan ditampilkan pada webpage dengan memodifikasi String pada potongan kode berikut:

const char* PARAM_INPUT_1 = "input1";
const char* PARAM_INPUT_2 = "input2";
const char* PARAM_INPUT_3 = "input3";

Testing

Setelah memodifikasi potongan kode program tersebut, kita dapat meng-upload kode tersebut ke ESP32. Selanjutnya apabila kode kita berhasil ter-upload ke ESP32, maka ketika kita membuka Serial Monitor dengan Baud Rate 115200, maka akan terlihat seperti pada gambar berikut:

IP address yang tercetak pada Serial Monitor

IP address yang tercetak pada serial monitor tersebut selanjutnya dapat kita akses apabila kita membukanya pada browser. Selanjutnya jika kita buka, maka akan ditampilkan halaman seperti pada gambar berikut:

Halaman pada project ilustrasi pertama

Selanjutnya kita dapat meng-input sebuah nilai pada field tersebut yang hasil bacaannya akan dicetak pada serial monitor.

Selanjutnya hasil tersebut akan dicetak pada Serial Monitor

Selesai deh testing untuk ilutrasi pertama ini huehue.

2. Ilustrasi Kedua

Pada bagian ini, gue akan menuntaskan terlebih dahulu pengerjaan untuk ilustrasi yang kedua.

Kode Program

Sama seperti ilustrasi pertama, pada ilustrasi kedua ini kita hanya perlu memodifikasi beberapa potongan program pada templat kode program yang sudah ada. Berikut potongan kodenya:

/*********
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 CREDENTIALS
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_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);
}

Sama seperti ilustrasi sebelumnya, pada potongan kode program tersebut, kita harus memodifikasi tterlebih dahulu potongan kode dibawah ini yang disesuaikan dengan jaringan WiFi yang kalian akan gunakan untuk ESP32 ini.

// REPLACE WITH YOUR NETWORK CREDENTIALS
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

Selanjutnya juga kita dapat mengubah beberapa String yang akan ditampilkan pada webpage dengan memodifikasi String pada potongan kode berikut:

const char* PARAM_STRING = "inputString";
const char* PARAM_INT = "inputInt";
const char* PARAM_FLOAT = "inputFloat";

Testing

Setelah memodifikasi potongan kode program tersebut, kita dapat meng-upload kode tersebut ke ESP32. Selanjutnya apabila kode kita berhasil ter-upload ke ESP32, maka ketika kita membuka Serial Monitor dengan Baud Rate 115200, maka akan terlihat seperti pada gambar berikut:

IP address yang tercetak pada serial monitor tersebut selanjutnya dapat kita akses apabila kita membukanya pada browser. Selanjutnya jika kita buka, maka akan ditampilkan halaman seperti pada gambar berikut:

Selanjutnya kita dapat meng-input sebuah nilai pada field tersebut yang hasil bacaannya akan dicetak pada “current value”, serta pada serial monitor.

Selanjutnya hasil tersebut pun akan dicetak secara berkala pada serial monitor.

Yeay, selesai deh project kali ini huehue. Menurut gue pribadi sih project kali ini jauh lebih mudah dari 2 project sebelumnya. Karena pada project ini gue cuma butuh ESP32, dan memodifikasi potongan kode dan meng-upload nya ke ESP32. Dan menarik sih menurut gue karena walaupun gampang kayak gini project-nya, tetapi kita bisa memanfaatkan HTML dan menerima sebuah input yang dapat kita manfaatkan untuk mengubah nilai suatu variabel huehue.

Berikut dokumentasi pada saat pengerjeaan project kali ini:

Sekian dulu untuk tulisan gue kali ini, Semoga bisa bermanfaat,

Semoga gue bisa mendapatkan indeks A, aamiin :), dan semoga kita semua sehat selalu!

Enjoy!

--

--

Ichsan Sholeh
ESP32 DEVKIT — AR Tech

Information System and Technology Student at Bandung Institute of Technology