#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Alamat I2C dari LCD, bisa jadi 0x27 atau 0x3F
#define I2C_ADDR 0x27
#define LCD_COLUMNS 16
#define LCD_ROWS 2
// Inisialisasi LCD
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_ROWS);
// Variabel untuk menghitung waktu
unsigned long previousMillis = 0;
const long interval = 1000; // Interval 1 detik
// Atur waktu awal
int hours = 20;
int minutes = 36;
int seconds = 0;
// Atur tanggal awal
int day = 24;
int month = 5;
int year = 2024;
// Hari dalam seminggu
const char* daysOfWeek[] = {"Sab", "Min", "Sen", "Sel", "Rab", "Kam", "Jum"};
void setup() {
// Inisialisasi LCD
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print(" Jam Digital");
lcd.setCursor(0, 1);
lcd.print(" Buatan Royy");
delay(5000); // Tampilkan pesan selama 5 detik
lcd.clear();
displayTime(); // Tampilkan waktu awal
}
void loop() {
// Ambil waktu saat ini
unsigned long currentMillis = millis();
// Jika sudah 1 detik berlalu, update waktu
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
updateClock();
displayTime();
}
}
void updateClock() {
// Tambahkan 1 detik
seconds++;
// Jika detik mencapai 60, reset ke 0 dan tambah 1 menit
if (seconds >= 60) {
seconds = 0;
minutes++;
// Jika menit mencapai 60, reset ke 0 dan tambah 1 jam
if (minutes >= 60) {
minutes = 0;
hours++;
// Jika jam mencapai 24, reset ke 0 dan tambah 1 hari
if (hours >= 24) {
hours = 0;
day++;
// Cek jumlah hari dalam bulan
if ((month == 4 || month == 6 || month == 9 || month == 11) && day > 30 ||
(month == 2 && isLeapYear(year) && day > 29) ||
(month == 2 && !isLeapYear(year) && day > 28) ||
day > 31) {
day = 1;
month++;
// Jika bulan mencapai 13, reset ke 1 dan tambah 1 tahun
if (month > 12) {
month = 1;
year++;
}
}
}
}
}
}
bool isLeapYear(int year) {
// Fungsi untuk mengecek apakah tahun adalah tahun kabisat
return ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0));
}
void displayTime() {
// Format waktu dalam bentuk HH:MM:SS
char timeStr[9];
sprintf(timeStr, "%02d:%02d:%02d", hours, minutes, seconds);
// Tampilkan waktu di baris pertama LCD
lcd.setCursor(0, 0);
lcd.print("PUKUL:");
lcd.setCursor(7, 0);
lcd.print(timeStr);
// Format tanggal dalam bentuk DD-MM-YYYY
char dateStr[11];
sprintf(dateStr, "%02d-%02d-%04d", day, month, year);
// Tampilkan hari dan tanggal di baris kedua LCD
lcd.setCursor(0, 1);
lcd.print(daysOfWeek[dayOfWeek(day, month, year)]);
lcd.print(", ");
lcd.print(dateStr);
}
int dayOfWeek(int d, int m, int y) {
// Algoritma Zeller's Congruence untuk menghitung hari dalam seminggu
if (m < 3) {
m += 12;
y--;
}
int K = y % 100;
int J = y / 100;
int f = d + ((13 * (m + 1)) / 5) + K + (K / 4) + (J / 4) - (2 * J);
int dayOfWeek = (f % 7 + 7) % 7; // pastikan hasilnya positif
return dayOfWeek;
}