// כולל ספריות
#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
#include <Adafruit_NeoPixel.h>
// הגדרות Neopixel
#define NEOPIXEL_PIN 6
#define NUMPIXELS 16
#define BUTTON_PIN 2
Adafruit_NeoPixel strip(NUMPIXELS, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800);
// צבעים: כתום, צהוב, לבן, כחול
uint8_t colors[][3] = {
{255, 164, 61},
{241, 252, 119},
{255, 255, 255},
{139, 215, 252}
};
int fadeDelays[] = {300, 200, 100, 150};
LiquidCrystal_I2C lcd(0x27, 16, 2);
RTC_DS1307 rtc;
// לחצנים
#define BTN_SET 4
#define BTN_CONTROL 2
#define BTN_END 10
#define POT_PIN A1
int h = 0, m = 0, s = 0;
int alarmH = 7, alarmM = 0;
int wakeBefore = 1;
int setState = 0;
bool preWarmStarted = false;
bool lightSequenceStarted = false;
bool alarmWasSet = false;
unsigned long lastSettingTime = 0;
// לוגיקת שירים
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;
bool buttonPressed = false;
bool calmMode = false;
void setup() {
lcd.init();
lcd.backlight();
Serial.begin(9600);
pinMode(BTN_SET, INPUT_PULLUP);
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(BTN_CONTROL, INPUT_PULLUP);
pinMode(BTN_END, INPUT_PULLUP);
strip.begin();
strip.show();
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 blinkStartMin = alarmMin - wakeBefore;
int preWarmMin = blinkStartMin - 2;
// 🟢 לוגיקת שירים
if (!alarmTriggered && nowMin == alarmMin) {
alarmTriggered = true;
songStartTime = millis();
if (digitalRead(BTN_CONTROL) == LOW) calmMode = true;
}
if (alarmTriggered && !song1Started && millis() - songStartTime >= 10000) {
song1Started = true;
playSong(1);
}
if (currentSong == 1 && song1Started) {
if (digitalRead(BTN_CONTROL) == LOW && !buttonPressed) {
buttonPressed = true;
calmMode = true;
playSong(2);
} else if (millis() - songStartTime >= 10000) {
playSong(2);
}
}
if (currentSong == 2 && song2Started) {
if (digitalRead(BTN_CONTROL) == LOW && !buttonPressed) {
buttonPressed = true;
playSong(3);
} else if (millis() - songStartTime >= 10000) {
playSong(calmMode ? 3 : 4);
}
}
if ((currentSong == 3 || currentSong == 4) && (song3Started || song4Started)) {
if (digitalRead(BTN_END) == LOW) {
playSong(5);
}
}
if (digitalRead(BTN_CONTROL) == HIGH) buttonPressed = false;
// 🔆 תאורה הדרגתית לפני השכמה
if (!preWarmStarted && !lightSequenceStarted && alarmWasSet &&
(setState == 0 || setState == 4) &&
nowMin >= preWarmMin && nowMin < blinkStartMin &&
(millis() - lastSettingTime > 3000)) {
preWarmStarted = true;
Serial.println("🟠 Pre-warm light on");
uint8_t r = colors[0][0], g = colors[0][1], b = colors[0][2];
for (int i = 0; i < NUMPIXELS; i++) {
float factor = 0.5 + (float(i) / (NUMPIXELS - 1)) * 0.5;
strip.setPixelColor(i, strip.Color(r * factor, g * factor, b * factor));
strip.show();
delay(fadeDelays[0]);
}
}
if (!lightSequenceStarted && alarmWasSet &&
(setState == 0 || setState == 4) &&
nowMin == blinkStartMin) {
lightSequenceStarted = true;
Serial.println("🔔 Starting light sequence!");
startLightSequence();
}
// הגדרות
if (digitalRead(BTN_SET) == LOW) {
delay(200);
setState = (setState + 1) % 5;
}
int potValue = analogRead(POT_PIN);
if (setState == 1) { alarmH = map(potValue, 0, 1023, 0, 23); alarmWasSet = true; }
else if (setState == 2) { alarmM = map(potValue, 0, 1023, 0, 59); alarmWasSet = true; }
else if (setState == 3) { wakeBefore = map(potValue, 0, 1023, 0, 59); alarmWasSet = true; }
// LCD שורה עליונה
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 ");
}
updateClockDisplay();
delay(100);
}
void printTwoDigits(int number) {
if (number < 10) lcd.print("0");
lcd.print(number);
}
void updateClockDisplay() {
DateTime now = rtc.now();
h = now.hour(); m = now.minute(); s = now.second();
lcd.setCursor(0, 1);
lcd.print("Time ");
printTwoDigits(h); lcd.print(":");
printTwoDigits(m); lcd.print(":");
printTwoDigits(s);
lcd.print(" ");
}
void startLightSequence() {
uint8_t r = colors[0][0], g = colors[0][1], b = colors[0][2];
if (!blinkWithButton(r, g, b, 10000, 700)) blinkWithButton(r, g, b, 10000, 700);
for (int c = 1; c < 4; c++) {
uint8_t rr = colors[c][0], gg = colors[c][1], bb = colors[c][2];
strip.clear(); strip.show();
for (int i = 0; i < NUMPIXELS; i++) {
float factor = (c == 2) ? 1.0 : (0.5 + (float(i) / (NUMPIXELS - 1)) * 0.5);
strip.setPixelColor(i, strip.Color(rr * factor, gg * factor, bb * factor));
strip.show(); delay(fadeDelays[c]);
}
fillAllPixels(rr, gg, bb);
if (!waitForButtonOrTimeout(10000) && c < 3) {
strip.clear(); strip.show(); delay(500);
}
}
}
bool waitForButtonOrTimeout(unsigned long durationMs) {
unsigned long start = millis(), lastUpdate = 0;
while (millis() - start < durationMs) {
if (digitalRead(BUTTON_PIN) == LOW) { delay(200); return true; }
if (millis() - lastUpdate > 500) { updateClockDisplay(); lastUpdate = millis(); }
delay(20);
}
return false;
}
bool blinkWithButton(uint8_t r, uint8_t g, uint8_t b, unsigned long durationMs, int interval) {
unsigned long start = millis(), lastUpdate = 0;
bool on = true;
while (millis() - start < durationMs) {
if (digitalRead(BUTTON_PIN) == LOW) { delay(200); return true; }
if (on) fillAllPixels(r, g, b);
else { strip.clear(); strip.show(); }
if (millis() - lastUpdate > 500) { updateClockDisplay(); lastUpdate = millis(); }
on = !on; delay(interval);
}
return false;
}
void fillAllPixels(uint8_t r, uint8_t g, uint8_t b) {
for (int i = 0; i < NUMPIXELS; i++) {
strip.setPixelColor(i, strip.Color(r, g, b));
}
strip.show();
}
void playSong(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;
}
}