#8 ESP32 Web Server : Room Monitoring and Controlling System [Sistem Embedded]

Erensi Ratu Chelsia
8 min readApr 2, 2023

--

Holaa! Kembali lagi di project sistem embedded ku yang ke-8. Disini kita akan coba untuk buat webserver yang akan menggunakan sensor temperatur dan LED.

Kalau sebelumnya di project #4 kita pakai sensor temperatur yang hasilnya dapat kita lihat di serial monitor, kalau sekarang kita bisa lihat hasil dari pembacaan sensornya di web kita sendiri >_<

Nah, kalau yang menggunakan LED ini nantinya kita bisa menyalakan dan mematikan lampu LED dari web kita sendiri juga >_<

Oke,, sebelum mulai ke percobaannya kita siapkan dulu komponen yang dibutuhkan. Berikut komponen yang dibutuhkan.

Weather Station

Nah, sekarang kita coba yang menggunakan sensor temperatur dulu, disini aku pakai sensor BMP280.

~Rangkaian

rangkaian yang digunakan
  1. Hubungkan 3V3 di ESP32 dengan VCC di BMP280
  2. Hubungkan GND di ESP32 dengan GND di BMP280
  3. Hubungkan GPIO22 di ESP32 dengan SCL di BMP280
  4. Hubungkan GPIO21 di ESP32 dengan SDA di BMP280

~Kode Program

Setelah menyusun rangkaian, sekarang kita beranjak ke Arduino IDE nya. Berikut kode program yang aku gunakan.

// Load Wi-Fi library
#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)

#define SEALEVELPRESSURE_HPA (1013.25)

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 = "{uname_wifi}";
const char* password = "{password_wifi}";

// Set web server port number to 80
WiFiServer server(80);

// Variable to store the HTTP request
String header;

// 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 BME 280.\n");
Serial.print(" ID of 0x61 represents a BME 680.\n");
while (1) delay(10);
}
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. */

// 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();

// 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: #0043af; 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; }");

// Web Page Heading
client.println("</style></head><body><h1>ESP32 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(SEALEVELPRESSURE_HPA));
client.println(" m</span></td></tr>");
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("");
}
}

Setelah upload kode program, lihat di serial monitor karena akan ada IP Address. Lalu, salin IP Address dan tempel pada browser (disini aku pakai google chrome).

~Hasil

Nah, nantinya pada browser akan ditampilkan kondisi lingkungan dari pembacaan BMP280 berupa suhu, tekanan, dan ketinggian. Untuk bisa melihat hasil terkini yang ditampilkan pada browser kita perlu melakukan refresh terus menerus agar hasilnya ter-update.

Controlling Devices

Setelah kita melakukan percobaan dengan menampilkan hasil pada browser menggunakan BMP280, sekarang kita coba dengan menyalakan dan mematikan lampu LED dengan web browser >_<

~Rangkaian

rangkaian yang digunakan

Disini aku menghubungkan LED hijau dengan GPIO19 dan LED biru dengan GPIO18.

~Kode Program

Seperti biasa, setelah rangkaian selesai, kita lanjut ke Arduino IDE. Berikut kode program yang digunakan.

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

// Replace with your network credentials
const char* ssid = "AFI 3";
const char* password = "tubagus3";

// 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 output18State = "off";
String output19State = "off";

// Assign output variables to GPIO pins
const int output18 = 18;
const int output19 = 19;

// 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);
// Initialize the output variables as outputs
pinMode(output18, OUTPUT);
pinMode(output19, OUTPUT);
// Set outputs to LOW
digitalWrite(output18, LOW);
digitalWrite(output19, 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 /18/on") >= 0) {
Serial.println("GPIO 18 on");
output18State = "on";
digitalWrite(output18, HIGH);
} else if (header.indexOf("GET /18/off") >= 0) {
Serial.println("GPIO 18 off");
output18State = "off";
digitalWrite(output18, LOW);
} else if (header.indexOf("GET /19/on") >= 0) {
Serial.println("GPIO 19 on");
output19State = "on";
digitalWrite(output19, HIGH);
} else if (header.indexOf("GET /19/off") >= 0) {
Serial.println("GPIO 19 off");
output19State = "off";
digitalWrite(output19, 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 18
client.println("<p>GPIO 18 - State " + output18State + "</p>");
// If the output18State is off, it displays the ON button
if (output18State=="off") {
client.println("<p><a href=\"/18/on\"><button class=\"button\">ON</button></a></p>");
} else {
client.println("<p><a href=\"/18/off\"><button class=\"button button2\">OFF</button></a></p>");
}

// Display current state, and ON/OFF buttons for GPIO 19
client.println("<p>GPIO 19 - State " + output19State + "</p>");
// If the output19State is off, it displays the ON button
if (output19State=="off") {
client.println("<p><a href=\"/19/on\"><button class=\"button\">ON</button></a></p>");
} else {
client.println("<p><a href=\"/19/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("");
}
}

Sama seperti yang sebelumnya, setelah upload kode program, lihat di serial monitor karena akan ada IP Address. Lalu, salin IP Address dan tempel pada browser (disini aku pakai google chrome).

seperti ini contoh ip address yang akan ditampilkan pada serial monitor

~Hasil

Akan ditampilkan button off dan on pada browser yang digunakan untuk mematikan dan menghidupkan lampu LED.

~Sekian dan Terimakasih

Oke, karena sudah selesai percobaan web server kali ini, maka berakhir pula project #8. Sampai jumpa di project selanjutnya! >_<

--

--