#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Tombol
const int pbOnOff = 2;
const int pbMode = 3;
const int pbUp = 4;
const int pbDown = 5;
// Relay pin
const int relayPins[4] = {6, 7, 8, 9};
// Waktu saat ini
int jam = 0;
int menit = 0;
int detik = 0;
// Waktu aktif relay (jam dan menit)
int relayHours[4] = {0, 0, 0, 0};
int relayMinutes[4] = {0, 0, 0, 0};
// Waktu aktif relay sebelumnya (untuk 1 menit nyala)
unsigned long lastActivated[4] = {0, 0, 0, 0};
bool relayOn[4] = {false, false, false, false};
// Mode pengaturan
int mode = 0; // 0 = normal, 1-8 = atur jam/menit relay 1-4
// Status global ON/OFF sistem
bool systemOn = true; // Status awal ON
// Waktu millis untuk detik
unsigned long previousMillis = 0;
void setup() {
Serial.begin(9600);
lcd.init();
lcd.backlight();
pinMode(pbOnOff, INPUT_PULLUP);
pinMode(pbMode, INPUT_PULLUP);
pinMode(pbUp, INPUT_PULLUP);
pinMode(pbDown, INPUT_PULLUP);
for (int i = 0; i < 4; i++) {
pinMode(relayPins[i], OUTPUT);
digitalWrite(relayPins[i], LOW);
}
lcd.setCursor(0, 0);
lcd.print("Jam = 00:00:00");
}
void loop() {
unsigned long currentMillis = millis();
// Update waktu tiap 1 detik
if (currentMillis - previousMillis >= 1000) {
previousMillis = currentMillis;
detik++;
if (detik >= 60) {
detik = 0;
menit++;
if (menit >= 60) {
menit = 0;
jam++;
if (jam >= 24) jam = 0;
}
}
}
// Tombol ON/OFF (PB1)
if (digitalRead(pbOnOff) == LOW) {
delay(200);
systemOn = !systemOn; // Toggle status ON/OFF
if (!systemOn) {
for (int i = 0; i < 4; i++) {
digitalWrite(relayPins[i], LOW); // Matikan semua relay
relayOn[i] = false; // Reset status
}
}
}
// Tombol mode (ubah hingga mode 11)
if (digitalRead(pbMode) == LOW) {
delay(200);
mode++;
if (mode > 11) mode = 0;
}
// Tombol UP
if (digitalRead(pbUp) == LOW) {
delay(200);
int idx = (mode - 1) / 2;
if (mode >= 1 && mode <= 8) {
if (mode % 2 == 1) {
relayHours[idx]++;
if (relayHours[idx] >= 24) relayHours[idx] = 0;
} else {
relayMinutes[idx]++;
if (relayMinutes[idx] >= 60) relayMinutes[idx] = 0;
}
} else if (mode == 9) {
jam++;
if (jam >= 24) jam = 0;
} else if (mode == 10) {
menit++;
if (menit >= 60) menit = 0;
} else if (mode == 11) {
detik++;
if (detik >= 60) detik = 0;
}
}
// Tombol DOWN
if (digitalRead(pbDown) == LOW) {
delay(200);
int idx = (mode - 1) / 2;
if (mode >= 1 && mode <= 8) {
if (mode % 2 == 1) {
relayHours[idx]--;
if (relayHours[idx] < 0) relayHours[idx] = 23;
} else {
relayMinutes[idx]--;
if (relayMinutes[idx] < 0) relayMinutes[idx] = 59;
}
}
}
// Cek waktu aktif relay jika sistem aktif
if (systemOn) {
for (int i = 0; i < 4; i++) {
if (jam == relayHours[i] && menit == relayMinutes[i] && detik == 0) {
digitalWrite(relayPins[i], HIGH);
relayOn[i] = true;
lastActivated[i] = currentMillis;
}
// Matikan relay setelah 1 menit
if (relayOn[i] && currentMillis - lastActivated[i] >= 60000) {
digitalWrite(relayPins[i], LOW);
relayOn[i] = false;
}
}
}
// Tampilkan waktu
lcd.setCursor(0, 0);
lcd.print("Jam = ");
if (jam < 10) lcd.print("0");
lcd.print(jam); lcd.print(":");
if (menit < 10) lcd.print("0");
lcd.print(menit); lcd.print(":");
if (detik < 10) lcd.print("0");
lcd.print(detik);
// Tampilkan waktu relay 1-4
lcd.setCursor(0, 1);
lcd.print("R1=");
if (relayHours[0] < 10) lcd.print("0");
lcd.print(relayHours[0]); lcd.print(":");
if (relayMinutes[0] < 10) lcd.print("0");
lcd.print(relayMinutes[0]);
lcd.setCursor(10, 1);
lcd.print("R2=");
if (relayHours[1] < 10) lcd.print("0");
lcd.print(relayHours[1]); lcd.print(":");
if (relayMinutes[1] < 10) lcd.print("0");
lcd.print(relayMinutes[1]);
lcd.setCursor(0, 2);
lcd.print("R3=");
if (relayHours[2] < 10) lcd.print("0");
lcd.print(relayHours[2]); lcd.print(":");
if (relayMinutes[2] < 10) lcd.print("0");
lcd.print(relayMinutes[2]);
lcd.setCursor(9, 2);
lcd.print(" R4=");
if (relayHours[3] < 10) lcd.print("0");
lcd.print(relayHours[3]); lcd.print(":");
if (relayMinutes[3] < 10) lcd.print("0");
lcd.print(relayMinutes[3]);
// Tampilkan mode dan status sistem
lcd.setCursor(0, 3);
if (mode == 0) {
lcd.print(" MAIN ");
} else {
int idx = (mode - 1) / 2;
if (mode % 2 == 1 && mode <= 8) {
lcd.print("Jam Relay "); lcd.print(idx + 1); lcd.print(" ");
} else if (mode % 2 == 0 && mode <= 8) {
lcd.print("Menit Relay"); lcd.print(idx + 1); lcd.print(" ");
} else if (mode == 9) {
lcd.print("SET JAM ");
} else if (mode == 10) {
lcd.print("SET MENIT ");
} else if (mode == 11) {
lcd.print("SET DETIK ");
}
}
lcd.setCursor(14, 3);
if (systemOn) {
lcd.print("ON ");
} else {
lcd.print("OFF");
}
}