#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <RTClib.h>
// Inisialisasi RTC DS3231
RTC_DS3231 rtc;
// Inisialisasi LCD 20x4 I2C
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Pengaturan untuk relay
const byte relayPins[4] = {5, 4, 3, 2}; // Pin untuk Relay 1, 2, 3, 4
// Pengaturan Keypad 4x4
const byte ROWS = 4; // 4 baris
const byte COLS = 4; // 4 kolom
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {13, 12, 11, 10}; // Pin yang terhubung ke baris keypad
byte colPins[COLS] = {9, 8, 7, 6}; // Pin yang terhubung ke kolom keypad
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// Variabel untuk menyimpan waktu ON dan OFF untuk masing-masing relay
byte onHour[4] = {18, 0, 0, 0}; // Waktu ON default
byte onMinute[4] = {0, 0, 0, 0}; // Menit ON default
byte offHour[4] = {23, 0, 0, 0}; // Waktu OFF default
byte offMinute[4] = {0, 0, 0, 0}; // Menit OFF default
// Variabel untuk mengontrol waktu RTC
unsigned long previousMillis = 0; // Variabel untuk menyimpan waktu sebelumnya
const long rtcInterval = 1000; // Interval waktu pembacaan RTC dalam milidetik (1 detik)
// Variabel untuk menyimpan waktu sekarang
byte currentHour = 0;
byte currentMinute = 0;
byte currentSecond = 0;
void setup() {
// Inisialisasi komunikasi serial
Serial.begin(9600);
// Inisialisasi RTC
if (!rtc.begin()) {
Serial.println(F("RTC tidak terdeteksi!"));
while (1);
}
// Ambil waktu awal dari RTC
DateTime now = rtc.now();
currentHour = now.hour();
currentMinute = now.minute();
currentSecond = now.second();
// Atur relay sebagai output dan matikan relay di awal
for (int i = 0; i < 4; i++) {
pinMode(relayPins[i], OUTPUT);
digitalWrite(relayPins[i], HIGH); // HIGH berarti relay mati (NO)
}
// Inisialisasi LCD
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print(F("Programmable Timer"));
delay(2000);
lcd.clear();
}
void loop() {
unsigned long currentMillis = millis();
// Update waktu dari RTC setiap interval
if (currentMillis - previousMillis >= rtcInterval) {
previousMillis = currentMillis;
// Update waktu dari RTC
DateTime now = rtc.now();
currentHour = now.hour();
currentMinute = now.minute();
currentSecond = now.second();
// Tampilkan waktu saat ini di LCD
lcd.setCursor(0, 0);
lcd.print(F("Time: "));
if (currentHour < 10) lcd.print('0');
lcd.print(currentHour);
lcd.print(':');
if (currentMinute < 10) lcd.print('0');
lcd.print(currentMinute);
lcd.print(':');
if (currentSecond < 10) lcd.print('0');
lcd.print(currentSecond);
// Tampilkan pengaturan waktu ON/OFF relay
for (int i = 0; i < 4; i++) {
lcd.setCursor(0, i + 1);
lcd.print(F("R"));
lcd.print(i + 1);
lcd.print(F(" ON "));
if (onHour[i] < 10) lcd.print('0');
lcd.print(onHour[i]);
lcd.print(':');
if (onMinute[i] < 10) lcd.print('0');
lcd.print(onMinute[i]);
lcd.print(F(" OFF "));
if (offHour[i] < 10) lcd.print('0');
lcd.print(offHour[i]);
lcd.print(':');
if (offMinute[i] < 10) lcd.print('0');
lcd.print(offMinute[i]);
}
}
// Cek apakah ada input dari keypad untuk mengubah waktu
char key = keypad.getKey();
if (key) {
if (key == 'A') {
setRelayTime(0); // Atur waktu Relay 1
} else if (key == 'B') {
setRelayTime(1); // Atur waktu Relay 2
} else if (key == 'C') {
setRelayTime(2); // Atur waktu Relay 3
} else if (key == 'D') {
setRelayTime(3); // Atur waktu Relay 4
}
}
// Cek apakah waktunya untuk menghidupkan/mematikan relay
for (int i = 0; i < 4; i++) {
// Jika waktu sekarang sama dengan waktu ON relay, nyalakan relay
if ((currentHour == onHour[i] && currentMinute == onMinute[i]) ||
(currentHour > onHour[i] && currentHour < offHour[i]) ||
(currentHour == offHour[i] && currentMinute < offMinute[i])) {
digitalWrite(relayPins[i], LOW); // Nyalakan relay
}
// Jika waktu sekarang sama dengan waktu OFF relay, matikan relay
if (currentHour == offHour[i] && currentMinute == offMinute[i]) {
digitalWrite(relayPins[i], HIGH); // Matikan relay
}
}
}
void setRelayTime(int relayIndex) {
// Fungsi untuk mengatur waktu ON/OFF relay melalui keypad
byte hour, minute;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Set ON Time R"));
lcd.print(relayIndex + 1);
lcd.setCursor(0, 1);
lcd.print(F("Hour: "));
hour = getNumberInput();
lcd.setCursor(0, 2);
lcd.print(F("Minute: "));
minute = getNumberInput();
onHour[relayIndex] = hour;
onMinute[relayIndex] = minute;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Set OFF Time R"));
lcd.print(relayIndex + 1);
lcd.setCursor(0, 1);
lcd.print(F("Hour: "));
hour = getNumberInput();
lcd.setCursor(0, 2);
lcd.print(F("Minute: "));
minute = getNumberInput();
offHour[relayIndex] = hour;
offMinute[relayIndex] = minute;
lcd.clear();
}
byte getNumberInput() {
// Fungsi untuk mendapatkan input angka dari keypad
byte num = 0;
char key;
while (true) {
key = keypad.getKey();
if (key >= '0' && key <= '9') {
num = num * 10 + (key - '0');
lcd.print(key);
} else if (key == '#') {
return num;
}
}
}