Project 8 : ESP32 Web Server — Room Monitoring and Controlling System

Gresya Leman
7 min readMar 31, 2022

Hello everyone! Welcome back to the eigth chapter of me trying to learn how to use ESP32. In this chapter I’ll show you how I experimented with web servers of ESP32 and also the WiFi feature by making a room monitoring and controlling system.

My lecturer challenged us to make a room monitoring and controlling system by utilizing web server and WiFi feature of ESP32. The criteria of the system is that the ESP32 is equipped with a temperature sensor in a room and connected by WiFi, the ESP32 should be connected with a fan (modeled by an LED light), the information should be accessed remotely using internet browser (on a PC or mobile phone), and the user can turn on / turn off the ‘fan’ remotely using internet browser.

Necessary Components

ESP32+Breadboard (1 each) — Here I used a longer breadboard, feel free adjust it to your needs
Micro USB Cable (1 pcs)
Laptop/PC (1 pcs)
BMP280 Sensor Module (1pcs)
5mm LED Light (1pcs)
330 Ohm Resistor (1pcs)
Male-to-Male Jumper Cables (6 pcs)

A little note, make sure to have a stable WiFi connection near you when doing this project, because otherwise, it won’t work.

Arrangements made on the breadboard

Make sure the ESP32 is secured on the breadboard. Then attach one LED light on the breadboard, attach a 330 ohm resistor on the negative leg and connect it to the GND pin on the ESP32 using a jumper cable. On the positive leg, connect it to GPIO 23 on the ESP32. Then attach the BMP280 sensor on the board and connect it as the table below using jumper cables.

Where to connect from BMP280 sensor to ESP32

Here’s how my finished circuit looked like.

My final arrangement on the breadboard

Code the program

After the arrangements in the circuit is completed, open the Arduino IDE. Make a new file then save it, and then copy and paste the code below.

