#include <Wire.h>
#include <I2C_RTC.h> //use lib by Manjunath CV in lib manager
#include <LiquidCrystal_I2C.h>
static DS3231 RTC; //Variable and component declaration
LiquidCrystal_I2C lcd(0x27, 16, 2);
const int relayPin = 2;
const int dtbuttonPin = 3;
const int cdbuttonPin = 4;
const int addSecBTPin = 5;
const int subtSecBTPin = 6;
const int addMinBTPin = 7;
const int subtMinBTPin = 8;
const int addHrBTPin = 9;
const int subtHrBTPin = 10;
const int addDayBTPin = 11;
const int subtDayBTPin = 12;
unsigned long startTime = 0;
const unsigned long duration = 10000;
unsigned long lastDiscardTime = 0;
const unsigned long discardInterval = 10000;
unsigned long CDGoal = 0;
unsigned long CDNow = 0;
unsigned long CDTick = 0;
unsigned long CDSeconds = 0;
unsigned long CDMinutes = 0;
unsigned long CDHours = 0;
void setup() { //Setup and initialization
Serial.begin(9600);
RTC.begin();
lcd.init();
pinMode(relayPin, OUTPUT);
pinMode(dtbuttonPin, INPUT);
pinMode(cdbuttonPin, INPUT);
RTC.setHourMode(CLOCK_H24);
}
void CDGoalSet() {
if (RTC.getWeek() == 6) { //Friday Countdown Goal Setting
if (RTC.getHours() < 8 && RTC.getHours() >= 0) {
CDGoal = 28800;
}
if (RTC.getHours() == 8 && RTC.getMinutes() < 10) { //To set 8:10
CDGoal = 29400;
}
if (RTC.getHours() == 8 && RTC.getMinutes() >= 10) { //To set 9am
CDGoal = 32400;
}
if (RTC.getHours() == 9 && RTC.getMinutes() < 50) { //To set 9:50
CDGoal = 35400;
}
if (RTC.getHours() == 9 && RTC.getMinutes() >= 50|| //To set 10:10
RTC.getHours() == 10 && RTC.getMinutes() < 10) {
CDGoal = 36600;
}
if (RTC.getHours() == 10 && RTC.getMinutes() >= 10) { //To set 11am
CDGoal = 39600;
}
if (RTC.getHours() == 11 && RTC.getMinutes() < 50) { //To set 11:50
CDGoal = 42600;
}
if (RTC.getHours() == 11 && RTC.getMinutes() >= 50|| //To set 12:50
RTC.getHours() == 12 && RTC.getMinutes() < 50) {
CDGoal = 46200;
}
if (RTC.getHours() == 12 && RTC.getMinutes() >= 50|| //To set 1:40
RTC.getHours() == 13 && RTC.getMinutes() < 40){
CDGoal = 49200;
}
if (RTC.getHours() == 13 && RTC.getMinutes() >= 40|| //To set 2:30
RTC.getHours() == 14 && RTC.getMinutes() < 30){
CDGoal = 52200;
}
if (RTC.getHours() == 14 && RTC.getMinutes() >= 30){ //To set 3pm
CDGoal = 54000;
}
if (RTC.getHours() >= 15 && RTC.getMinutes() <= 24) {
CDGoal = 0;
}
}
if (RTC.getWeek() >= 2 && RTC.getWeek() < 6 ) { /* To set 8am */ //Monday-Thursday Countdown Goal Setting
if (RTC.getHours() < 8 && RTC.getHours() >= 0) {
CDGoal = 28800;
}
if (RTC.getHours() == 8 && RTC.getMinutes() < 10) { //To set 8:10
CDGoal = 29400;
}
if (RTC.getHours() == 8 && RTC.getMinutes() >= 10) { //To set 9am
CDGoal = 32400;
}
if (RTC.getHours() == 9 && RTC.getMinutes() < 50) { //To set 9:50
CDGoal = 35400;
}
if (RTC.getHours() == 9 && RTC.getMinutes() >= 50|| //To set 10:10
RTC.getHours() == 10 && RTC.getMinutes() < 10) {
CDGoal = 36600;
}
if (RTC.getHours() == 10 && RTC.getMinutes() >= 10) { //To set 11am
CDGoal = 39600;
}
if (RTC.getHours() == 11 && RTC.getMinutes() < 50) { //To set 11:50
CDGoal = 42600;
}
if (RTC.getHours() == 11 && RTC.getMinutes() >= 50|| //To set 12:50
RTC.getHours() == 12 && RTC.getMinutes() < 50) {
CDGoal = 46200;
}
if (RTC.getHours() == 12 && RTC.getMinutes() >= 50|| //To set 1:40
RTC.getHours() == 13 && RTC.getMinutes() < 40){
CDGoal = 49200;
}
if (RTC.getHours() == 13 && RTC.getMinutes() >= 40|| //To set 2:30
RTC.getHours() == 14 && RTC.getMinutes() < 30){
CDGoal = 52200;
}
if (RTC.getHours() == 14 && RTC.getMinutes() >= 30){ //To set 3pm
CDGoal = 54000;
}
if (RTC.getHours() >= 15 && RTC.getMinutes() <= 24) {
CDGoal = 0;
}
}
}
void RingBell() { //Bell activation function
digitalWrite(relayPin, HIGH);
delay(1500);
digitalWrite(relayPin, LOW);
}
void CDLcdPrint() { //Countdown LCD Function
if (CDSeconds == 9) {
lcd.clear();
}
if (CDGoal == 0) {
lcd.backlight();
lcd.setCursor(3,0);
lcd.print("COUNTDOWN");
lcd.setCursor(0,1);
lcd.print("School day done");
} else {
lcd.backlight();
lcd.setCursor(3,0);
lcd.print("COUNTDOWN");
lcd.setCursor(4,1);
lcd.print(CDHours);
lcd.print(":");
lcd.print(CDMinutes);
lcd.print(":");
lcd.print(CDSeconds);
}
}
void DTLcdPrint() { //Date and Time LCD Function
if (RTC.getSeconds() == 0) {
lcd.clear();
}
lcd.backlight();
lcd.setCursor(0,0);
lcd.print("DATE : ");
lcd.print(RTC.getMonth());
lcd.print("/");
lcd.print(RTC.getDay());
lcd.print("/");
lcd.print(RTC.getYear());
lcd.setCursor(0,1);
lcd.print("TIME : ");
lcd.print(RTC.getHours());
lcd.print(":");
lcd.print(RTC.getMinutes());
lcd.print(":");
lcd.print(RTC.getSeconds()); //Time
}
void SerialPrint() { //Serial Print Info
Serial.print(RTC.getWeek()); //DOW
Serial.print(" ");
Serial.print(RTC.getDay());
Serial.print("/");
Serial.print(RTC.getMonth());
Serial.print("/");
Serial.print(RTC.getYear());
Serial.print(" ");
Serial.print(RTC.getHours());
Serial.print(":");
Serial.print(RTC.getMinutes());
Serial.print(":");
Serial.print(RTC.getSeconds());
Serial.print(" ");
Serial.print(digitalRead(cdbuttonPin));
Serial.print(" ");
Serial.print(digitalRead(dtbuttonPin));
Serial.print(" ");
Serial.print(CDHours);
Serial.print(":");
Serial.print(CDMinutes);
Serial.print(":");
Serial.print(CDSeconds);
Serial.print(" ");
Serial.print(CDGoal);
Serial.print(" ");
Serial.println(CDNow);
}
void discardSerialData() { //Clear serial buffer
while (Serial.available() > 0) {
char c = Serial.read();
}
}
void ArduinoTimedReset() {
if (RTC.getHours() == 25 && RTC.getMinutes() == 0 && RTC.getSeconds() == 0|| //test line
RTC.getHours() == 8 && RTC.getMinutes() == 5 && RTC.getSeconds() == 0||
RTC.getHours() == 8 && RTC.getMinutes() == 35 && RTC.getSeconds() == 0||
RTC.getHours() == 9 && RTC.getMinutes() == 25 && RTC.getSeconds() == 0||
RTC.getHours() == 10 && RTC.getMinutes() == 0 && RTC.getSeconds() == 0||
RTC.getHours() == 10 && RTC.getMinutes() == 35 && RTC.getSeconds() == 0||
RTC.getHours() == 11 && RTC.getMinutes() == 25 && RTC.getSeconds() == 0||
RTC.getHours() == 12 && RTC.getMinutes() == 20 && RTC.getSeconds() == 0||
RTC.getHours() == 13 && RTC.getMinutes() == 15 && RTC.getSeconds() == 0||
RTC.getHours() == 14 && RTC.getMinutes() == 5 && RTC.getSeconds() == 0||
RTC.getHours() == 14 && RTC.getMinutes() == 45 && RTC.getSeconds() == 0||
RTC.getHours() >= 15 && RTC.getMinutes() == 30 && RTC.getSeconds() == 0 && RTC.getHours() <= 24||
RTC.getHours() >= 16 && RTC.getMinutes() == 0 && RTC.getSeconds() == 0 && RTC.getHours() <= 24||
RTC.getHours() >= 0 && RTC.getMinutes() == 0 && RTC.getSeconds() == 0 && RTC.getHours() < 8||
RTC.getHours() >= 0 && RTC.getMinutes() == 30 && RTC.getSeconds() == 0 && RTC.getHours() < 8) {
asm volatile (" jmp 0");
}
}
void CheckBell() {
if (RTC.getWeek() >= 2 && RTC.getWeek() < 7 ) { //When to ring bell
if (RTC.getHours() == 8 && RTC.getMinutes() == 0 && RTC.getSeconds() == 0||
RTC.getHours() == 8 && RTC.getMinutes() == 10 && RTC.getSeconds() == 0||
RTC.getHours() == 9 && RTC.getMinutes() == 0 && RTC.getSeconds() == 0||
RTC.getHours() == 9 && RTC.getMinutes() == 50 && RTC.getSeconds() == 0||
RTC.getHours() == 10 && RTC.getMinutes() == 10 && RTC.getSeconds() == 0||
RTC.getHours() == 11 && RTC.getMinutes() == 0 && RTC.getSeconds() == 0||
RTC.getHours() == 11 && RTC.getMinutes() == 50 && RTC.getSeconds() == 0||
RTC.getHours() == 12 && RTC.getMinutes() == 50 && RTC.getSeconds() == 0||
RTC.getHours() == 13 && RTC.getMinutes() == 40 && RTC.getSeconds() == 0||
RTC.getHours() == 14 && RTC.getMinutes() == 30 && RTC.getSeconds() == 0||
RTC.getHours() == 15 && RTC.getMinutes() == 0 && RTC.getSeconds() == 0) {
RingBell();
delay(1000);
Serial.flush();
}
}
}
void loop() {
ArduinoTimedReset();
CDGoalSet();
CDNow = ((RTC.getHours() * 3600UL) + (RTC.getMinutes() * 60UL) + RTC.getSeconds() );
SerialPrint();
CDTick = CDGoal - CDNow;
CDHours = CDTick / 3600;
CDMinutes = (CDTick % 3600) / 60;
CDSeconds = CDTick % 60;
CheckBell();
if (millis() - lastDiscardTime >= discardInterval) { //Clear serial buffer
discardSerialData();
lastDiscardTime = millis();
}
if (digitalRead(cdbuttonPin) == 1) { //Shows cooldown on LCD for 10 seconds then turns off LCD
startTime = millis();
while (millis() - startTime <= duration) {
CDNow = ((RTC.getHours() * 3600UL) + (RTC.getMinutes() * 60UL) + RTC.getSeconds() );
CDTick = CDGoal - CDNow;
CDHours = CDTick / 3600;
CDMinutes = (CDTick % 3600) / 60;
CDSeconds = CDTick % 60;
CDLcdPrint();
SerialPrint();
delay(250);
SerialPrint();
delay(250);
SerialPrint();
delay(250);
SerialPrint();
delay(250);
}
lcd.noBacklight();
lcd.clear();
}
if (digitalRead(dtbuttonPin) == 1) { //Shows date and time on LCD for 10 seconds then turns off LCD
startTime = millis();
while (millis() - startTime <= duration) {
DTLcdPrint();
SerialPrint();
delay(250);
SerialPrint();
delay(250);
SerialPrint();
delay(250);
SerialPrint();
delay(250);
}
lcd.noBacklight();
lcd.clear();
}
delay(250);
}