Translate

Monitoring Suhu Kelembaban via Website Fitur Grafik dan Datalogger Realtime

Monitoring Suhu Kelembaban via Website Fitur Grafik dan Datalogger Realtime 
 

         Pada kesempatan kali ini saya akan menjelaskan mengenai bagaimana cara membuat sebuah alat untuk memonitoring suhu dan kelembaban dengan sensor DHT11 kemudian data tersebuut masuk ke database https://supabase.com setelah masuk ke dalam web itu untuk tampilannya saya gunakan https://www.infinityfree.com/ jadi saya gunakan 2 web itu karena jika saya gunakan infinityfree saja ada masalah saat pengiriman datanya. untuk lebih jelasnya berikut koding dan interfacenya.
 
 
1. Skema
 
 
 
2. Interface
 



 
3. Koding Arduino IDE
 
#include <WiFi.h>
#include <HTTPClient.h>
#include <DHT.h>

#define DHTPIN 13
#define DHTTYPE DHT11

DHT dht(DHTPIN, DHTTYPE);

// WIFI
const char* ssid = "wifihpku";
const char* password = "123456789";

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

String supabaseKey = "sb_publishable_mJNp2PCt9civsxe26URVYg_xxxxxxxx";

void setup() {

  Serial.begin(115200);

  dht.begin();

  WiFi.begin(ssid,password);

  Serial.print("Menghubungkan WiFi");

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

    delay(500);
    Serial.print(".");

  }

  Serial.println();
  Serial.println("WiFi Terhubung");

}

void loop() {

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

  if(isnan(suhu) || isnan(kelembaban)){

    Serial.println("Sensor gagal membaca");
    delay(1000);
    return;

  }

  Serial.print("Suhu : ");
  Serial.println(suhu);

  Serial.print("Kelembaban : ");
  Serial.println(kelembaban);

  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 json = 
    "{"
    "\"suhu\":" + String(suhu) +
    ",\"kelembaban\":" + String(kelembaban) +
    "}";

    Serial.println("Kirim:");
    Serial.println(json);
    int response = http.POST(json);

    Serial.print("Response: ");
    Serial.println(response);

    Serial.println(http.getString());

    http.end();

  }

  delay(1000);

}
 
 
4. Program index.html
 
<!DOCTYPE html>
<html>
<head>

<title>ESP32 DHT11 Monitoring</title>

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

<style>

*{
box-sizing:border-box;
}

body{
margin:0;
font-family:Arial,sans-serif;
background:#052e22;
color:white;
}

.header{
text-align:center;
padding:25px;
font-size:30px;
font-weight:bold;
}

.container{
width:92%;
margin:auto;
}


/* CARD */

.cards{

display:flex;
justify-content:center;
gap:25px;
flex-wrap:wrap;

}

.card{

background:#0b5139;
width:280px;
padding:25px;
border-radius:20px;
text-align:center;
box-shadow:0 5px 20px #0005;

}

.value{

font-size:45px;
font-weight:bold;
color:#00ff99;

}


/* BUTTON */

.btn-download{

background:#00a86b;
color:white;

border:none;

padding:12px 25px;

border-radius:25px;

font-size:16px;

cursor:pointer;

font-weight:bold;

margin-bottom:20px;

}

.btn-download:hover{

background:#00ff99;
color:#003b25;

}

/* CHART */

.chart-box{

background:#083b2b;

margin-top:25px;

padding:20px;

border-radius:20px;

cursor:pointer;

}

.chart-container{

height:230px;

}

.chart-container.fullscreen{

position:fixed;

top:20px;

left:20px;

right:20px;

bottom:20px;

height:auto;

background:#052e22;

z-index:999;

padding:30px;

border-radius:20px;

}

.chart-container canvas{

width:100%!important;

height:100%!important;

}

/* TABLE */

.table-box{

background:#083b2b;

margin-top:25px;

padding:20px;

border-radius:20px;

}

table{

width:100%;

border-collapse:collapse;

}

th{

background:#00a86b;

padding:14px;

}

td{

padding:12px;

text-align:center;

}

tr:nth-child(even){

background:#0b5139;

}

tr:nth-child(odd){

background:#06452f;

}

tr:hover{

background:#007f5f;

}

.badge-suhu{

background:#ff7b54;

padding:7px 15px;

border-radius:20px;

font-weight:bold;

}

.badge-hum{

background:#3498db;

padding:7px 15px;

border-radius:20px;

font-weight:bold;

}

