Translate

Monitoring Kadar Gas Amonia (NH₃) Berbasis ESP32 IOT BLYNK

Monitoring Kadar Gas Amonia (NH₃) Berbasis ESP32 IOT BLYNK 
 
 
Berikut deskripsi alat dan sistem kerja yang sesuai dengan koding ESP32 Monitor Amonia menggunakan sensor MQ-137, OLED, dan Blynk.

Deskripsi Alat

Alat ini merupakan sistem monitoring kadar gas amonia (NH₃) berbasis ESP32 yang digunakan untuk mendeteksi dan memantau konsentrasi gas amonia di udara. Sensor utama yang digunakan adalah MQ-137, sedangkan ESP32 berfungsi sebagai pusat pengolah data.

Nilai hasil pembacaan sensor diproses menjadi nilai konsentrasi amonia dalam satuan ppm (parts per million). Hasil pengukuran kemudian ditampilkan secara langsung pada OLED SH1106 128 × 64 pixel dan dikirim melalui jaringan Wi-Fi ke aplikasi Blynk, sehingga pengguna dapat melakukan pemantauan secara lokal maupun melalui perangkat yang terhubung ke Blynk.

Sistem membagi kondisi kadar amonia menjadi tiga kategori, yaitu:

Kadar AmoniaStatus
< 10 ppm    AMAN
10 sampai < 30 ppm    WASPADA
≥ 30 ppm     BAHAYA

Komponen utama yang digunakan pada alat ini adalah ESP32, sensor MQ-137, OLED SH1106 I2C, jaringan Wi-Fi, dan platform Blynk IoT.

Sistem Kerja Alat

Saat alat dinyalakan, ESP32 melakukan inisialisasi terhadap sensor MQ-137, OLED, komunikasi I2C, komunikasi serial, jaringan Wi-Fi, dan koneksi ke server Blynk. OLED menggunakan komunikasi I2C melalui pin SDA GPIO 21 dan SCL GPIO 22, sedangkan output analog sensor MQ-137 dibaca ESP32 melalui GPIO 34.

Setelah sistem aktif, alat melakukan kalibrasi awal sensor. OLED menampilkan pesan “KALIBRASI SENSOR” dan “Jangan beri gas”. Program memberi waktu awal sekitar 5 detik sebelum proses pengambilan data kalibrasi dilakukan.

Selama proses kalibrasi, ESP32 membaca nilai resistansi sensor sebanyak 30 kali. Nilai tersebut kemudian dirata-ratakan untuk mendapatkan nilai R0 sebagai nilai referensi sensor pada kondisi udara awal atau kondisi tanpa paparan gas yang ingin diukur.

Pada proses pengukuran, ESP32 membaca keluaran analog MQ-137 sebanyak 50 kali dalam satu siklus. Pengambilan data berulang ini digunakan untuk mendapatkan nilai rata-rata ADC sehingga pembacaan lebih stabil.

Nilai ADC kemudian dikonversi menjadi tegangan menggunakan persamaan:

Selanjutnya program menghitung resistansi sensor Rs menggunakan:

dengan nilai RL = 500 yang telah ditentukan dalam program.

Setelah nilai Rs diperoleh, program membandingkannya dengan nilai R0 hasil kalibrasi. Jika nilai Rs lebih besar atau sama dengan R0, program menetapkan konsentrasi amonia sebesar 0 ppm.

Jika Rs lebih kecil dari R0, program menghitung perubahan resistansi menggunakan:

Kemudian nilai tersebut dikonversi menjadi ppm menggunakan persamaan dalam program:

Setelah mendapatkan nilai ppm, ESP32 menentukan status kondisi udara. Nilai di bawah 10 ppm dinyatakan AMAN, nilai 10 sampai kurang dari 30 ppm dinyatakan WASPADA, sedangkan nilai 30 ppm atau lebih dinyatakan BAHAYA.

Hasil pembacaan kemudian ditampilkan pada OLED dalam bentuk nilai konsentrasi amonia dan statusnya, misalnya:

MONITOR AMONIA

15.2 ppm

STATUS: WASPADA

ESP32 juga mengirimkan data ke aplikasi Blynk setiap 2 detik. Data yang dikirim terdiri dari:

Virtual Pin BlynkData
V0Nilai kadar amonia dalam ppm
V1Nilai resistansi sensor Rs
V2Status AMAN, WASPADA, atau BAHAYA

