Get to Know ESP32 #7: Web Server

Despite COVID-19, let’s be productive! Here’s how to make a simple web server — won’t spend more than 15 minutes :)

Audrey Betsy Rumapea
8 min readMar 23, 2020

Hi, been a while! A lot happened lately, especially this coronavirus — called COVID-19. My college has decided to help the government by making courses online, and here I am, in Jakarta. Yes, I know I shouldn’t have come home, but my parents worry a lot about my health in Bandung, because they’d be unable to check on my well being if I stayed there.

And that’s actually.. a constraint. As you may know (or not?), this weekly project is done by a group of three people, and my teammates, Hollyana and Cindy isn’t located near me. We are currently doing social distancing for ours and others’ health, so we decided that I, the one who has the tools, will do this project. Then, I’m gonna note important things, such as errors, the steps, video recordings of my project, and then I’ll send it to them. Oh, and of course, when I face any error, I’ll ask help from them to figure it out :)

Another backstory. I was pretty sure I brought my box where I put my tools, but it turned out that it was left in Bandung. I was shook *insert surprised Pikachu meme*, but thankfully someone who took care of my room in Bandung was able to find the tools and I asked her to send them via JNE. I used YES service which is a service that assured the package arrived next day. Fortunately, it really arrived next day. *exhales*

Okay, moving on to the project. This project is called web server, and in this project the web server is going to control outputs which are two LEDs. The web server can be accessed through any browser from devices — using IP address — inside the local network. e web server is mobile responsive and can be accessed with any device that as a browser on the local network.

Preparation

These are the hardware required to create this web server:

  • 1 NodeMCU ESP-32S development board with 30 pins (or any ESP32)
  • 1 USB-A to Micro-USB cable
  • 3 Male-to-Female wire jumpers
  • 1 Laptop with Arduino IDE installed and configured
  • 2 red LEDs
  • 2 330 Ohm resistors
  • 1 Breadboard

Circuit

Yea, now it’s time to get our hands dirty. Below is the schematic diagram for this project.

Source: randomnerdtutorials

Pay attention to the cathode and anode position. The bent one means it is longer, or called anode. The straight one is shorter, called cathode. The cathode is connected to resistor, and the anode is connected to a wire connecting breadboard and pins in ESP32. Also, don’t forget to connect the ground in breadboard to GND in ESP32.

Above, you can see some photos of my circuit. You can see that I have different resistors with different color bands. The story is actually quite funny, but we’ll discuss that in ‘Problems’ part at the end of this blog.

Code

/*********
Rui Santos
Complete project details at http://randomnerdtutorials.com
*********/
// Load Wi-Fi library
#include <WiFi.h>
// Replace with your network credentials
const char* ssid = "Mi Phone";
const char* password = "akugajah";
// 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("");
}
}

This code uses Wi-Fi library as shown below.

// Load Wi-Fi library
#include <WiFi.h>

I didn’t modify the code, but keep in mind that you have to change the SSID and password according to the Wi-Fi you’re using.

// Replace with your network credentials
const char* ssid = "Mi Phone";
const char* password = "akugajah";

Demonstration

As always, verify the code. If it’s sucessfully compiled, get your USB-A to Micro-USB cable and connect your ESP32 to your laptop. Press the BOOT button if necessary while it says ‘Connecting’.

Done uploading? Open the Serial Monitor from Tools>Serial Monitor or simply press Ctrl+Shift+M. Set the baud rate to 115200 baud.

It should look like this. If it doesn’t, try to press the EN / reset button. Pay attention, the IP address is actually ESP32’s IP address.

Next, open browser in laptop and paste the IP address.

How the Web Server looks like from my laptop.

In the Serial Monitor, you’re going to notice new lines.

Then, I try to open the IP address from my cellphone.

How the Web Server looks from my cellphone.
Lines that show up in my Serial Monitor the first time I open the web server.
When I try to turn on and off the LEDs from my cellphone.

Now, let’s see. Below is when I try to turn a LED off by using my cellphone, and turn the LED back on by using my laptop. You can see, there’s some differences. In my laptop, the User Agent is Chrome, Safari, AppleWebKit, Mozilla. Meanwhile, by using my cellphone, it detects User-Agent as Mi Mix 2S (my phone type!)

You can see my video of my project here.

Problems / Errors

There are some problems I encounter during this project.

  1. This showed up when I first uploaded the code. Solution: press the EN/Reset button.

2. I (thought I) didn’t have 2 330 Ohm resistors! I told my friends that we only have 1 330 Ohm resistor (based on the schematic diagram). We only try to find the same resistor with same colors as the schematic diagram, but it turned out that actually the blue one is also a 330 Ohm resistor. The difference is that it has 1% error tolerance while the brown one has 5% error tolerance. HAHA. Jokes on me.

3. At first, I couldn’t open the web server from my laptop, but I was able to open it from my cellphone. When I checked my Wi-Fi connection again in laptop, I just realized that I connected to a different local network. Lesson learned: Make sure you’re using the same local connection as the one in your code.

Okay, that’s the end of our project :) Don’t forget to wait for my project next week, and let’s hope this COVID-19 ends soon. Adios!

--

--

No responses yet