</style>
</head>
<body>
<div class="header">

🌿 ESP32 DHT11 MONITORING

</div>

<div class="container">

<div class="cards">

<div class="card">

<h2>🌡 Suhu</h2>

<div class="value">

<span id="suhu">0</span> °C

</div>

</div>

<div class="card">

<h2>💧 Kelembaban</h2>

<div class="value">

<span id="kelembaban">0</span> %

</div>

</div>


</div>

<div class="chart-box">

<h2>📈 Grafik Suhu</h2>

<div class="chart-container"
onclick="besarGrafik(this)">

<canvas id="grafikSuhu"></canvas>

</div>

</div>

<div class="chart-box">

<h2>📈 Grafik Kelembaban</h2>

<div class="chart-container"
onclick="besarGrafik(this)">

<canvas id="grafikHum"></canvas>

</div>

</div>

<div class="table-box">

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

<button class="btn-download"
onclick="downloadExcel()">

📥 Download Excel

</button>

<table>

<thead>

<tr>

<th>No</th>

<th>Waktu</th>

<th>Suhu</th>

<th>Kelembaban</th>

</tr>

</thead>

<tbody id="tabel">

</tbody>

</table>

</div>

</div>

<script type="module">

import { createClient }

from "https://cdn.jsdelivr.net/npm/@supabase/supabase-js/+esm";

// SUPABASE

const SUPABASE_URL =
"https://yizpzxixllbgixxxxxxx.supabase.co";

const SUPABASE_KEY =
"sb_publishable_mJNp2PCt9civsxe26URVYg_xxxxxxxx";

const supabase =
createClient(
SUPABASE_URL,
SUPABASE_KEY
);

let chartSuhu;

let chartHum;

let dataExcel=[];

async function loadData(){

let {data,error}=await supabase

.from("dht11_data")

.select("*")

.order("id",{ascending:false})

.limit(100);

if(error){

console.log(error);

return;

}

dataExcel=data;

data=data.reverse();

let waktu=[];

let suhu=[];

let hum=[];

data.forEach(item=>{

waktu.push(

new Date(item.waktu)
.toLocaleTimeString()

);

suhu.push(item.suhu);

hum.push(item.kelembaban);

});

document.getElementById("suhu").innerHTML=

suhu[suhu.length-1] ?? 0;

document.getElementById("kelembaban").innerHTML=

hum[hum.length-1] ?? 0;

let isi="";

let no=1;

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

isi+=`

<tr>

<td>${no}</td>


<td>

${new Date(item.waktu).toLocaleString()}

</td>

<td>

<span class="badge-suhu">

${item.suhu} °C

</span>

</td>

<td>

<span class="badge-hum">

${item.kelembaban} %

</span>

</td>

</tr>

`;

no++;

});

document.getElementById("tabel").innerHTML=isi;

if(chartSuhu)

chartSuhu.destroy();

chartSuhu=new Chart(

document.getElementById("grafikSuhu"),

{

type:"line",

data:{

labels:waktu,

datasets:[{

label:"Suhu °C",

data:suhu,

borderColor:"#00ff99",

backgroundColor:
"rgba(0,255,153,.2)",

fill:true,

tension:.4

}]

},

options:{

responsive:true,

maintainAspectRatio:false

}

}

);

if(chartHum)

chartHum.destroy();

chartHum=new Chart(

document.getElementById("grafikHum"),

{

type:"line",

data:{

labels:waktu,

datasets:[{

label:"Kelembaban %",

data:hum,

borderColor:"#3498db",

backgroundColor:
"rgba(52,152,219,.2)",

fill:true,

tension:.4

}]

},

options:{

responsive:true,

maintainAspectRatio:false

}

}

);

}

window.besarGrafik=function(el){

el.classList.toggle("fullscreen");

}

window.downloadExcel=function(){

let csv="No,Waktu,Suhu,Kelembaban\n";

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

csv+=

`${index+1},${item.waktu},${item.suhu},${item.kelembaban}\n`;

});

let blob=new Blob(

[csv],

{
type:"text/csv"
}

);

let url=URL.createObjectURL(blob);

let a=document.createElement("a");

a.href=url;

a.download="logger_DHT11.csv";

a.click();

URL.revokeObjectURL(url);

}

setInterval(loadData,2000);

loadData();

</script>

</body>
</html> 
 
 
 
4. VIDEO HASILNYA
 

 
 
 
 
 
 

No comments:

Post a Comment