Dengan demikian, alur utama kerja alat adalah:

MQ-137 mendeteksi gas amonia → ESP32 membaca sinyal analog → menghitung Rs → membandingkan Rs dengan R0 → menghitung nilai ppm → menentukan status → menampilkan data pada OLED → mengirim data ke Blynk melalui Wi-Fi.

Catatan penting: rumus konversi ppm pada program ini menggunakan pendekatan persentase × 3. Jadi nilai ppm tersebut merupakan hasil pendekatan berdasarkan logika program, bukan kurva kalibrasi resmi MQ-137. Jika alat digunakan untuk pengukuran yang membutuhkan akurasi tinggi, sebaiknya kalibrasi dan persamaan ppm disesuaikan dengan datasheet sensor atau menggunakan gas referensi dengan konsentrasi yang diketahui.

 

1. Skema

 

2. Flowchart

 


3. Program Arduino IDE

 #define BLYNK_TEMPLATE_ID "TMPL6DEb3TXXX"
#define BLYNK_TEMPLATE_NAME "monitor amoniak"
#define BLYNK_AUTH_TOKEN "7bm6F-WExr0KU8pvXgTFZWh0w4hSjXXX"

#include <WiFi.h>
#include <BlynkSimpleEsp32.h>

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>

//================ WIFI =================

char ssid[] = "hotspothpku";
char pass[] = "1234567879";

//================ OLED =================
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_ADDR 0x3C

Adafruit_SH1106G display(
SCREEN_WIDTH,
SCREEN_HEIGHT,
&Wire,
-1
);

//================ MQ137 =================

#define MQ137_PIN 34

float RL = 500.0;

float R0 = 0;

BlynkTimer timer;

//=======================================
// BACA RS SENSOR
//=======================================

float bacaRs()
{

long total = 0;

for(int i=0;i<50;i++)
{

total += analogRead(MQ137_PIN);

delay(5);

}

float adc = total / 50.0;

float voltage = adc * 3.3 / 4095.0;

if(voltage <= 0)
{
return 0;
}

float Rs = ((5.0 / voltage)-1)* RL;

return Rs;

}

//=======================================
// AUTO KALIBRASI
//=======================================

void kalibrasiAwal()
{

display.clearDisplay();

display.setTextColor(
SH110X_WHITE);

display.setTextSize(1);

display.setCursor(10,10);

display.println("KALIBRASI SENSOR");

display.setCursor(10,30);

display.println("Jangan beri gas");

display.display();

delay(5000);

float total = 0;

for(int i=30;i>0;i--)
{

float Rs = bacaRs();

total += Rs;

display.clearDisplay();

display.setCursor(10,15);

display.println("Kalibrasi...");

display.setCursor(45,35);

display.print(i);

display.println(" s");

display.display();

delay(1000);

}

R0 =total / 30.0;

Serial.print("R0 = ");

Serial.println(R0);

}

//=======================================
// HITUNG PPM
//=======================================

float hitungPPM(float Rs)
{

if(Rs >= R0)
{

return 0;

}

float persen = ((R0-Rs)/R0)*100;

float ppm =
persen * 3;

return ppm;

}

//=======================================
// STATUS
//=======================================

String statusGas(float ppm)
{

if(ppm < 10)
{
return "AMAN";
}

else if(ppm < 30)
{
return "WASPADA";
}

else
{
return "BAHAYA";
}

}

//=======================================
// OLED
//=======================================

void tampilOLED(
float ppm,
String status
)
{

display.clearDisplay();

display.setTextColor(
SH110X_WHITE);

display.setTextSize(1);

display.setCursor(15,0);

display.println(
"MONITOR AMONIA");

display.drawLine(0,12,128,12,SH110X_WHITE);

display.setTextSize(2);

display.setCursor(5,25);

display.print(
ppm,1);

display.setTextSize(1);

display.print(
" ppm");

display.setCursor(0,55);

display.print(
"STATUS:");

display.print(
status);

display.display();

}

//=======================================
// UPDATE SENSOR
//=======================================

