/*
This is a church bell controller (advanced).
The relay is for the hour bell.
This have 2 timers that ring every day,year,month,daily.
To update the alarms, press the grey button.
To set your alarms, to to "Set Timer 1" or "Set Timer 2" to set the bells and time you want.
The bells counter is in binary. Eg 3 = bell 2 and bell 3.
For now the bells will be daily ONLY and the relay wont be on.
But will update soon.
*/
#include "Wire.h"
#include <EEPROM.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;
//for menu setTime
byte s = 0,m,h,w = 1,d = 1,n = 1,y;
//for menu
int buttonP;
//bells
int bell1 = 6;
int bell2 = 5;
int bell3 = 4;
//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);
//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)
pinMode(2, INPUT_PULLUP); //for upodate
//init ringing bells
pinMode(bell1, OUTPUT);
pinMode(bell2, OUTPUT);
pinMode(bell3, OUTPUT);
}
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();
}
else if(buttonP == 8){
displaySE1();
}
else if(buttonP == 9){
displaySE2();
}
else if(buttonP == 10){
displaySE1B();
}
else if(buttonP == 11){
displaySE2B();
}
if(!digitalRead(12)){
delay(debounceDel);
++buttonP;
if(buttonP >= 12){
buttonP = 0;
}
}
}
//timer
void displaySE1(){
delay(debounceDel);
lcd.clear();
lcd.print("Set Timer 1");
lcd.setCursor(0,1);
lcd.print("Seconds Since 12am: ");
static long seconde;
lcd.setCursor(0,2);
lcd.print(seconde);
if(!digitalRead(10)){
++seconde;
}
if(!digitalRead(9)){
--seconde;
}
if(seconde >= 86400){
seconde = 0;
}
if(seconde <= -1){
seconde = 86399;
}
if(!digitalRead(11)){
EEPROM.put(0, seconde);
}
}
void displaySE2(){
delay(debounceDel);
lcd.clear();
lcd.print("Set Timer 2");
lcd.setCursor(0,1);
lcd.print("Seconds Since 12am: ");
static long seconde;
lcd.setCursor(0,2);
lcd.print(seconde);
if(!digitalRead(10)){
++seconde;
}
if(!digitalRead(9)){
--seconde;
}
if(seconde >= 86400){
seconde = 0;
}
if(seconde <= -1){
seconde = 86399;
}
if(!digitalRead(11)){
EEPROM.put(10, seconde);
}
}
//how many bells
void displaySE1B(){
delay(debounceDel);
lcd.clear();
lcd.print("Bells T1: ");
lcd.setCursor(0,1);
lcd.print("Val: ");
static byte b;
lcd.setCursor(0,2);
lcd.print(b);
if(!digitalRead(10)){
++b;
}
if(!digitalRead(9)){
--b;
}
if(b >= 8){
b = 0;
}
if(b <= -1){
b = 7;
}
if(!digitalRead(11)){
EEPROM.put(20, b);
}
}
void displaySE2B(){
delay(debounceDel);
lcd.clear();
lcd.print("Bells T2: ");
lcd.setCursor(0,1);
lcd.print("Val: ");
static byte b;
lcd.setCursor(0,2);
lcd.print(b);
if(!digitalRead(10)){
++b;
}
if(!digitalRead(9)){
--b;
}
if(b >= 8){
b = 0;
}
if(b <= -1){
b = 7;
}
if(!digitalRead(11)){
EEPROM.put(25, b);
}
}
//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);
static long t1,t2;
static byte b1,b2;
lcd.setCursor(0,1);
lcd.print("Alarm 1:");
lcd.print(t1);
lcd.setCursor(0,2);
lcd.print("Alarm 2:");
lcd.print(t2);
lcd.setCursor(0,3);
lcd.print("TB1:");
lcd.print(b1);
lcd.print(" ");
lcd.print("TB2:");
lcd.print(b2);
if(!digitalRead(2)){
EEPROM.get(0,t1);
EEPROM.get(10,t2);
EEPROM.get(20,b1);
EEPROM.get(25,b2);
}
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);
}
}