Weather Station Web Server : ESP32 + BMP280
ESP32 Project #9
Hello fellows!
Seperti project sebelumnya (here), kali ini aku buat lagi web server. Bedanya, kalau yang kemarin web-nya untuk mengendalikan LED, kali ini web-nya lebih pasif karena hanya akan digunakan untuk menampilkan hasil pembacaan sensor BMP280. Jadi, akan dibuat weather station di web tersebut. Dibandingkan project sebelumnya, project ini lebih simple, loh! Bahas langsung aja kali yaaa leggooo~
What You’ll Need
Komponen yang dibutuhkan untuk eksperimen kali ini sedikit banget, yaitu :
- 1 buah ESP32 Development Board
- 2 buah breadboard
- 1 helai kabel micro-USB
- 4 helai jumper wire male-to-male
- 1 buah sensor BMP280
- 1 buah smartphone (atau device lain yang bisa akses website)
Karena project ini memakai WiFi, tentu jangan lupa siapkan WiFi-nya juga ya! Seperti projects sebelumnya, referensi yang digunakan adalah Random Nerd Tutorials. Pada referensi ini digunakan sensor BME280 tetapi karena aku tidak punya, jadi aku pakai yang BMP280. Karena tujuannya membuat weather station, sebenarnya sensor apapun bisa dipakai, tinggal sesuaikan di code-nya aja nanti.
How It Will Look Like
Semua komponen di atas bakal dirangkai seperti skema di bawah ini :
Skema ini sederhana banget, cuma menghubungkan BMP280 ke ESP32. Pin VIN pada BMP280 dihubungkan ke pin 3V3 pada ESP32, pin GND di kedua device juga dihubungkan, kemudian pin SCL pada BMP280 dihubungkan ke GPIO 22, dan terakhir pin SDA dihubungkan ke GPIO 21.
The Magic Spell
Setelah membuat rangkaian, kita juga perlu membuat program untuk ESP32 di Arduino IDE. Code yang digunakan merupakan modifikasi dari code di Random Nerd Tutorials. Hasil modifikasinya :
// Load Wi-Fi library
#include <WiFi.h>
#include <Wire.h>
#include <Adafruit_BMP280.h>#define SEALEVELPRESSURE_HPA (1013.25)Adafruit_BMP280 bmp; // I2C// Replace with your network credentials
const char* ssid = "naadd";
const char* password = "croissant";// 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);
bool status;// default settings
// (you can also pass in a Wire library object like &Wire2)
//status = bmp.begin();
if (!bmp.begin(0x76)) {
Serial.println("Could not find a valid BMP280 sensor, check wiring!");
while (1);
}// 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 clientsif (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: Helvetica}");
client.println("table { border-collapse: collapse; margin-left:auto; margin-right:auto; }");
client.println("th { padding: 12px; background-color: #f50ca7; color: white; }");
client.println("tr { border: 1px solid #ddd; padding: 12px; }");
client.println("tr:hover { background-color: #ffe3fa; }");
client.println("td { border: none; padding: 12px; }");
client.println(".sensor { color:black; font-weight: bold; padding: 1px; }");
// Web Page Heading
client.println("</style></head><body><h1>Hello Fellows!</h1>");
client.println("</style></head><body><h3>Welcome to Nadya's Weather Station</h3>");
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>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("");
}
}
Modifikasi yang aku buat itu di lines yang aku bold, kalau dijabarin :
- SSID & Password. Sama seperti sebelumnya, bagian ini wajib kalian modifikasi supaya sesuai dengan SSID dan password WiFi yang akan digunakan.
- Library, variabel, setup(), dan loop() untuk BMP280. Karena di referensi menggunakan BME280, tentu harus diubah semua hal yang terkait sensor menjadi compatible dengan BMP280. Pertama adalah library yang jadi menggunakan <Adafruit_BMP280.h>. Kemudian nama variabel dan tipenya juga akan diubah supaya menjadi bmp dan BMP280. Setelah ini, replace semua “bme” dengan “bmp”. Kemudian pada loop(), hapus bagian readHumidity karena BMP280 tidak dapat membaca kelembaban udara. Aku juga menghapus bagian yang menampilkan suhu dalam satuan Fahrenheit karena suhu dalam Celcius sudah cukup.
- HTML & CSS. Modifikasi pada bagian ini opsional. Di sini aku modifikasi teks di web heading, kemudian tabelnya aku hapus rasio width-nya supaya tidak terlalu sempit. Aku juga mengubah font teks dan mengubah warna tabel, baik warna basic-nya hingga warna hover-nya. Style pada hover akan muncul ketika kursor kita melewati bagian yang dimaksud (yaitu pada kode ini table row) atau bila disentuh (jika diakses pada smartphone).
Let’s Get It!
Karena semua sudah siap, langsung aja terjun ke eksperimennya~ Video di bawah ini aku memperlihatkan proses eksperimen ini mulai dari merangkai komponen sampai ke eksekusinya. Jangan lupa nyalakan CC untuk melihat penjelasannya ya!
The Result & Lesson Learned
Berhasillll~~ Tetapi sebenarnya keberhasilan itu hasil dari proses percobaan yang sempat ada kendalanya. Kendala yang aku hadapi pada percobaan ini dan cara menanganinya :
- Can’t connect to ESP32. Jadi, saat upload code ke ESP32, entah kenapa can’t connect hingga time out. Walaupun aku udah coba cabut dan pasang kembali kabel micro-USB dan ganti port, ternyata masih time out juga. Akhirnya aku coba pencet tombol BOOT pada ESP32 untuk melakukan reset. Voila! Ternyata cara itu berhasil gaes~ ESP32 langsung bisa connect dan berfungsi dengan baik seperti pada video yeay!
- Can’t reach the site. Pada project sebelumnya, terjadi juga hal ini karena menggunakan WiFi rumah. Namun, kali ini aku udah pakai WiFi dari smartphone dan tetap tidak bisa. Ternyata aku baru sadar bahwa device yang aku gunakan untuk mengakses web masih terhubung ke WiFi yang berbeda, bukan ke WiFi dari smartphone. Karena ini web server ini sifatnya private, dia hanya bisa diakses oleh device yang terhubung ke jaringan yang sama.
Kendala pada project ini jauh lebih sedikit dibanding project sebelumnya karena basically, project ini menyatukan BMP280 dengan web server, yang keduanya sudah pernah dilakukan. Karena sudah paham cara kerjanya dan aspek-aspek yang harus diperhatikan, pengerjaan jadi lebih mudah dan lancar. Proses menangani kendala juga lebih cepat karena sudah lebih banyak pengalaman sehingga bisa menerka-nerka apa yang harus dilakukan. Karena itu, jangan menyerah dan tingkatkan jam terbang ya gais! Pasti lama-lama akan lebih menguasai bagaimana mengotak-atik ESP32 :) In the end, kesimpulannyaa..
Project 9 : Successful!
That’s all about Project #9! Semoga bisa menginspirasi dan membantu kalian yaa. Semangat terus main-main sama ESP32-nya, selamat mencoba, dan have fun! See you in the next project!
Adiós amigos!✨