Tugas Akhir E32210601

This commit is contained in:
nicosaputra307 2024-07-17 07:27:48 +07:00
commit 692f297461
5 changed files with 685 additions and 0 deletions

View File

@ -0,0 +1,263 @@
#include <SPI.h>
#include <Wire.h>
#include "RTClib.h"
// INA226
#include <WiFi.h>
#include <HTTPClient.h>
#include <INA226_WE.h>
#define I2C_ADDRESS 0x40 //alamat I2C
// Config Wifi
const char *ssid = "KOSTR5"; //Nama Wifi
const char *password = "tanyapakjoko"; // pass wifi
INA226_WE ina226 = INA226_WE(I2C_ADDRESS);
//Global Variable
float shuntVoltage_mV = 0.0;
float loadVoltage_V = 0.0;
float busVoltage_V = 0.0;
float current_A = 0.0;
float power_mW = 0.0;
unsigned long previousMillis = 0; // variabel untuk menyimpan waktu terakhir pembaruan
const long interval = 10000; // interval waktu dalam milidetik
RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
const int RELAY_1 = 33;
const int RELAY_2 = 25;
const int RELAY_5 = 32;
int LDR_PIN_1 = 34;
int LDR_PIN_2 = 35;
int ldrValue1;
int ldrValue2;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Wire.begin();
ina226.init();
connectToWifi();
ina226.setResistorRange(0.075, 50.0); // choose resistor 5 mOhm and gain range up to 10 A
ina226.setCorrectionFactor(1.0);
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1)
;
}
rtc.adjust(DateTime(__DATE__, __TIME__));
pinMode(LDR_PIN_1, INPUT);
pinMode(LDR_PIN_2, INPUT);
pinMode(RELAY_1, OUTPUT);
pinMode(RELAY_2, OUTPUT);
pinMode(RELAY_5, OUTPUT);
digitalWrite(RELAY_1, HIGH);
digitalWrite(RELAY_2, HIGH);
digitalWrite(RELAY_5, HIGH);
delay(500);
}
void loop() {
DateTime now = rtc.now();
int hour = now.hour();
int minute = now.minute();
int second = now.second();
ldrValue1 = digitalRead(LDR_PIN_1);
ldrValue2 = digitalRead(LDR_PIN_2);
Serial.println(ldrValue1);
Serial.println(ldrValue2);
delay(100);
showTime();
Serial.println(minute);
// mengaktifkan alat relay suplai power
if (hour >= 7 && minute >= 0) {
digitalWrite(RELAY_1, LOW);
Serial.println("Relay 4 CH nyala");
delay(100);
}
//mematikan alat relay suplay power
if (hour >= 18 && minute > 0) {
digitalWrite(RELAY_1, HIGH);
Serial.println("Relay 4 CH mati");
delay(100);
}
//reset panel ke popsisi awal
if (hour == 17 && minute == 58 && second >= 0) {
digitalWrite(RELAY_2, LOW);
delay(10);
} else if (hour == 17 && minute == 58 && second >= 20) {
digitalWrite(RELAY_2, HIGH);
delay(10);
}
// Logika untuk relay 2 berdasarkan nilai LDR
if (ldrValue1 == 0) {
digitalWrite(RELAY_2, LOW);
Serial.println("nyala1");
delay(100);
} else {
digitalWrite(RELAY_2, HIGH);
Serial.println("mati1");
delay(100);
}
// Logika untuk relay 5 berdasarkan nilai LDR
if (ldrValue2 == 0) {
digitalWrite(RELAY_5, LOW);
Serial.println("nyala1");
delay(100);
} else {
digitalWrite(RELAY_5, HIGH);
Serial.println("mati1");
delay(100);
}
//Perluangan tiap 10 meniit sekali dengan waktu RTC
// if (minute % 10 == 0 && second == 0) {
// bacaSensor();
// Serial.println("Data terbaca");
// delay(1000);
// kirim_data();
// Serial.println("Data terkirim");
// }
// bacaSensor();
// Serial.println("Data terbaca");
// delay(1000);
// kirim_data();
// Serial.println("Data terkirim");
//Perluangan tiap 10 meniit sekali dan mengambil data dari jam 7-18 wib dengan waktu RTC
if (hour >= 7 && hour < 18) {
if (minute % 10 == 0 && second == 0) {
bacaSensor(); // Memanggil fungsi untuk membaca sensor
Serial.println("Data terbaca");
delay(1000);
kirim_data(); // Memanggil fungsi untuk mengirim data
Serial.println("Data terkirim");
}
} else {
Serial.println("Tidak mengirim data (18.00 - 07.00 WIB)");
}
}
void showTime() {
DateTime now = rtc.now();
Serial.print(now.hour(), DEC);
Serial.print(":");
if (now.minute() < 10) {
Serial.print("0");
}
Serial.print(now.minute(), DEC);
Serial.print(":");
if (now.second() < 10) {
Serial.print("0");
}
Serial.print(now.second(), DEC);
Serial.print(" ");
Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
Serial.print(" ");
Serial.print(now.day(), DEC);
Serial.print("-");
Serial.print(now.month(), DEC);
Serial.print("-");
Serial.println(now.year(), DEC);
}
void bacaSensor() {
ina226.readAndClearFlags();
shuntVoltage_mV = ina226.getShuntVoltage_mV();
busVoltage_V = ina226.getBusVoltage_V();
current_A = ina226.getCurrent_mA() /1000;
power_mW = ina226.getBusPower();
loadVoltage_V = busVoltage_V + (shuntVoltage_mV / 1000);
Serial.print("Shunt Voltage [mV]: ");
Serial.println(shuntVoltage_mV);
Serial.print("Bus Voltage [V]: ");
Serial.println(busVoltage_V);
Serial.print("Load Voltage [V]: ");
Serial.println(loadVoltage_V);
Serial.print("Current[A]: ");
Serial.println(current_A);
Serial.print("Bus Power [mW]: ");
Serial.println(power_mW);
if (!ina226.overflow) {
Serial.println("Values OK - no overflow");
} else {
Serial.println("Overflow! Choose higher current range");
}
Serial.println();
}
void kirim_data() {
int kelembaban = random(10, 20);
String postData = (String) "tegangan=" + loadVoltage_V + "&arus=" + current_A;
HTTPClient http;
http.begin("http://192.168.18.26/esp32_http/api2.php"); //mengirim ke database localhost melalui file api.php
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
auto httpCode = http.POST(postData);
String payload = http.getString();
Serial.println(postData);
Serial.println(payload);
http.end();
}
void connectToWifi() {
delay(1000);
WiFi.mode(WIFI_OFF);
delay(1000);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("");
Serial.print("Connecting");
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP()); //IP address assigned to your ESP
}

