//oM zrii gurave namaH
const int debug = 0;
#include <Wire.h>
#include <RTClib.h>
//#include <<DS3231.h>
#include <LiquidCrystal_I2C.h>
// Define the pins -- i.e. assigning the function to the PIN
#define RELAY_PIN 2
#define BUZZER_PIN 3
#define backlight_PIN 4
#define modeButton 13
#define bellButton 12
#define autoLed_PIN A0
#define potPin A1 // Pin connected to the potentiometer
int ringDuration = 100; // how long to ring // pot used to alter
String msg; String mode_Msg;
int mode = 1; // 1 = auto, 0 = manual
// Create objects
LiquidCrystal_I2C lcd(0x27, 16, 2);// ref: datasheet
RTC_DS3231 rtc;
void setup() { // -----IMPORTANT ------//
Serial.begin(9600);//---Initialize Serial Monitor for debugging purpose
Wire.begin(); //to ensure I2C bus is properly initialized before any communication takes place.
lcd.begin(16, 2); // Initialize LCD COLUMN, ROW
// Initialize pins
const int outPutPins[3] = {RELAY_PIN, BUZZER_PIN, autoLed_PIN};
const int pullUpButtons[3] = {modeButton, bellButton, backlight_PIN};
for(int i = 0; i < 3; ++i){
pinMode(outPutPins[i], OUTPUT);
pinMode(pullUpButtons[i], INPUT_PULLUP);
Serial.println(i);
}
beep();
// Initialize RTC
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1); delay(10);
} if (rtc.lostPower()) { Serial.println("RTC lost power, let's set the time!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
/////-----IMPORTANT ----------------------//
// Uncomment the next line on the first run to set the correct time
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// manual setup example: January 14, 2024, 15:28:00 : >>>
//rtc.adjust(DateTime(2024, 1, 14, 15, 28, 0)); // for manual adjustment with buttons
//delay(1000);// give rtc module some time to initialize
} /// ------Setup ends -------------------------
void loop() { /// ------------ void loop starts ---------
//--------Clock function start ----------------------
DateTime now = rtc.now();
byte currentHour = now.hour(); byte currentMin = now.minute(); byte currentSec = now.second();
byte currentDay = now.day(); byte currentMonth = now.month(); int currentYear = now.year();
byte temp = rtc.getTemperature();
byte dayOfWeek = now.dayOfTheWeek(); //index to match a representation where Sunday is 1.
//--------Clock function end ----------------------
//~~~~~~~~~~~~~~~~~~ BUTTON CODE STARTS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
static unsigned long lastModeButtonPress = 0;
if (digitalRead(modeButton) == LOW && millis() - lastModeButtonPress > 1000) { // 1 sec pause before 2nd press
lastModeButtonPress = millis();
mode = 1 - mode; // toggle between Auto and manual mode
beep();// to confirm button press
}
if(digitalRead(bellButton)== LOW){ring(1);} // manual ring
if(digitalRead(backlight_PIN)==LOW) { lcd.backlight();} // lcd backlight ON
if(digitalRead(backlight_PIN)==HIGH){ lcd.noBacklight(); } // lcd backlight OFF
//~~~~~~~~~~~~~~~~~~ BUTTON CODE ENDS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//-------------Variable Ring Duration starts ------------------//
int potValue = analogRead(potPin); // Read the analog value from the potentiometer
ringDuration = map(potValue, 0, 1023, 100, 2000); //map to 100 mili sec to 2 sec here
// ------------Variable Ring Duration ends --------------------//
if (mode) {
if (currentHour == 10 && currentMin == 40 ) { // 10:40 AM Prayer Starts
msg = "Pray"; if (currentSec == 00) {ring(1);}
} else if (currentHour == 10 && currentMin == 50 ) { // 10:50 AM 1st period starts
msg = "(1p)"; if (currentSec == 00) {ring(1);}
} else if (currentHour == 11 && currentMin == 30 ) { // 11:30 AM 2nd period starts
msg = "(2p)"; if (currentSec == 00) {ring(1);}
} else if (currentHour == 12 && currentMin == 10 ) { // 12:10 PM 3rd period starts
msg = "(3p)"; if (currentSec == 00) {ring(1);}
} else if (currentHour == 12 && currentMin == 50 ) { // 12:50 PM 4th period starts
msg = "(4p)"; if (currentSec == 00) {ring(1);}
} else if (currentHour == 13 && currentMin == 30 ) { // 1:30 PM Tiffin starts
msg = "MDM"; if (currentSec == 00) {ring(1);}
} else if (currentHour == 14 && currentMin == 10 ) { // 2:10 PM 5th period
msg = "(5p)"; if (currentSec == 00) {ring(1);}
} else if (currentHour == 14 && currentMin == 45 ) { // 2:45 PM 6th period
msg = "(6p)"; if (currentSec == 00) {ring(1);}
} else if (currentHour == 15 && currentMin == 20 ) { // 3:20 PM 7th period
msg = "(7p)"; if (currentSec == 00) {ring(1);}
} else if (currentHour == 15 && currentMin == 55 ) { // 3:55 PM 8th period
msg = "(8p)"; if (currentSec == 00) {ring(1);}
} else if (currentHour == 16 && currentMin == 30 ) { // 4:30 PM END of SCHOOL
msg = "End"; if (currentSec == 00) { ring(1); }
}
mode_Msg = "(A)";
digitalWrite(autoLed_PIN, HIGH); // switch on the AUTO LED
}
else {
mode_Msg = "(M)"; digitalWrite(autoLed_PIN, LOW); // switch off the AUTO LED
}
//---- LCD TOP ROW ----starts
lcd.clear(); lcd.setCursor(0, 0);// clear screen & start at upper row
printLcd(0, 0, String(currentHour)); printLcd(2, 0, ":");
printLcd(3, 0, String(currentMin)); printLcd(5, 0, ":");
printLcd(6, 0, String(currentSec));
printLcd(9, 0, String(currentDay) + monthToString(currentMonth) + String(currentYear % 100));
//---- LCD TOP ROW ----ENDS
//----- LCD Bottom row ------start
printLcd(0, 1, dayToString(dayOfWeek));
printLcd(4, 1, msg);
printLcd(9, 1, String(temp - 3)); // to subtrack heat inside the box
printLcd(11, 1, "C");
printLcd(13, 1, mode_Msg);
// ----- LCD Bottom row -----end
delay(1000); //delay for stability-- IMPORTANT
}// /// ------------ void loop ends ------------------///
//--------------------UDF starts -----------------------
void ring(int t) {
lcd.backlight();
for (int i = 1; i <= t; ++i) {
digitalWrite(RELAY_PIN, HIGH); // switch on relay
if (debug) {Serial.println("running for " + String(i) + " time");}
const int melody[] = {2100, 2000, 2200, 1900, 2300, 1800, 3000, 3500, 2000};// in Hz
for (int c = 0; c < sizeof(melody) / sizeof(melody[0]); c++) {
tone(BUZZER_PIN, melody[c], ringDuration);
delay(ringDuration);
//noTone(BUZZER_PIN);
}
digitalWrite(RELAY_PIN, LOW); // switch off relay
printLcd(4, 1, "Ring>" + String(ringDuration) + "ms-" + String(t));
// Add a delay for silence between iterations
delay(1000); // Adjust the duration of silence as needed
lcd.noBacklight();
}
}
void beep() {
lcd.backlight(); tone(BUZZER_PIN, 3700, 170); lcd.noBacklight();
}
void printLcd (int shuru, int sesh, String myWords) { // For LCD Display
lcd.setCursor(shuru, sesh); lcd.print(myWords);
}
String monthToString(int month) {
switch (month) {
case 1: return "Jan"; case 2: return "Feb"; case 3: return "Mar";
case 4: return "Apr"; case 5: return "May"; case 6: return "Jun";
case 7: return "Jul"; case 8: return "Aug"; case 9: return "Sep";
case 10: return "Oct"; case 11: return "Nov"; case 12: return "Dec";
default: return "";
}
}
String dayToString(int theDay) {
switch (theDay) {
case 0: return "Sun"; case 1: return "Mon"; case 2: return "Tue";
case 3: return "Wed"; case 4: return "Thu"; case 5: return "Fri";
case 6: return "Sat"; default: return "Invalid day";
}
}//-------------- UDF ends -----------------//