#include <RtcDS1307.h>
#include <ThreeWire.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Arduino.h>
enum Mode
{
CLOCK,
ALARM,
SET_DATE,
SET_TIME
};
Mode mode = CLOCK;
byte AlarmHour = 7;
byte AlarmMin = 0;
byte AlarmDay = 1;
byte AlarmMon = 1;
bool AlarmArmed = false;
bool IsRinging = false;
unsigned long previousMillis = 0;
const unsigned long debouncedelay = 50;
const long interval = 500;
int ModeCount = 0;
int Previous_AlarmHour = 0;
int Previous_AlarmMin = 0;
int Previous_AlarmDay = 0;
int Previous_AlarmMon = 0;
#define BTN_MODE 2
#define BTN_HOUR 3
#define BTN_MIN 4
#define RTC_CLK 6
#define RTC_DAT 7
#define RTC_RST 8
#define BUZZER 9
int LastState_Mode = 1;
int LastState_Hour = 1;
int LastState_Min = 1;
int ButtonState_Mode = 1;
int ButtonState_Hour = 1;
int ButtonState_Min = 1;
unsigned long LastDebounce_Mode = 1;
unsigned long LastDebounce_Hour = 1;
unsigned long LastDebounce_Min = 1;
LiquidCrystal_I2C lcd(0x27, 16, 2);
RtcDS1307<TwoWire> Rtc(Wire);
void SaveAlarm()
{
Rtc.SetMemory(1, 165);
Rtc.SetMemory(2, AlarmMin);
Rtc.SetMemory(3, AlarmHour);
Rtc.SetMemory(4, AlarmDay);
Rtc.SetMemory(5, AlarmMon);
Rtc.SetMemory(6, AlarmArmed);
}
void LoadAlarm()
{
if (Rtc.GetMemory(1) == 165)
{
AlarmHour = Rtc.GetMemory(3);
AlarmMin = Rtc.GetMemory(2);
AlarmDay = Rtc.GetMemory(4);
AlarmMon = Rtc.GetMemory(5);
AlarmArmed = Rtc.GetMemory(6);
}
}
void setup()
{
pinMode(BTN_MODE, INPUT_PULLUP);
pinMode(BTN_HOUR, INPUT_PULLUP);
pinMode(BTN_MIN, INPUT_PULLUP);
pinMode(BUZZER, OUTPUT);
lcd.init();
lcd.backlight();
Serial.begin(9600);
Rtc.Begin();
LoadAlarm();
Rtc.SetIsRunning(true);
RtcDateTime currentTime = RtcDateTime(__DATE__, __TIME__);
if (!Rtc.IsDateTimeValid() || Rtc.GetDateTime() < currentTime)
{
Rtc.SetDateTime(currentTime);
}
Serial.println("RTC Successfully Booted!");
Serial.println("------------------------");
}
void loop()
{
RtcDateTime now = Rtc.GetDateTime();
if (!now.IsValid())
{
Serial.println("RTC Wire Error! Check wires on pins A4,A5");
delay(1000);
return;
}
int Reading_Mode = digitalRead(BTN_MODE);
if (Reading_Mode != LastState_Mode)
{
LastDebounce_Mode = millis();
}
if ((millis() - LastDebounce_Mode) > debouncedelay)
{
if (Reading_Mode != ButtonState_Mode)
{
ButtonState_Mode = Reading_Mode;
if (ButtonState_Mode == 0)
{
if (IsRinging == true)
{
noTone(BUZZER);
IsRinging = false;
}
else
{
ModeCount++;
if (ModeCount > 3)
{
ModeCount = 0;
if (Previous_AlarmDay != AlarmDay || Previous_AlarmHour != AlarmHour || Previous_AlarmMin != AlarmMin || Previous_AlarmMon != AlarmMon)
{
AlarmArmed = true;
}
SaveAlarm();
}
if (ModeCount == 0)
{
mode = CLOCK;
}
if (ModeCount == 1)
{
mode = ALARM;
}
if (ModeCount == 2)
{
mode = SET_DATE;
if (!AlarmArmed)
{
AlarmDay = now.Day();
AlarmMon = now.Month();
}
Previous_AlarmDay = AlarmDay;
Previous_AlarmHour = AlarmHour;
Previous_AlarmMin = AlarmMin;
Previous_AlarmMon = AlarmMon;
}
if (ModeCount == 3)
{
mode = SET_TIME;
}
lcd.clear();
}
}
}
}
LastState_Mode = Reading_Mode;
int Reading_Hour = digitalRead(BTN_HOUR);
if (Reading_Hour != LastState_Hour)
{
LastDebounce_Hour = millis();
}
if ((millis() - LastDebounce_Hour) > debouncedelay)
{
if (Reading_Hour != ButtonState_Hour)
{
ButtonState_Hour = Reading_Hour;
if (ButtonState_Hour == 0)
{
if (IsRinging == true)
{
noTone(BUZZER);
IsRinging = false;
}
else
{
if (mode == ALARM)
{
AlarmArmed = true;
SaveAlarm();
}
if (mode == SET_DATE)
{
AlarmMon++;
}
if (AlarmMon > 12)
{
AlarmMon = 1;
}
if (mode == SET_TIME)
{
AlarmHour++;
}
if (AlarmHour > 23)
{
AlarmHour = 0;
}
}
}
}
}
LastState_Hour = Reading_Hour;
int Reading_Min = digitalRead(BTN_MIN);
if (Reading_Min != LastState_Min)
{
LastDebounce_Min = millis();
}
if ((millis() - LastDebounce_Min) > debouncedelay)
{
if (Reading_Min != ButtonState_Min)
{
ButtonState_Min = Reading_Min;
if (ButtonState_Min == 0)
{
if (IsRinging == true)
{
noTone(BUZZER);
IsRinging = false;
}
else
{
if (mode == ALARM)
{
AlarmArmed = false;
SaveAlarm();
}
if (mode == SET_DATE)
{
AlarmDay++;
}
if (AlarmDay > 31)
{
AlarmDay = 1;
}
if (mode == SET_TIME)
{
AlarmMin++;
}
if (AlarmMin > 59)
{
AlarmMin = 0;
}
}
}
}
}
LastState_Min = Reading_Min;
if (mode == CLOCK)
{
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval)
{
previousMillis = currentMillis;
Serial.print("Date: ");
if (now.Day() < 10)
Serial.print("0");
Serial.print(now.Day());
Serial.print("/");
if (now.Month() < 10)
Serial.print("0");
Serial.print(now.Month());
Serial.print("/");
Serial.print(now.Year());
Serial.print(" | ");
Serial.print("Time: ");
if (now.Hour() < 10)
Serial.print("0");
Serial.print(now.Hour());
Serial.print(":");
if (now.Minute() < 10)
Serial.print("0");
Serial.print(now.Minute());
Serial.print(":");
if (now.Second() < 10)
Serial.print("0");
Serial.println(now.Second());
lcd.setCursor(0, 0);
lcd.print("Date: ");
if (now.Day() < 10)
lcd.print("0");
lcd.print(now.Day());
lcd.print("/");
if (now.Month() < 10)
lcd.print("0");
lcd.print(now.Month());
lcd.print("/");
lcd.print(now.Year());
lcd.setCursor(0, 1);
lcd.print("Time: ");
if (now.Hour() < 10)
lcd.print("0");
lcd.print(now.Hour());
lcd.print(":");
if (now.Minute() < 10)
lcd.print("0");
lcd.print(now.Minute());
lcd.print(":");
if (now.Second() < 10)
lcd.print("0");
lcd.print(now.Second());
}
}
if (mode == ALARM)
{
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval)
{
previousMillis = currentMillis;
lcd.setCursor(0, 0);
lcd.print("Alarm ");
if (AlarmDay < 10)
{
lcd.print("0");
}
lcd.print(AlarmDay);
lcd.print("/");
if (AlarmMon < 10)
{
lcd.print("0");
}
lcd.print(AlarmMon);
lcd.setCursor(0, 1);
lcd.print("Time ");
if (AlarmHour < 10)
{
lcd.print("0");
}
lcd.print(AlarmHour);
lcd.print(":");
if (AlarmMin < 10)
{
lcd.print("0");
}
lcd.print(AlarmMin);
if (AlarmArmed == false)
{
lcd.print(" OFF");
}
else
{
lcd.print(" ON ");
}
}
}
if (mode == SET_DATE)
{
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval)
{
previousMillis = currentMillis;
lcd.setCursor(0, 0);
lcd.print("Month: ");
if (AlarmMon < 10)
{
lcd.print("0");
}
lcd.print(AlarmMon);
lcd.setCursor(0, 1);
lcd.print("Day: ");
if (AlarmDay < 10)
{
lcd.print("0");
}
lcd.print(AlarmDay);
}
}
if (mode == SET_TIME)
{
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval)
{
previousMillis = currentMillis;
lcd.setCursor(0, 0);
lcd.print("Hour: ");
if (AlarmHour < 10)
{
lcd.print("0");
}
lcd.print(AlarmHour);
lcd.setCursor(0, 1);
lcd.print("Minute: ");
if (AlarmMin < 10)
{
lcd.print("0");
}
lcd.print(AlarmMin);
}
}
if (now.Month() == AlarmMon && now.Day() == AlarmDay && now.Hour() == AlarmHour && now.Minute() == AlarmMin && AlarmArmed == true)
{
AlarmArmed = false;
tone(BUZZER, 300);
IsRinging = true;
SaveAlarm();
}
}