ESP32 Devlog 13 — ESP32 HTML Input Form
Remember the GET and POST form for HTML? yea, we could do that in here too with Google Sheets Integration.
This is an continuation from the previous blog post. We don’t use BMP180 as an reading to the post anymore. instead, we are making a form with ESP32 and passes the data to the Google Sheets using IFTTT Webhooks service. As usual, i’m using the Random Nerd Tutorials article about ESP32 Input Data HTML Form as a reference.
In the previous web project, we make a simple data logging that saves the ESP32 readings to the Google Sheets for future use by sending the request to the 3rd party IFTTT Webhooks service. Here’s the previous link to the old projects related to this devlog:
- ESP32 Devlog 8 — Wifi LED Switch
- ESP32 Devlog 9 — Real-Time Weather Station Web
- ESP32 Devlog 10 — SPIFFS Filesystem
- ESP32 Devlog 11 — Data Visualization
- ESP32 Devlog 12 — Data Logging
In this project, i want to make a simple HTML form. I also want to log our form data using spreadsheets. This can be used for a feedback feature or something else. The whys about my decision to use IFTTT could be read from my previous devlog. The concept is more like this:
- First, the ESP32 connects to the wireless network and ready to be connected by clients
- Then, the client sends some data from the web page
- The ESP32 communicates with the IFTTT Webhooks service that publishes the data to a spreadsheet on Google Sheets that is saved in the Google Drive folder
- After publish the readings, the ESP32 is ready for another connection to the client.
I assume you guys have made an IFTTT account and could make a webhook to google sheet service. The details can be found on my previous devlog about data logging with IFTTT Webhook.
A. Requirements and To-Do
These are the requirements for this project assuming you have your own personal Google Account and IFTTT Account:
Software Requirement
- Arduino IDE with ESP32 Board Support
- Modern Browser that can open google sheets without problem
Hardware Requirement
To be frank, ESP32 alone with USB to UART cable is sufficient enough
Service Requirement
- IFTTT Webhooks
- Google Sheets
- Knowledge about how the HTTP POST and GET works.
To-Do
- Make a cool HTML form, in this case the feedback form consists of 3 fields: Name, Feedback Test, and Rating.
- Use the ESP32 to pass the data to IFTTT Webhook service to log the readings to Google Sheets
Document Tree
Most of the links refer to the Random Nerd Tutorials, check the blog out for more reference and technical detail. This devlog is not a tutorial, rather it keeps me log the troubles i’ve got so far.
B. Make another Webhooks to Google Sheets Service
Create an applet by clicking the human head looking icon on the top right.
Click the “This” word
Type “webhook” in the input form and click the big blue rectangle webhooks icon
Click connect
Then there was an blue button element which titled “Receive a web request” in Choose Trigger page. Click on it.
You will be taken to complete trigger fields page. Enter the Event name.
Then, click on the “That” button
Fill the input form with “sheets” keyword and you will get the dark blue Google Sheets button. Click on it.
Connect to the google sheets and select the appropriate account. Allow the IFTTT permissions to Google Services
Then, click the button titled “Add row to spreadsheet”
Fill out the forms, the Spreadsheet name, formatted row, and drive folder path. Leave the drive folder path empty to default. After that, click the Create Action Button
Then, you’ll arrived at Review and Finish page. Turn off the notifications and click the Finish Button.
C. Test the Webhook Service
First, go to the Webhook page in the IFTTT. the click the documentation button on the top left beside the settings button.
The button will take you to settings page. You may test the event by filling out the form and check your corresponding google sheets.
D. Create Arduino File
First, include the necessary libraries to the sketch.
#include <WiFi.h>
#include "SPIFFS.h"
#include "ESPAsyncWebServer.h"
Then, create an instance to make an Asynchronous Web Server
AsyncWebServer server(80);
The thing you would like to modify is the ssid and the password to connect to the wireless network you use. Then, change the value of resource constant equals to the unique IFTTT URL Resource.
// Replace with your SSID and Password
const char* ssid = "TP-LINK_890E7A";
const char* password = "suryanaga";// Replace with your unique IFTTT URL resource
const char* resource = "/trigger/bmp180_readings/with/key/dO1uekEnRGjVGzi245KCYn";
In the setup(), initialize the serial baud rate and SPIFFS filesystem
Serial.begin(115200); // Hardware Checking
if(!SPIFFS.begin(true)){
Serial.println("An Error has occurred while mounting SPIFFS");
return;
}
Then, connect to WiFi and print the IP Address in the Serial Monitor
// Connect to WiFi
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi Connected");
Serial.println("IP Address: ");// Local IP Address
Serial.println(WiFi.localIP());
The next step is to configure the web server routing. I have an style.css and script.js as usual, but the script.js may be empty so you may focus on the /post URI. It mainly uses the AsyncWebServer library to get the HTTP Request parameters. You can find out more in the documentation.
// Routing
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(SPIFFS, "/index.html");
});server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(SPIFFS, "/style.css", "text/css");
});server.on("/success.svg", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(SPIFFS, "/success.svg", "image/svg+xml");
});server.on("/script.js", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(SPIFFS, "/script.js", "text/javascript");
});server.on("/post", HTTP_POST, [](AsyncWebServerRequest *request){
String nama = "";
String feedback = "";
String rating = "";
if(request->hasParam("nama", true)) {
AsyncWebParameter* p = request->getParam("nama", true);
nama = p->value().c_str();
} if(request->hasParam("feedback", true)) {
AsyncWebParameter* p = request->getParam("feedback", true);
feedback = p->value().c_str();
} if(request->hasParam("rating", true)) {
AsyncWebParameter* p = request->getParam("rating", true);
rating = p->value().c_str();
} makeIFTTTRequest(nama, feedback, rating);
request->send(SPIFFS, "/success.html");
});server.begin();
The makeIFTTTRequest Procedure
The HTTP request to the IFTTT service is similiar to my previous devlog about the HTTP Connection. The different thing in this project is instead of text/html data, we are sending POST (not GET) request to the IFTTT service which consists of an application/json data. We construct the jsonObject
void makeIFTTTRequest(String value1, String value2, String value3) {
Serial.print("Connecting to ");
Serial.print(IFTTTserver);
WiFiClient client;
int retries = 5;
while(!!!client.connect(IFTTTserver, 80) && (retries-- > 0)) {
Serial.print(".");
}
Serial.println();
if(!!!client.connected()) {
Serial.println("Failed to connect...");
}
Serial.print("Request resource: ");
Serial.println(resource);
String jsonObject = String("{\"value1\":\"") + value1 + "\",\"value2\":\"" + value2 + "\",\"value3\":\"" + value3 + "\"}";
client.println(String("POST ") + resource + " HTTP/1.1");
client.println(String("Host: ") + IFTTTserver);
client.println("Connection: close\r\nContent-Type: application/json");
client.print("Content-Length: ");
client.println(jsonObject.length());
client.println();
client.println(jsonObject);
int timeout = 5 * 10; // 5 seconds
while(!!!client.available() && (timeout-- > 0)){
delay(100);
}
if(!!!client.available()) {
Serial.println("No response...");
}
while(client.available()){
Serial.write(client.read());
}
Serial.println("\nclosing connection");
client.stop();
}
The ESP32 will send the data to the IFTTT and the IFTTT will pass the data to the Google Sheets which can be saved for later use.
E. Demonstration
F. Conclusion and Next Project
The next project would be a Database. I don’t know which database management service i’ll be using. I might experiment with MongoDB Atlas.
There was several problem in this project:
- SPIFFS are very limited and could only support flat structure
- ESP32 Flash Memory only holds 4MB of data, for my perspective which heavily relies on CSS styling, it could support up to 3MB of CSS code minus SCSS code and several SVG images. I would like to use the URL Method to fetch an image.
- I have this peculiar problem which i really don’t know how to solve. Maybe i should put my ESP32 to quick deep sleep after a reboot? it works fine afterwards though.
The files used for this project can be downloaded from my github. Here’s the repository for this project.
Stay safe guys and be productive at home.
EDIT: June 7th, 2020
Guys, for the IFTTT and Google Sheets, i just found out that the service Only accepts at maximum of three different values. So yea, i cannot cheese my way out by relying on IFTTT for every single HTML Form to Google Sheets Integration.