#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define buzzerPin 8
#define modeButtonPin 6
#define selectButtonPin 7
#define led1Pin 9
#define led2Pin 10
LiquidCrystal_I2C lcd(0x27, 16, 2);
const unsigned long intervals[] = {
30UL * 1000UL, // Mode 1: 30 detik
60UL * 1000UL, // Mode 2: 1 menit
120UL * 1000UL // Mode 3: 2 menit
};
int mode = 0;
bool alarmActive = false;
bool timeExpired = false;
unsigned long previousMillis = 0;
unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 200;
// Untuk LED bergantian
unsigned long lastBlinkTime = 0;
bool ledState = false;
const unsigned long blinkInterval = 500; // 500 ms
void setup() {
pinMode(buzzerPin, OUTPUT);
pinMode(modeButtonPin, INPUT_PULLUP);
pinMode(selectButtonPin, INPUT_PULLUP);
pinMode(led1Pin, OUTPUT);
pinMode(led2Pin, OUTPUT);
lcd.begin(16, 2);
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Pilih Mode:");
showMode();
}
void loop() {
handleButtons();
if (alarmActive && !timeExpired) {
unsigned long currentMillis = millis();
unsigned long elapsed = currentMillis - previousMillis;
if (elapsed >= intervals[mode]) {
timeExpired = true;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("!!! MINUM OBAT");
lcd.setCursor(0, 1);
lcd.print("Tekan MODE...");
} else {
displayElapsedTime(elapsed);
digitalWrite(buzzerPin, LOW);
digitalWrite(led1Pin, LOW);
digitalWrite(led2Pin, LOW);
}
}
// Jika waktu habis, buzzer dan LED menyala bergantian
if (timeExpired) {
digitalWrite(buzzerPin, HIGH);
// LED berkedip bergantian setiap 500 ms
if (millis() - lastBlinkTime >= blinkInterval) {
lastBlinkTime = millis();
ledState = !ledState;
digitalWrite(led1Pin, ledState ? HIGH : LOW);
digitalWrite(led2Pin, ledState ? LOW : HIGH);
}
}
}
void handleButtons() {
if (digitalRead(modeButtonPin) == LOW && millis() - lastDebounceTime > debounceDelay) {
lastDebounceTime = millis();
if (timeExpired) {
// Reset alarm
digitalWrite(buzzerPin, LOW);
digitalWrite(led1Pin, LOW);
digitalWrite(led2Pin, LOW);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Obat diminum");
lcd.setCursor(0, 1);
lcd.print("Reset...");
delay(2000);
lcd.clear();
alarmActive = false;
timeExpired = false;
lcd.setCursor(0, 0);
lcd.print("Pilih Mode:");
showMode();
} else if (!alarmActive) {
// Ganti mode
mode = (mode + 1) % 3;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Pilih Mode:");
showMode();
}
}
if (digitalRead(selectButtonPin) == LOW && millis() - lastDebounceTime > debounceDelay && !alarmActive) {
alarmActive = true;
previousMillis = millis();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Mulai Mode ");
lcd.print(mode + 1);
delay(1000);
lcd.clear();
lastDebounceTime = millis();
}
}
void showMode() {
lcd.setCursor(0, 1);
switch (mode) {
case 0: lcd.print("Mode 1: 30 dtk "); break;
case 1: lcd.print("Mode 2: 1 menit"); break;
case 2: lcd.print("Mode 3: 2 menit"); break;
}
}
void displayElapsedTime(unsigned long elapsed) {
int totalSeconds = elapsed / 1000;
int hours = totalSeconds / 3600;
int minutes = (totalSeconds % 3600) / 60;
int seconds = totalSeconds % 60;
lcd.setCursor(0, 0);
lcd.print("Obat dlm ");
lcd.print(intervals[mode] / 60000UL);
lcd.print(" mnt");
lcd.setCursor(0, 1);
lcd.print("Jln: ");
if (hours < 10) lcd.print("0");
lcd.print(hours); lcd.print(":");
if (minutes < 10) lcd.print("0");
lcd.print(minutes); lcd.print(":");
if (seconds < 10) lcd.print("0");
lcd.print(seconds);
}