ESP32 Challenge #8: Wi-Fi Communication (Web Server)

Gisela Ivenita
10 min readMar 28, 2021

--

Haloo! Selamat datang di challenge ke-8. Ikutin terus sampe akhir ya, karena challenge kali ini bakalan seru banget!

Pada challenge sebelumnya, kita sudah menggunakan Short Range Communication Protocol dari ESP32, yaitu Bluetooth. Nah, kali ini kita akan menggunakan Mid Range Communication Protocol, yaitu Wi-Fi. Di sini kita akan membuat sebuah web server ESP32 untuk menyalakan dan mematikan 2 buah LED. Seru banget, kan?

Daripada menunggu terlalu lama, langsung kita mulai aja, yuk!

DAFTAR KOMPONEN DAN PERANGKAT

Komponen dan perangkat yang harus disiapkan sebagai berikut:

  1. ESP32 Development Board (disini aku menggunakan ESP32 DOIT DEVKIT V1)
  2. Breadboard
  3. LED
  4. Resistor 330 Ohm
  5. Kabel male to male (bisa disesuaikan)
  6. Micro USB Cable
  7. Laptop/komputer yang terdapat aplikasi Arduino IDE (sudah terinstall package board ESP32)
  8. Wi-Fi

DIAGRAM SKEMA

Langsung aja kalian rangkai komponen dan perangkat sebelumnya seperti pada skema berikut:

Gambar 1. Skema Rangkaian

Silahkan hubungkan GPIO 26 (D26) ESP32 dengan kutub positif (anoda) LED berwarna hijau dan GPIO 27 (D27) ESP32 dihubungkan dengan kutub positif (anoda) LED berwarna merah. Untuk masing-masing kutub negatif (katoda) LED dihubungkan dengan resistor 330 Ohm. Untuk setiap resistor 330 Ohm dihubungkan dengan kutub negatif breadboard. Lalu, kutub negatif breadboard dihubungkan dengan GND ESP32. Micro USB Cable menghubungkan ESP32 Development Board dengan laptop yang terdapat aplikasi Arduino IDE.

KODE PROGRAM

Kode program yang kita gunakan sebagai berikut, tetapi SSID dan password silahkan sesuaikan dengan nama Wi-Fi dan password Wi-Fi kalian, yaa!

/*********
Rui Santos
Complete project details at http://randomnerdtutorials.com
*********/

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

// 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 output26State = "off";
String output27State = "off";

// Assign output variables to GPIO pins
const int output26 = 26;
const int output27 = 27;

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

Keterangan program:

#include <WiFi.h>

Pada bagian awal program, kita harus meng-include library Wi-Fi.

// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

Nah, pada bagian ini, silahkan ganti SSID dengan nama Wi-Fi kalian dan password dengan password Wi-Fi kalian. Jangan sampai typo, yaa!

WiFiServer server(80);

Lalu, set port number web server 80. Nah, 80 ini merupakan default dari port HTTP .

String header;

Lalu, deklarasi variabel header dengan tipe String untuk menyimpan HTTP request.

String output26State = "off";
String output27State = "off";

Nah, variabel output26State dan output27State untuk menyimpan status output saat ini. Pada awal, kita set “off”.

const int output26 = 26;
const int output27 = 27;

Kita buat variabel output26 dengan nilai integer konstan sebesar 26, dan variabel output27 dengan nilai integer konstan sebesar 27. Dalam hal ini, nilai 26 dan 27 adalah pin GPIO yang berfungsi sebagai output.

unsigned long currentTime = millis();

Nah, disini ada fungsi millis yang dapat menjalankan program secara multitasking sehingga tidak menghentikan proses keseluruhan arduino.

unsigned long previousTime = 0; 

const long timeoutTime = 2000;

Lalu diinisialisasi previousTime dengan nilai 0 dan timeoutTime dengan nilai 2000 ms (2 s).

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

Kemudian, pada bagian setup, kita akan menghubungkan dengan serial monitor sehingga perlu diaktifkan menggunakan Serial.begin dan kecepatannya sebesar 115200 baud. Lalu, terdapat instruksi pinMode yang menentukan output26 dan output27 sebagai output. Kemudian, kita buat output26 dan output27 mati terlebih dahulu dengan membuatnya menjadi LOW. Setelah itu, terdapat instruksi untuk connect dengan Wi-Fi sesuai dengan SSID dan password. Jika Wi-Fi sudah terhubung, akan ditampilkan local IP Address dan web server akan mulai dijalankan.

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

Pada bagian loop, program akan mengecek apakah ada client yang connect. Jika ada client yang connect, maka pada serial monitor akan muncul pesan “New Client”. Kemudian, jika client menekan tombol ON sesuai pin GPIO, maka LED yang terhubung dengan GPIO tersebut akan menyala. Sebaliknya, jika client menekan tombol OFF sesuai pin GPIO, maka LED yang terhubung dengan GPIO tersebut akan mati. Selanjutnya, dibuat tampilan HTML web pagenya sesuai kode program di atas.

EKSPERIMEN DAN DEMO

Setelah rangkaian dan kode program telah siap, silahkan pilih verify dan compile pada aplikasi Arduino IDE. Jangan lupa pastikan bahwa Wi-Fi kalian sudah menyala yaa.

Kemudian, jika sudah terhubung, tekan tombol EN pada ESP32 Development Board. Silahkan buka Serial Monitor dengan mengecek Tools > Serial Monitor pada aplikasi Arduino IDE. Pada layar serial monitor, akan muncul IP Address.

Nah, silahkan copy IP Address tersebut pada device yang juga terhubung dengan Wi-Fi yang sama. Maka, akan muncul ESP32 Web Server.

Gambar 2. ESP32 Web Server

Pada layar serial monitor akan diberi tahu jika ada client baru yang join.

Gambar 3. New Client

Silahkan tekan tombol ON dan/atau OFF yang tersedia pada web server. Kalian bisa menyalakan dan mematikan LED melalui web server tersebut.

Gambar 4. Tombol ON/OFF LED

DOKUMENTASI

Gambar 5. Dokumentasi Eksperimen

Pada saat kita menyalakan dan mematikan LED melalui web server, pada serial monitor juga akan muncul GPIO yang terhubung ke LED yang dinyalakan/dimatikan.

Gambar 6. Layar Serial Monitor saat Menyalakan/Mematikan LED

HASIL EKSPERIMEN DAN ANALISIS

Eksperimen dapat berjalan dengan lancar. Namun, yang perlu diperhatikan adalah masukan SSID dan password pada kode program harus sesuai dengan Wi-Fi yang digunakan. Selain itu, web browser yang digunakan juga harus web browser pada device yang terhubung dengan Wi-Fi yang sama. Nah, dengan menggunakan web server ini kita dapat mengontrol benda-benda tertentu dengan jarak yang lebih jauh dibanding Bluetooth asalkan terhubung dengan Wi-Fi yang sama, sehingga jauh lebih efisien, bukan?

Challenge kali ini sudah selesai. Seru banget, kan? Sampai jumpa di challenge berikutnyaa!

--

--

No responses yet