void kirimData()
{

float Rs =
bacaRs();

float ppm =
hitungPPM(Rs);

String status =
statusGas(ppm);

Serial.println("================");

Serial.print("R0 : ");
Serial.println(R0);

Serial.print("Rs : ");
Serial.println(Rs);

Serial.print("PPM : ");
Serial.println(ppm);

tampilOLED(
ppm,
status);

Blynk.virtualWrite(
V0,
ppm);

Blynk.virtualWrite(
V1,
Rs);

Blynk.virtualWrite(V2,status);

}

//=======================================
// SETUP
//=======================================

void setup()
{

Serial.begin(115200);

analogReadResolution(12);

pinMode(MQ137_PIN,INPUT);

Wire.begin(21,22);

display.begin(
OLED_ADDR,
true);

display.clearDisplay();

Blynk.begin(
BLYNK_AUTH_TOKEN,
ssid,
pass
);

// lakukan kalibrasi otomatis

kalibrasiAwal();

timer.setInterval(
2000,
kirimData
);

}

//=======================================
// LOOP
//=======================================

void loop()
{

Blynk.run();

timer.run();

}

 

4. VIDEO HASILNYA


JASA TUGAS AKHIR ELEKTRONIKA

JASA TUGAS AKHIR ELEKTRONIKA


Jasa Pembuatan Tugas Akhir Elektronika & Mikrokontroler

Bingung mengerjakan tugas akhir atau skripsi yang berhubungan dengan elektronika, mikrokontroler, IoT, robotika, dan sistem monitoring? Kami siap membantu Anda dari tahap perancangan, pembuatan alat, pemrograman, pengujian, hingga bimbingan dan penyelesaian proyek.

Kami melayani berbagai kebutuhan tugas akhir berbasis teknologi, baik untuk mahasiswa maupun pelajar, dengan sistem pengerjaan yang disesuaikan dengan kebutuhan dan tingkat kesulitan proyek.

Layanan yang Kami Sediakan

🔧 Pembuatan Alat Elektronika & Mikrokontroler

  • Arduino

  • ESP32 / ESP32-S3

  • Sensor dan aktuator

  • Sistem kontrol otomatis

  • Perancangan dan perakitan rangkaian

📡 IoT & Monitoring

  • Blynk

  • ThingSpeak

  • Firebase

  • Supabase

  • MQTT

  • Monitoring melalui smartphone dan website

  • Database dan grafik data realtime

📱 Aplikasi Android

  • MIT App Inventor

  • Android Studio

  • Aplikasi monitoring dan kontrol perangkat

  • Komunikasi Bluetooth dan Wi-Fi

🌐 Website & Database

  • PHP

  • MySQL

  • Supabase

  • Dashboard monitoring

  • Grafik realtime

  • Sistem login dan database

  • Hosting dan integrasi internet

🤖 Robotika & Sistem Otomatisasi

  • Robot Line Follower

  • Smart Car

  • Robot berbasis Arduino/ESP32

  • Sistem sensor dan kontrol motor

  • Proyek robotika lainnya

🧠 Artificial Intelligence (AI)

  • Deteksi objek

  • Pengenalan wajah

  • Kamera ESP32

  • Integrasi AI dengan mikrokontroler

  • Sistem monitoring berbasis AI

💻 Software Interface

  • Visual Basic 6

  • VB.NET

  • Delphi 7 dan versi terbaru

  • Interface PC untuk monitoring dan kontrol alat

🔌 Desain Elektronika & PCB

  • Perancangan skematik

  • Desain PCB

  • Pemilihan komponen

  • Dokumentasi rangkaian

  • Perakitan dan pengujian

Bimbingan Sampai Selesai

Tidak hanya pembuatan alat dan program. Kami juga menyediakan konsultasi dan bimbingan online untuk membantu memahami cara kerja alat, program, rangkaian, serta proses pengujian sehingga Anda lebih siap saat melakukan presentasi atau sidang.

Kenapa Memilih Kami?

✅ Pengerjaan disesuaikan dengan kebutuhan proyek
✅ Bisa konsultasi mengenai ide dan konsep alat
✅ Program dan rangkaian dapat dijelaskan
✅ Pengujian alat sebelum diserahkan
✅ Bimbingan online
✅ Support selama proses pengerjaan
✅ Harga menyesuaikan tingkat kesulitan proyek

Biaya mulai dari Rp500.000, tergantung jenis alat, jumlah komponen, tingkat kompleksitas, dan kebutuhan program.

Contoh Proyek