38
database.php Normal file
View File

@ -0,0 +1,38 @@
<?php
// database.php
$host = 'localhost';
$db = 'monitoringdaya';
$user = 'root';
$pass = '';
$charset = 'utf8mb4';
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
try {
$pdo = new PDO($dsn, $user, $pass, $options);
} catch (\PDOException $e) {
throw new \PDOException($e->getMessage(), (int)$e->getCode());
}
function getData($date = null) {
global $pdo;
$query = "SELECT tegangan, arus, waktu FROM sensor";
$params = [];
if ($date) {
$query .= " WHERE DATE(waktu) = ?";
$params = [$date];
}
$query .= " ORDER BY waktu";
$stmt = $pdo->prepare($query);
$stmt->execute($params);
return $stmt->fetchAll();
}

8
get_data.php Normal file
View File

@ -0,0 +1,8 @@
<?php
// get_data.php
require_once 'database.php';
$date = $_GET['date'] ?? null;
$data = getData($date);
echo json_encode($data);

204
index.php Normal file
View File

@ -0,0 +1,204 @@
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dashboard Monitoring Daya</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/moment@2.29.1/moment.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment@1.0.0/dist/chartjs-adapter-moment.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="content">
<header>
<div class="container">
<h1 class="title_h1">Dashboard Monitoring Daya</h1>
</div>
</header>
<div class="container">
<div class="dashboard">
<div id="dateFilter">
<!-- <label for="date">Pilih Tanggal:</label> -->
<input type="date" id="date">
<button class="btn" onclick="filterData()"><i class="bi bi-search"></i></button>
</div>
</div>
<div class="nama">
<div class="chart-nama">
<h1> Pengukuran Tegangan </h1>
</div>
</div>
<div class="dashboard-tegangan-arus">
<div class="chart-container">
<canvas id="voltageChart"></canvas>
</div>
</div>
<div class="nama">
<div class="chart-nama">
<h1> Pengukuran Arus </h1>
</div>
</div>
<div class="dashboard-tegangan-arus">
<div class="chart-container">
<canvas id="currentChart"></canvas>
</div>
</div>
</div>
<footer>
<div class="container">
<p class="copyright">&copy; 2024 Dashboard Monitoring Daya</p>
</div>
</footer>
</div>
<button id="scrollTopBtn" class="scroll-top-btn" onclick="scrollToTop()"> &#8679;</button>
<script>
document.addEventListener("DOMContentLoaded", function() {
// Mendapatkan elemen input tanggal
var tanggalInput = document.getElementById("date");
// Mendapatkan tanggal hari ini
var today = new Date();
var day = String(today.getDate()).padStart(2, '0');
var month = String(today.getMonth() + 1).padStart(2, '0'); // Januari adalah 0!
var year = today.getFullYear();
// Format YYYY-MM-DD
var todayFormatted = year + '-' + month + '-' + day;
// Mengatur nilai input tanggal ke hari ini
tanggalInput.value = todayFormatted;
filterData();
});
let voltageChart, currentChart;
function createCharts(data) {
const ctx1 = document.getElementById('voltageChart').getContext('2d');
const ctx2 = document.getElementById('currentChart').getContext('2d');
// Mendapatkan nilai minimum untuk tegangan dan arus dari data
const minVoltage = Math.min(...data.map(item => item.tegangan));
const minCurrent = Math.min(...data.map(item => item.arus));
// Tentukan nilai minimum yang akan digunakan
const minVoltageValue = Math.floor(minVoltage) - 2; // Dimulai dari nilai minimum tegangan dikurangi 2
const minCurrentValue = Math.floor(minCurrent) - 2; // Dimulai dari nilai minimum arus dikurangi 2
const chartOptions = {
responsive: true,
maintainAspectRatio: false,
scales: {
x: {
type: 'time',
time: {
unit: 'hour'
}
},
y: {
// Skala untuk tegangan (V)
voltage: {
beginAtZero: false,
suggestedMin: minVoltageValue
},
// Skala untuk arus (A)
current: {
beginAtZero: false,
suggestedMin: minCurrentValue
}
}
}
};
voltageChart = new Chart(ctx1, {
type: 'line',
data: {
labels: data.map(item => item.waktu),
datasets: [{
label: 'Tegangan (V)',
data: data.map(item => ({ x: item.waktu, y: item.tegangan })),
borderColor: '#1a237e',
backgroundColor: 'rgba(26, 35, 126, 0.1)',
tension: 0.1
}]
},
options: chartOptions
});
currentChart = new Chart(ctx2, {
type: 'line',
data: {
labels: data.map(item => item.waktu),
datasets: [{
label: 'Arus (A)',
data: data.map(item => ({ x: item.waktu, y: item.arus })),
borderColor: '#3949ab',
backgroundColor: 'rgba(57, 73, 171, 0.1)',
tension: 0.1
}]
},
options: chartOptions
});
}
function filterData() {
const date = document.getElementById('date').value;
fetch(`get_data.php?date=${date}`)
.then(response => response.json())
.then(data => {
if (voltageChart) voltageChart.destroy();
if (currentChart) currentChart.destroy();
createCharts(data);
});
}
// Inisialisasi grafik dengan semua data
setInterval(() => {
filterData();
}, 10000);
fetch('get_data.php')
.then(response => response.json())
.then(data => createCharts(data));
// Tampilkan tombol ketika pengguna scroll ke bawah 20px dari atas dokumen
window.onscroll = function() {
scrollFunction();
};
function scrollFunction() {
const scrollTopBtn = document.getElementById('scrollTopBtn');
if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
scrollTopBtn.style.display = 'block';
} else {
scrollTopBtn.style.display = 'none';
}
}
// Scroll ke atas halaman ketika tombol ditekan
function scrollToTop() {
document.body.scrollTop = 0; // Untuk Safari
document.documentElement.scrollTop = 0; // Untuk Chrome, Firefox, IE, dan Opera
}
</script>
</body>
</html>

