Quarantine and Chill with My ESP32 Web Server
Hi, it’s been a while since my last post. For this article, I decided to write in English.
As you might know, the whole world is experiencing from a global pandemic right now because of the novel coronavirus disease known as COVID-19. Here in Indonesia, cases of COVID-19 are spreading like wildfire. Schools and universities are being closed and we, students, are forced to study from home. Office workers are also advised to work from home.
Amidst this global pandemic, we as student are still obliged to study and do our assignments. Me and my friends (Xavier and Yumna) have to come up with a way for us to do our project without having to see each other. This week, the said project is to build an ESP32 Web Server from an article in randomnerdtutorials.com. Luckily, each of us have an ESP32 microcontroller, however the project also requires these parts:
- 2 LEDs
- Jumper wires
- Breadboard
- Resistor
- USB2.0/3.0 to MicroUSB cable
Unlucky me, unlike my two friends, I only have the ESP32 microcontroller and not the other parts. And so we three decided to the project remotely, with Xavier demonstrating the semantics and sharing his screen through video conference so me and Yumna could see the whole process. When we decided a day to do the conference, Yumna didn’t show up, leaving me and Xavier doing the conference for only the two of us.
Turns out Yumna was having fun binge watching movies and didn’t even bother to check her phone! I guess she had fun “quarantining” herself, LOL. She already did the project herself because she had all the parts required and she didn’t even tell me :(. I initially thought the one who has all the parts were only Xavier. And so I studied how the project works by myself and from Xavier’s demonstration. Note that photos in this article were documented by Yumna. Well, enough story time, now it’s time to go through the project.
Overview
The project is to build a web server to control two LEDs which are connected to GPIO26 and GPIO27 of the ESP32. The ESP32 web server is accessible by typing the ESP32 IP address on a browser in the local network. The state of each LED is changed by clicking the buttons on the web server, thus turning it on or off. The purpose of this project is to demonstrate building a web server which controls output, the idea later on is to replace the LEDs with other electronic devices.
Schematic
I have listed the parts required for this project. Now let’s go through building the circuit. Start by connecting the LEDs. In this demonstration, I’m using GPIO26 and GPIO27, but you can use any suitable GPIOs, really. Here’s a schematic diagram from randomnerdtutorials.com which guided me and will also probably make your life easier:
Code
After building the circuit, start by connecting your ESP32 to your desktop device. Note that in this article I will not go through the code in much detail. Run the Arduino IDE and copy these set of codes (also taken from randomnerdtutorials.com) :
/*********
Rui Santos
Complete project details at https://randomnerdtutorials.com
*********/
// Load Wi-Fi library
#include <WiFi.h>
// Replace with your network credentials
const char* ssid = "sushi";
const char* password = "sashimi23";
// Set web server port number to 80
WiFiServer server(80);
// Variable to store the HTTP request
String header;
// Auxiliar variables to store the current output state
String output26State = "off";
String output27State = "off";
// Assign output variables to GPIO pins
const int output26 = 26;
const int output27 = 27;
void setup() {
Serial.begin(115200);
// Initialize the output variables as outputs
pinMode(output26, OUTPUT);
pinMode(output27, OUTPUT);
// Set outputs to LOW
digitalWrite(output26, LOW);
digitalWrite(output27, LOW);
// Connect to Wi-Fi network with SSID and password
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
// Print local IP address and start web server
Serial.println("");
Serial.println("WiFi connected.");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
server.begin();
}
void loop(){
WiFiClient client = server.available(); // Listen for incoming clients
if (client) { // If a new client connects,
Serial.println("New Client."); // print a message out in the serial port
String currentLine = ""; // make a String to hold incoming data from the client
while (client.connected()) { // loop while the client's connected
if (client.available()) { // if there's bytes to read from the client,
char c = client.read(); // read a byte, then
Serial.write(c); // print it out the serial monitor
header += c;
if (c == '\n') { // if the byte is a newline character
// if the current line is blank, you got two newline characters in a row.
// that's the end of the client HTTP request, so send a response:
if (currentLine.length() == 0) {
// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
// and a content-type so the client knows what's coming, then a blank line:
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println("Connection: close");
client.println();
// turns the GPIOs on and off
if (header.indexOf("GET /26/on") >= 0) {
Serial.println("GPIO 26 on");
output26State = "on";
digitalWrite(output26, HIGH);
} else if (header.indexOf("GET /26/off") >= 0) {
Serial.println("GPIO 26 off");
output26State = "off";
digitalWrite(output26, LOW);
} else if (header.indexOf("GET /27/on") >= 0) {
Serial.println("GPIO 27 on");
output27State = "on";
digitalWrite(output27, HIGH);
} else if (header.indexOf("GET /27/off") >= 0) {
Serial.println("GPIO 27 off");
output27State = "off";
digitalWrite(output27, LOW);
}
// Display the HTML web page
client.println("<!DOCTYPE html><html>");
client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
client.println("<link rel=\"icon\" href=\"data:,\">");
// CSS to style the on/off buttons
// Feel free to change the background-color and font-size attributes to fit your preferences
client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
client.println(".button { background-color: #4CAF50; border: none; color: white; padding: 16px 40px;");
client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
client.println(".button2 {background-color: #555555;}</style></head>");
// Web Page Heading
client.println("<body><h1>ESP32 Web Server</h1>");
// Display current state, and ON/OFF buttons for GPIO 26
client.println("<p>GPIO 26 - State " + output26State + "</p>");
// If the output26State is off, it displays the ON button
if (output26State=="off") {
client.println("<p><a href=\"/26/on\"><button class=\"button\">ON</button></a></p>");
} else {
client.println("<p><a href=\"/26/off\"><button class=\"button button2\">OFF</button></a></p>");
}
// Display current state, and ON/OFF buttons for GPIO 27
client.println("<p>GPIO 27 - State " + output27State + "</p>");
// If the output27State is off, it displays the ON button
if (output27State=="off") {
client.println("<p><a href=\"/27/on\"><button class=\"button\">ON</button></a></p>");
} else {
client.println("<p><a href=\"/27/off\"><button class=\"button button2\">OFF</button></a></p>");
}
client.println("</body></html>");
// The HTTP response ends with another blank line
client.println();
// Break out of the while loop
break;
} else { // if you got a newline, then clear currentLine
currentLine = "";
}
} else if (c != '\r') { // if you got anything else but a carriage return character,
currentLine += c; // add it to the end of the currentLine
}
}
}
// Clear the header variable
header = "";
// Close the connection
client.stop();
Serial.println("Client disconnected.");
Serial.println("");
}
}
Now you might think that’s a long and complex code. But really, the part that makes it looks longer and harder to understand than it should, is the part to display HTML web page. In general, the code starts by including the WiFi library. Then, you need to insert an SSID and password of your network credentials (you can use your home WiFi or even your phone’s mobile hotspot) and set up the web server port to 80. The code also creates some variable to store the header of the HTTP request and to store the current state of the outputs (LEDs state). It also assign a GPIO to each of the LED outputs.
In the setup() code block, a serial communication is started, GPIOs OUTPUTs are defined and initially set to LOW (meaning your LEDs are off at the start of the program). Next, Wi-Fi connection is generated and its IP address is printed on the Serial Monitor.
In the loop() block code, things which occurs when a new client establishes a connection with the web server is programmed. Next, there are conditional statements which checks the buttons in the web page. Which are pressed and which are not. The code sets the LED state accordingly to the state of its button.
The last part is displaying the HTML web page, which is written with HTML code.
Uploading the code
Next, I uploaded the code to my ESP32 and open the Serial Monitor to check the IP address of my ESP32 in order to open the web server.
Now, let’s try and type in our ESP32 IP address in the web browser and try to switch on our LEDs.
When a client connects to the web server, you will see something like this on your Serial Monitor:
And I guess that’s all for this week’s project. I sure do hope this global pandemic will end soon. Stay healthy and hydrated folks!