Beberapa proyek yang dapat kami bantu antara lain:

  • Monitoring suhu & kelembaban

  • Monitoring pH dan kekeruhan air

  • Sistem monitoring berbasis IoT

  • Robot Line Follower

  • Smart Car

  • Sistem kontrol Bluetooth/Wi-Fi

  • Aplikasi Android untuk kontrol ESP32

  • Website monitoring realtime

  • Drone / Quadcopter

  • Sistem otomatisasi

  • Proyek Arduino dan ESP32

  • Integrasi kamera dan AI

  • Berbagai proyek elektronika lainnya

Konsultasi & Pemesanan

Punya ide tugas akhir tetapi belum tahu mulai dari mana?

Konsultasikan ide dan kebutuhan proyek Anda terlebih dahulu.

📱 WhatsApp: 085726496643
▶️ YouTube: Project DIY Microcontroller
🎵 TikTok: @yanuarm3

Wujudkan ide tugas akhir Anda menjadi karya nyata!




Jasa Pembuatan Drone atau QUADCOPTER atau Drone FPV

Jasa Pembuatan Drone atau QUADCOPTER atau Drone FPV


JASA PEMBUATAN DRONE & QUADCOPTER KUSTOM 🚁💥

Punya kebutuhan kustomisasi drone, rakitan FPV, atau proyek riset mikrokontroler? Kami siap bantu dari nol sampai terbang!

🛠️ Layanan yang Kami Melayani:

  • Quadcopter Standar & Custom Frame (Frame F450, DIY, dll.)

  • Drone FPV (Racing, Freestyle, & Cinematic)

  • Integrasi Mikrokontroler (Arduino, ESP32, STM32, dll.)

  • Perakitan, Setting Flight Controller, & Tuning

  • Konsultasi & Service / Troubleshooting

Cocok untuk kebutuhan hobi, tugas akhir/riset kampus, hingga kebutuhan pemetaan/cinematic kustom.

📲 Minat / Konsultasi Gratis:

  • WhatsApp: 085726496643

  • TikTok: @yanuarm3

  • YouTube: Project diy microcontroller


VIDEO HASILNYA




JASA PEMBUATAN ALAT UNTUK TUGAS AKHIR / UMUM dan JASA PEMBUATAN PROGRAM / CODING

JASA PEMBUATAN ALAT UNTUK TUGAS AKHIR / UMUM  dan JASA PEMBUATAN PROGRAM / CODING


Sedang mengerjakan Tugas Akhir, Skripsi, Proyek, atau penelitian berbasis mikrokontroler dan IoT? Kami membantu dalam pembuatan program, perancangan alat, integrasi hardware-software, hingga bimbingan online sesuai kebutuhan proyek Anda.

🔧 SPESIALISASI:
• Arduino
• ESP32 & ESP32-S3
• Internet of Things (IoT)
• Website & Web Monitoring
• AI / Artificial Intelligence
• Bluetooth, WiFi & Internet
• Android MIT App Inventor
• Blynk, ThingSpeak & Firebase
• Website Hosting
• Data Logger & Monitoring
• Sistem Otomatisasi & Kontrol
• Software Interface VB6 / VB.NET / Delphi 7 & versi terbaru

💻 JASA CODING
Mulai dari Rp300.000, menyesuaikan tingkat kesulitan dan kebutuhan program.

🛠️ PEMBUATAN ALAT
Mulai dari Rp500.000 hingga > Rp2.000.000, menyesuaikan spesifikasi, komponen, fitur, dan tingkat kompleksitas alat.

📚 BIMBINGAN ONLINE
Membantu memahami coding, rangkaian, cara kerja sistem, troubleshooting, pengujian, dan pengembangan proyek sehingga proyek dapat dipahami dan dikembangkan sesuai kebutuhan.

💡 Konsultasikan terlebih dahulu!
Setiap proyek memiliki tingkat kesulitan dan kebutuhan komponen yang berbeda. Harga menyesuaikan kompleksitas dan spesifikasi proyek.

📱 PEMESANAN & KONSULTASI
WhatsApp: 0857-2649-6643

▶️ YouTube: Project DIY Microcontroller
🎵 TikTok: @yanuarm3

Melayani proyek mikrokontroler, IoT, monitoring, otomasi, interface komputer, aplikasi Android, hingga sistem berbasis Internet.










