/*
This is a church bell controller.
The relay is for the hour bell.
The second relay is for ringing bell (please implement the ringing circuit seperatly)
You can implement a timer for second relay. I didnt made the timer code , Make your own
*/
#include "Wire.h"
#include <LiquidCrystal_I2C.h>
#define I2C_ADDR 0x27
#define LCD_COLUMNS 20
#define LCD_LINES 4
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
//BEGIN RTC CODE
//rtc variables
int second, minute, hour;
int dayOfWeek, dayOfMonth, month, year;
//end rtc variables
#define DS3231_I2C_ADDRESS 0x68
byte decToBcd(byte val) {
return ( (val / 10 * 16) + (val % 10) );
}
// Convert binary coded decimal to decimal numbers
byte bcdToDec(byte val) {
return ( (val / 16 * 10) + (val % 16) );
}
// Set the time
void rtc_setTime(byte second, byte minute, byte hour, byte wday, byte mday, byte mon, byte year) {
// sets time and date data to DS3231
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0); // set next input to start at the seconds register
Wire.write(decToBcd(second)); // set seconds
Wire.write(decToBcd(minute)); // set minutes
Wire.write(decToBcd(hour)); // set hours
Wire.write(decToBcd(wday)); // set day of week (1=Monday, 7=Sunday)
Wire.write(decToBcd(mday)); // set date (1 to 31)
Wire.write(decToBcd(mon)); // set month
Wire.write(decToBcd(year)); // set year (0 to 99)
Wire.endTransmission();
}
void rtc_readTime() {
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0); // set DS3231 register pointer to 00h
Wire.endTransmission();
// request seven bytes of data from DS3231 starting from register 00h
Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
second = bcdToDec(Wire.read() & 0x7f);
minute = bcdToDec(Wire.read());
hour = bcdToDec(Wire.read() & 0x3f);
dayOfWeek = bcdToDec(Wire.read());
dayOfMonth = bcdToDec(Wire.read());
month = bcdToDec(Wire.read());
year = bcdToDec(Wire.read());
//leap year correction
#define LEAP_YEAR(Y) ( !(((Y))%4) && ( (((Y))%100) || !(((Y))%400) ) )
if(LEAP_YEAR(year) == 0 && dayOfMonth == 29 && month == 2){
rtc_setTime(second, minute, hour, dayOfWeek, 1, 3, year);
}
}
void rtc_init(){
Wire.begin();
}
//END RTC CODE
//timing variables
uint32_t previous, previous1;
//your bell pin
int relay_pin = 13;
//your ringing bell ( this is using a relay, so you have to make a circuit to make the bell ringing)
int bell_pin = 8;
//for menu setTime
byte s = 0,m,h,w = 1,d = 1,n = 1,y;
//for menu
int buttonP;
//for debounce delay
long debounceDel = 100;
void setup() {
// Init lcd
lcd.init();
//lcd.begin();
lcd.backlight();
// Init rtc
rtc_init();
//for debug:
//rtc_setTime(55, 59, 23, 1,1,1,1);
//init hour bell
pinMode(relay_pin, OUTPUT);
//init ringing bell
pinMode(bell_pin, OUTPUT);
//buttons
pinMode(12, INPUT_PULLUP); //for menu display (black)
pinMode(11, INPUT_PULLUP); //for setting time (green)
pinMode(10, INPUT_PULLUP); //for ++ (blue)
pinMode(9, INPUT_PULLUP); //for -- (red)
//switch (for ringing bell)
pinMode(7, INPUT_PULLUP);
}
void strike_bell(long interval1, long interval2){
int varhour = 12;
if(hour >= 13){
varhour = hour - 12;
}
else if(hour == 0){
varhour = 12;
}
else {
varhour = hour;
}
for(int i = 1; i <= varhour; i++){
digitalWrite(relay_pin,1);
delay(interval1);
digitalWrite(relay_pin,0);
delay(interval2);
}
}
void loop() {
rtc_readTime();
if(buttonP == 0){
displayDT();
}
else if(buttonP == 1){
displaySY();
}
else if(buttonP == 2){
displaySN();
}
else if(buttonP == 3){
displaySD();
}
else if(buttonP == 4){
displaySW();
}
else if(buttonP == 5){
displaySH();
}
else if(buttonP == 6){
displaySM();
}
else if(buttonP == 7){
displayST();
}
if(!digitalRead(12)){
delay(debounceDel);
++buttonP;
if(buttonP >= 8){
buttonP = 0;
}
}
if(!digitalRead(7)){
digitalWrite(bell_pin,1);
} else {
digitalWrite(bell_pin, 0);
}
}
//lcd display
void displayDT(){
//print datetime
if(micros() - previous >= 500000){
lcd.clear();
char buffer[20];
sprintf(buffer, "%02d:%02d:%02d", hour, minute, second);
lcd.setCursor(0,0);
lcd.print(buffer);
sprintf(buffer, "%02d/%02d/%02d", (year%100), month, dayOfMonth);
lcd.setCursor(12,0);
lcd.print(buffer);
previous = micros();
}
if(minute == 0 && second == 0){
strike_bell(200, 700);
}
}
void displaySY(){
delay(debounceDel);
lcd.clear();
lcd.print("Set Year since 2000");
lcd.setCursor(0,3);
lcd.print(y);
if(!digitalRead(10)){
++y;
}
if(!digitalRead(9)){
--y;
}
}
void displaySN(){
delay(debounceDel);
lcd.clear();
lcd.print("Set Month");
lcd.setCursor(0,3);
lcd.print(n);
if(!digitalRead(10)){
++n;
}
if(!digitalRead(9)){
--n;
}
if(n >= 13){
n = 1;
}
}
void displaySD(){
delay(debounceDel);
lcd.clear();
lcd.print("Set DOM");
lcd.setCursor(0,3);
lcd.print(d);
if(!digitalRead(10)){
++d;
}
if(!digitalRead(9)){
--d;
}
if(d >= 32){
d = 1;
}
}
void displaySW(){
delay(debounceDel);
lcd.clear();
lcd.print("Set DOW");
lcd.setCursor(0,3);
lcd.print(w);
if(!digitalRead(10)){
++w;
}
if(!digitalRead(9)){
--w;
}
if(w >= 8){
w = 1;
}
}
void displaySH(){
delay(debounceDel);
lcd.clear();
lcd.print("Set Hour");
lcd.setCursor(0,3);
lcd.print(h);
if(!digitalRead(10)){
++h;
}
if(!digitalRead(9)){
--h;
}
if(w >= 13){
w = 1;
}
}
void displaySM(){
delay(debounceDel);
lcd.clear();
lcd.print("Set Minute");
lcd.setCursor(0,3);
lcd.print(m);
if(!digitalRead(10)){
++m;
}
if(!digitalRead(9)){
--m;
}
if(m >= 60){
m = 1;
}
}
void displayST(){
lcd.clear();
lcd.print("Set All");
if(!digitalRead(11)){
rtc_setTime(s,m,h,w,d,n,y);
}
}