#include <Wire.h>
#include <WiFi.h>
#include <SPI.h>
#include <Adafruit_BMP280.h>
#define BMP_SCK (13)
#define BMP_MISO (12)
#define BMP_MOSI (11)
#define BMP_CS (10)
Adafruit_BMP280 bmp; // I2C
//Adafruit_BMP280 bmp(BMP_CS); // hardware SPI
//Adafruit_BMP280 bmp(BMP_CS, BMP_MOSI, BMP_MISO, BMP_SCK);
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// 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 outputState = "off";
// Assign output variables to GPIO pins
const int output = 23;
// Current time
unsigned long currentTime = millis();
// Previous time
unsigned long previousTime = 0;
// Define timeout time in milliseconds (example: 2000ms = 2s)
const long timeoutTime = 2000;
void setup() {
Serial.begin(115200);
while ( !Serial ) delay(100); // wait for native usb
Serial.println(F("BMP280 test"));
unsigned status;
//status = bmp.begin(BMP280_ADDRESS_ALT, BMP280_CHIPID);
status = bmp.begin(0x76);
if (!status) {
Serial.println(F("Could not find a valid BMP280 sensor, check wiring or "
"try a different address!"));
Serial.print("SensorID was: 0x"); Serial.println(bmp.sensorID(),16);
Serial.print(" ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n");
Serial.print(" ID of 0x56-0x58 represents a BMP 280,\n");
Serial.print(" ID of 0x60 represents a BMP 280.\n");
Serial.print(" ID of 0x61 represents a BMP 680.\n");
while (1) delay(10);
}
/* Default settings from datasheet. */
bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */
Adafruit_BMP280::SAMPLING_X2, /* Temp. oversampling */
Adafruit_BMP280::SAMPLING_X16, /* Pressure oversampling */
Adafruit_BMP280::FILTER_X16, /* Filtering. */
Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */

// Initialize the output variables as outputs
pinMode(output, OUTPUT);
// Set outputs to LOW
digitalWrite(output, 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,
currentTime = millis();
previousTime = currentTime;
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() && currentTime - previousTime <= timeoutTime) { // loop while the client's connected
currentTime = millis();
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 /23/on") >= 0) {
Serial.println("GPIO 23 on");
outputState = "on";
digitalWrite(output, HIGH);
} else if (header.indexOf("GET /23/off") >= 0) {
Serial.println("GPIO 23 off");
outputState = "off";
digitalWrite(output, 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 table
client.println("<style>body { text-align: center; font-family: \"Trebuchet MS\", Arial;}");
client.println("table { border-collapse: collapse; width:35%; margin-left:auto; margin-right:auto; }");
client.println("th { padding: 12px; background-color: #00ffd9; color: white; }");
client.println("tr { border: 1px solid #ddd; padding: 12px; }");
client.println("tr:hover { background-color: #bcbcbc; }");
client.println("td { border: none; padding: 12px; }");
client.println(".sensor { color:white; font-weight: bold; background-color: #bcbcbc; padding: 1px; }");
// CSS to style the on/off buttons
client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
client.println(".button { background-color: #00ffd9; border: none; color: white; padding: 16px 40px;");
client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
client.println(".button2 {background-color: #ff0000;}</style></head>");

// Web Page Heading
client.println("</style></head><body><h1>Proj8 : ESP32 Web Server with BMP280</h1>");
client.println("<table><tr><th>MEASUREMENT</th><th>VALUE</th></tr>");
client.println("<tr><td>Temp. Celsius</td><td><span class=\"sensor\">");
client.println(bmp.readTemperature());
client.println(" *C</span></td></tr>");
client.println("<tr><td>Temp. Fahrenheit</td><td><span class=\"sensor\">");
client.println(1.8 * bmp.readTemperature() + 32);
client.println(" *F</span></td></tr>");
client.println("<tr><td>Pressure</td><td><span class=\"sensor\">");
client.println(bmp.readPressure() / 100.0F);
client.println(" hPa</span></td></tr>");
client.println("<tr><td>Approx. Altitude</td><td><span class=\"sensor\">");
client.println(bmp.readAltitude(1013.25));
client.println(" m</span></td></tr>");
// Display current state, and ON/OFF buttons for GPIO 23
client.println("<p>Fan State " + outputState + "</p>");
if (outputState=="off") {
client.println("<p><a href=\"/23/on\"><button class=\"button\">ON</button></a></p>");
} else {
client.println("<p><a href=\"/23/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("");
}
}

Make sure to change the ssid and password according to the WiFi you’re using.

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

Compile the code and wait until it says ‘Done compiling’.

Before uploading the code, don’t forget to make sure that the ESP32 is connected. Also make sure the Arduino IDE is set on the right board and port on the Tools menu.

Then click on the right arrow icon next to the tick icon to upload the code to the ESP32 and wait until it’s done uploading.

After it’s done uploading, go to Tools > Serial Monitor

A new window should pop up and it should look like the picture below. If the message don’t show up, press the EN button on the ESP32 to restart the ESP32.

Copy and paste the IP address to any internet browser you have to access the web server that has been made. The result should show as the following picture.

To turn on the LED light (a replacement for the fan), click on the blue ON button. When it’s clicked, the blue ON button will turn into a red OFF button. Click on the red OFF button to turn the LED light off.

Here’s a video on how my experiment turned out.

I faced a little problem when doing this experiment. When I thought I did everything correctly, the ESP32 couldn’t detect my BMP280 sensor. I checked the wiring but it was connected to the right pins. So I tried making the web server without the BMP280 sensor, and then I faced another problem, my LED light won’t turn on. I tried changing the LED light but it didn’t work, so I changed my jumper cable and soon the LED light turned on. It turned out that my jumper cable was broken :(. So then I tried it again but the ESP32 still couldn’t detect my BMP280. I tried changing it to my spare BMP280 sensor and it worked. Turned out my sensor was broken too :(. But in the end I succeeded in this experiment, and I’m pretty happy on how it turned out.

This is the end of the tutorial and I hope this helps!

--

--