Kursus Private Robotika Area kota Batang - Pekalongan Jawa Tengah

Kursus Private Robotika Area kota Batang - Pekalongan Jawa Tengah

kursus private robotika
kelas SD SMP SMA dengan ketentuan yaitu
1. materi robotika dasar
2. materi elektronika dasar
3. materi bahasa pemrograman dasar Arduino
4. area murid di kota batang dan pekalongan
5. guru / tentor siap datang ke rumah murid 
6. waktu belajar 2 jam
7. biaya 500rb / 4 kali pertemuan

 minat hubungi WA 085726496643 (Yanuar) 

channel YOUTUBE = https://www.youtube.com/@DIYmicrocontroller

Channel TIKTOK = @yanuarm3 

  

 

Monitor Suhu & Kelembaban via Bluetooth ESP32 MIT INVENTOR dan Kendali LED

Monitor Suhu & Kelembaban via Bluetooth ESP32 MIT INVENTOR dan Kendali LED
 

       Pada kesempatan kali ini saya akan menjelaskan mengenai bagaimana cara membuat sebuah alat untuk monitor suhu kelembaban secara realtime dengan mnggunakan ESP32 via Bluetooth, aplikasi yang digunakan yaitu MIT Inventor dan koding juga sudah saya berikan pada page ini. untuk lebih jelasnya berikut detailnya.
 
 
1. Skema
 
 
 
2. Interface MIT INVENTOR
 


 
 
3. Program Arduino IDE
 
#include "DHT.h"
#include "BluetoothSerial.h"

#define DHTPIN 13
#define DHTTYPE DHT11

DHT dht(DHTPIN, DHTTYPE);

int LED_PIN = 12;
BluetoothSerial SerialBT;

void setup() {
  Serial.begin(115200);
  pinMode(LED_PIN,OUTPUT);
  dht.begin();

  SerialBT.begin("ESP32_SENSOR");
  
  Serial.println("Bluetooth aktif");
}

void loop() {

  int suhu = dht.readTemperature();
  int kelembaban = dht.readHumidity();

  if (isnan(suhu) || isnan(kelembaban)) {
    return;
  }

  String data = String(suhu) + "|" + String(kelembaban);

  SerialBT.println(data);
  Serial.println(data);

  if (SerialBT.available()) {

    char data = SerialBT.read();

    //Serial.print("Data diterima: ");
    //Serial.println(data);

    if (data == '1') {
      digitalWrite(LED_PIN, HIGH);
      //SerialBT.println("LED ON");
      Serial.println("LED ON");
    }

    else if (data == '0') {
      digitalWrite(LED_PIN, LOW);
      //SerialBT.println("LED OFF");
      Serial.println("LED OFF");
    }
  }


  delay(100);
}
 
 
4. VIDEO HASILNYA
 
 

Monitoring 2 Suhu via Website Hosting + Realtime Grafik DataLogger

Monitoring 2 Suhu via Website Hosting + Realtime Grafik DataLogger 
 

        Pada kesempatan kali ini saya akan menjelaskan mengenai bagaimana cara membuat sebuah alat yang daapaat memonitor 2 buah suhu secaraa terpisah tapi bisa dimasukkan ke dalam 1 website dan 1 database. untuk database saya menggunakan https://supabase.com dan untuk datamanager dan website saya menggunakan hosting dari infinityfree.com. untuk detailnya yaitu seperti berikut.
 
 
1. Skema
 

 
2. Interface
 




 
 
3. VIDEO HASILNYA
 

 
4. Program ESP32 - Batang / Semarang
 
 #include <WiFi.h>
#include <HTTPClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <time.h>

// ================= WIFI =================

const char* ssid = "wifihpku";
const char* password = "12345678";

// ================= SUPABASE =================

String supabaseURL =
"https://yizpzxixllbgixxxxxxx.supabase.co/rest/v1/suhu_data";

String supabaseKey =
"sb_publishable_mJNp2PCt9civsxe26URVYg_dxxxxxxx";

// ================= DEVICE =================

// ESP32 pertama

String device = "ESP32_BATANG";
String kota = "Batang";

// ESP32 kedua ubah menjadi:
// String device = "ESP32_SEMARANG";
// String kota = "Semarang";

// ================= DS18B20 =================

#define ONE_WIRE_BUS 13