172
style.css Normal file
View File

@ -0,0 +1,172 @@
html {
scroll-behavior: smooth; /* Membuat scroll lebih smooth */
}
body {
font-family: Arial, sans-serif;
margin: 0;
position: -webkit-sticky;
padding: 0;
background-color: #f0f0f0;
padding-bottom: 50px; /* Tambahkan padding bawah */
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 10px 20px;
}
header {
background-color: #1a237e;
color: white;
padding: 10px 0;
position: sticky;
/* position: -webkit-sticky; */
top: 0;
/* display: flex;
justify-content: space-between; */
/* align-items: center; */
}
.container .title_h1 {
text-align: left;
}
.navbar {
text-align: right;
}
.navbar ul {
list-style-type: none;
margin: 0;
padding: 0;
}
.navbar ul li {
display: inline-block;
margin-left: 15px;
}
.navbar ul li a {
color: white;
text-decoration: none;
padding: 10px 15px;
border-radius: 4px;
transition: background-color 0.3s;
}
.navbar ul li a:hover {
background-color: #3949ab;
}
h1 {
margin: 0;
font-size: 1.2em;
text-align: left;
}
.dashboard {
background-color: white;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
margin-top: 20px;
padding: 20px;
}
.dashboard-tegangan-arus {
background-color: white;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
padding: 20px;
}
.nama {
background-color: white;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
margin-top: 20px;
margin-bottom: 2px;
padding: 1px;
}
.chart-nama {
width: 70%;
height: 20px;
margin: 10px;
}
.nama h1 {
margin: 0;
font-size: 1.2em;
text-align: left;
color: #1a237e;
}
.chart-container {
width: 70%;
height: 300px;
margin: 20px auto;
}
#dateFilter {
/* margin-bottom: 7px; */
text-align: right;
margin-right: 10px;
}
#dateFilter input {
padding: 7px;
border-radius: 5px;
}
footer {
background-color: #1a237e;
color: white;
text-align: center;
padding: 5px 0;
position: fixed;
bottom: 0;
width: 100%;
}
.copyright {
font-size: 0.8em;
margin: 0;
}
.btn {
background-color: #1a237e;
color: white;
border: none;
padding: 8px 15px;
border-radius: 4px;
cursor: pointer;
font-size: 0.9em;
}
.btn:hover {
background-color: #3949ab;
}
.scroll-top-btn {
display: none;
position: fixed;
bottom: 55px;
right: 20px;
background-color: #1e2ab1;
color: white;
border: none;
padding: 10px;
border-radius: 25%; /* Changed to a circle */
cursor: pointer;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
font-size: 18px;
z-index: 1000;
}
.scroll-top-btn:hover {
background-color: #2f3986;
transition: background-color 0.3s;
}