#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
RTC_DS1307 rtc;
// לחצנים
#define BTN_SET 4
#define BTN_UP 3
#define BTN_DOWN 5
#define BTN_CONTROL 2
#define BTN_END 10
// זמן נוכחי
int h = 0, m = 0, s = 0;
// זמן השכמה
int alarmH = 7, alarmM = 0;
int wakeBefore = 0;
int setState = 0;
// ניהול לחיצה ארוכה
unsigned long lastActionTime = 0;
unsigned long repeatDelay = 400;
unsigned long repeatRate = 150;
// ניהול סאונדים
bool alarmTriggered = false;
bool song1Started = false;
bool song2Started = false;
bool song3Started = false;
bool song4Started = false;
bool song5Started = false;
int currentSong = 0;
unsigned long songStartTime = 0;
void setup() {
lcd.init();
lcd.backlight();
Serial.begin(9600);
pinMode(BTN_SET, INPUT_PULLUP);
pinMode(BTN_UP, INPUT_PULLUP);
pinMode(BTN_DOWN, INPUT_PULLUP);
pinMode(BTN_CONTROL, INPUT_PULLUP);
pinMode(BTN_END, INPUT_PULLUP);
rtc.begin();
if (!rtc.isrunning()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
}
void loop() {
DateTime now = rtc.now();
h = now.hour();
m = now.minute();
s = now.second();
int nowMin = h * 60 + m;
int alarmMin = alarmH * 60 + alarmM;
int startMin = alarmMin - wakeBefore;
// 1. זמן השכמה הגיע
if (!alarmTriggered && nowMin == alarmMin) {
alarmTriggered = true;
songStartTime = millis();
if (digitalRead(BTN_CONTROL) == LOW) {
startSong(1);
}
}
// 2. התחלה אוטומטית של שיר 1 אחרי 10 שניות אם לא נלחץ כפתור
if (alarmTriggered && !song1Started && millis() - songStartTime >= 10000) {
startSong(1);
}
// 3. מעבר משיר 1 לשיר 2
if (currentSong == 1 && song1Started) {
if (digitalRead(BTN_CONTROL) == LOW) {
startSong(2);
} else if (millis() - songStartTime >= 10000) {
startSong(2);
}
}
// 4. מעבר משיר 2 לשיר 3 או 4
if (currentSong == 2 && song2Started) {
if (digitalRead(BTN_CONTROL) == LOW) {
startSong(3);
} else if (millis() - songStartTime >= 10000) {
startSong(4);
}
}
// 5. שיר 3/4 – מעבר לשיר 5 עם כפתור סיום
if ((currentSong == 3 || currentSong == 4) && (song3Started || song4Started)) {
if (digitalRead(BTN_END) == LOW) {
startSong(5);
}
}
// תפריט הגדרות
if (digitalRead(BTN_SET) == LOW) {
delay(200);
setState++;
if (setState > 4) setState = 0;
}
if (setState == 1) {
updateWithHold(alarmH, 0, 23);
} else if (setState == 2) {
updateWithHold(alarmM, 0, 59);
} else if (setState == 3) {
updateWithHold(wakeBefore, 0, 59);
}
// LCD שורה 1
lcd.setCursor(0, 0);
if (setState == 0) {
lcd.print("Set alarm ");
} else if (setState == 1) {
lcd.print("Set hour: ");
printTwoDigits(alarmH); lcd.print(" ");
} else if (setState == 2) {
lcd.print("Set min: ");
printTwoDigits(alarmM); lcd.print(" ");
} else if (setState == 3) {
lcd.print("Set awake: ");
lcd.print(wakeBefore); lcd.print("m ");
} else if (setState == 4) {
lcd.print("Alarm ");
printTwoDigits(alarmH); lcd.print(":");
printTwoDigits(alarmM); lcd.print(", ");
lcd.print(wakeBefore); lcd.print("m ");
}
// LCD שורה 2 – שעה נוכחית
lcd.setCursor(0, 1);
lcd.print("Time ");
printTwoDigits(h); lcd.print(":");
printTwoDigits(m); lcd.print(":");
printTwoDigits(s);
lcd.print(" ");
delay(100);
}
// שינוי ערכים עם לחיצה ארוכה
void updateWithHold(int &value, int minVal, int maxVal) {
static bool wasUpHeld = false;
static bool wasDownHeld = false;
static unsigned long lastRepeatTime = 0;
if (digitalRead(BTN_UP) == LOW) {
if (!wasUpHeld) {
lastActionTime = millis();
value = (value + 1 > maxVal) ? minVal : value + 1;
wasUpHeld = true;
} else if (millis() - lastActionTime > repeatDelay && millis() - lastRepeatTime > repeatRate) {
value = (value + 1 > maxVal) ? minVal : value + 1;
lastRepeatTime = millis();
}
} else {
wasUpHeld = false;
}
if (digitalRead(BTN_DOWN) == LOW) {
if (!wasDownHeld) {
lastActionTime = millis();
value = (value - 1 < minVal) ? maxVal : value - 1;
wasDownHeld = true;
} else if (millis() - lastActionTime > repeatDelay && millis() - lastRepeatTime > repeatRate) {
value = (value - 1 < minVal) ? maxVal : value - 1;
lastRepeatTime = millis();
}
} else {
wasDownHeld = false;
}
}
// הדפסת מספר עם אפס מוביל
void printTwoDigits(int number) {
if (number < 10) lcd.print("0");
lcd.print(number);
}
// התחלת שיר
void startSong(int songNum) {
currentSong = songNum;
songStartTime = millis();
switch (songNum) {
case 1:
song1Started = true;
Serial.println("🎵 Play rustling leaves sound");
break;
case 2:
song2Started = true;
Serial.println("🎵 Play bird chirping sound");
break;
case 3:
song3Started = true;
Serial.println("🎵 Play harp sound melody");
break;
case 4:
song4Started = true;
Serial.println("🎵 Play beeping truck reverse sound");
break;
case 5:
song5Started = true;
Serial.println("🎵 Playing 'Happy' – motion detected");
break;
}
}