OneWire oneWire(ONE_WIRE_BUS);

DallasTemperature sensors(&oneWire);

void setup(){

Serial.begin(115200);

sensors.begin();

// WIFI

WiFi.begin(ssid,password);

Serial.print("Connecting");

while(WiFi.status()!=WL_CONNECTED){

delay(500);

Serial.print(".");

}

Serial.println();

Serial.println("WiFi Connected");

// waktu WIB

configTime(
7*3600,
0,
"pool.ntp.org",
"time.nist.gov"
);

}

String getTime(){

struct tm timeinfo;

if(!getLocalTime(&timeinfo)){

return "NULL";

}

char waktu[30];

strftime(

waktu,

sizeof(waktu),

"%Y-%m-%d %H:%M:%S",

&timeinfo

);

return String(waktu);

}

void kirimSupabase(float suhu){

if(WiFi.status()==WL_CONNECTED){

HTTPClient http;

http.begin(supabaseURL);

http.addHeader(
"Content-Type",
"application/json"
);

http.addHeader(
"apikey",
supabaseKey
);

http.addHeader(
"Authorization",
"Bearer "+supabaseKey
);

String data = "{";

data += "\"device\":\""+device+"\",";

data += "\"kota\":\""+kota+"\",";

data += "\"suhu\":"+String(suhu)+",";

data += "\"waktu\":\""+getTime()+"\"";

data += "}";

Serial.println(data);

int code=http.POST(data);

Serial.print("Response Supabase : ");

Serial.println(code);

http.end();

}

}

void loop(){

sensors.requestTemperatures();

float suhu = sensors.getTempCByIndex(0);

if(suhu == -127){

Serial.println("Sensor DS18B20 tidak terbaca");

return;

}

Serial.print("Suhu ");

Serial.print(kota);

Serial.print(" : ");

Serial.println(suhu);

kirimSupabase(suhu);

delay(5000);

}
 
 
 
5. Api.php
 
<?php

$supabase_url = "https://yizpzxixllbgixxxxxxx.supabase.co/rest/v1/suhu_data";

$supabase_key = "sb_publishable_mJNp2PCt9civsxe26URVYg_dxxxxxxx";

$curl = curl_init();

curl_setopt_array($curl,[

CURLOPT_URL => $supabase_url."?select=*&order=id.desc&limit=100",

CURLOPT_RETURNTRANSFER => true,

CURLOPT_HTTPHEADER => [

"apikey: ".$supabase_key,

"Authorization: Bearer ".$supabase_key,

"Content-Type: application/json"

]

]);

$response = curl_exec($curl);

curl_close($curl);

header("Content-Type: application/json");

echo $response;

?> 
 
 
6. index.php
 
<!DOCTYPE html>
<html>

<head>

<title>Monitoring Suhu ESP32</title>

<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

<style>

*{
box-sizing:border-box;
}

body{

margin:0;
font-family:'Segoe UI',Arial,sans-serif;
background:#120021;
color:#ffd700;

}

.header{

background:linear-gradient(135deg,#5a189a,#240046);
padding:25px;
text-align:center;
box-shadow:0 5px 20px #000;

}

.header h1{

margin:0;
font-size:34px;

}

.header p{

color:#fff3a0;

}

.container{

width:92%;
margin:auto;

}

.map-box{

margin-top:25px;
background:#240046;
padding:25px;
border-radius:25px;
box-shadow:0 0 20px #000;
text-align:center;

}

.map-box h2{

color:#ffd700;

}

.peta{

width:90%;
max-width:1000px;
height:260px;
object-fit:cover;

border-radius:20px;

border:3px solid #7b2cbf;

}

.cards{

display:grid;
grid-template-columns:repeat(2,1fr);
gap:25px;

margin-top:25px;

}

.card{

background:#240046;
padding:25px;
border-radius:25px;
text-align:center;

box-shadow:0 0 20px #000;

}

.card h2{

color:#ffd700;

}

.nilai{

font-size:70px;
font-weight:bold;

color:#ffd700;

}

.status{

color:#00ff99;
font-weight:bold;

}

.panel{

background:#240046;
margin-top:25px;

padding:25px;

border-radius:25px;

box-shadow:0 0 20px #000;

}

.chart{

height:400px;

}

canvas{

width:100%!important;
height:100%!important;

}

table{

width:100%;
border-collapse:collapse;

}

th{

background:#5a189a;
color:#ffd700;

}

td,th{

padding:12px;
text-align:center;

border-bottom:1px solid #7b2cbf;

}

tr:hover{

background:#3c096c;

}

@media(max-width:700px){

.cards{

grid-template-columns:1fr;

}

}

</style>

</head>

<body>

<div class="header">

<h1>🌡 MONITORING SUHU ESP32</h1>

<p>DS18B20 Temperature Sensor</p>

</div>

<div class="container">

<!-- PETA -->

<div class="map-box">

<h2>🗺 PETA JAWA</h2>

<img src="jawa-map.png" class="peta">

</div>

<!-- NILAI SUHU -->

<div class="cards">

<div class="card">

<h2>📍 ESP32 BATANG</h2>

<div id="batang" class="nilai">

-- °C

</div>

<div class="status">

● ONLINE

</div>

</div>

<div class="card">

<h2>📍 ESP32 SEMARANG</h2>

<div id="semarang" class="nilai">

-- °C

</div>

<div class="status">

● ONLINE

</div>

</div>

</div>

<!-- GRAFIK -->

<div class="panel">

<h2>📈 Grafik Suhu Batang</h2>

<div class="chart">

<canvas id="grafikBatang"></canvas>

</div>

</div>

<div class="panel">

<h2>📈 Grafik Suhu Semarang</h2>

<div class="chart">

<canvas id="grafikSemarang"></canvas>

</div>

</div>

<!-- LOGGER -->

<div class="panel">

<h2>📋 Logger Data 100 Terakhir</h2>

<table>

<tr>

<th>No</th>
<th>Device</th>
<th>Kota</th>
<th>Suhu</th>
<th>Waktu</th>

</tr>

<tbody id="logger"></tbody>

</table>

</div>

</div>

<script>

let chartBatang;

let chartSemarang;

function loadData(){

fetch("api.php")

.then(res=>res.json())

.then(data=>{

let batang=[];

let semarang=[];

let waktuBatang=[];

let waktuSemarang=[];

let suhuBatang=0;

let suhuSemarang=0;

let idBatang=0;

let idSemarang=0;

data.slice().reverse().forEach(item=>{

if(item.device=="ESP32_BATANG"){

batang.push(Number(item.suhu));

waktuBatang.push(item.waktu);

if(Number(item.id)>idBatang){

idBatang=item.id;

suhuBatang=item.suhu;

}

}

if(item.device=="ESP32_SEMARANG"){

semarang.push(Number(item.suhu));

waktuSemarang.push(item.waktu);

if(Number(item.id)>idSemarang){

idSemarang=item.id;

suhuSemarang=item.suhu;

}

}

});

document.getElementById("batang").innerHTML =

Number(suhuBatang).toFixed(2)+" °C";

document.getElementById("semarang").innerHTML =

Number(suhuSemarang).toFixed(2)+" °C";

if(chartBatang){

chartBatang.destroy();

}

chartBatang=new Chart(

document.getElementById("grafikBatang"),

{

type:"line",

data:{

labels:waktuBatang,

datasets:[{

label:"ESP32 BATANG",

data:batang,

borderColor:"#ffd700",

backgroundColor:"rgba(255,215,0,0.2)",

fill:true,

tension:0.4,

borderWidth:3

}]

},

options:{

responsive:true,

maintainAspectRatio:false

}

}

);

if(chartSemarang){

chartSemarang.destroy();

}

chartSemarang=new Chart(

document.getElementById("grafikSemarang"),

{

type:"line",

data:{

labels:waktuSemarang,

datasets:[{

label:"ESP32 SEMARANG",

data:semarang,

borderColor:"#00ffff",

backgroundColor:"rgba(0,255,255,0.2)",

fill:true,

tension:0.4,

borderWidth:3

}]

},

options:{

responsive:true,

maintainAspectRatio:false

}

}

);

let html="";

data.forEach((item,index)=>{

html+=`

<tr>

<td>${index+1}</td>

<td>${item.device}</td>

<td>${item.kota}</td>

<td>${item.suhu} °C</td>

<td>${item.waktu}</td>

</tr>

`;

});

document.getElementById("logger").innerHTML=html;

});

}

loadData();

setInterval(loadData,5000);

</script>

</body>

</html>