// https://forum.arduino.cc/t/new-project-ships-clock/1339379
// https://en.wikipedia.org/wiki/Ship%27s_bell
/*
// Calculating ships bells
void setup() {
Serial.begin(115200);
for (int hour = 0; hour <= 24; hour ++) { // count the hours
Serial.print(hour);
Serial.print(" = ");
if (hour && !(hour % 4)) // greater than zero and evenly divisible by 4
Serial.print(4); // four double bells
else
Serial.print(hour % 4); // remainder of hour division by 4
Serial.print(" double bells");
Serial.println();
}
}
void loop() {}
*/
#include <RTClib.h>
RTC_DS1307 rtc;
DateTime now;
char daysOfTheWeek[7][4] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
bool onetime;
byte buzzerPin = 2;
void setup () {
Serial.begin(115200);
rtc.begin();
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // system time
// January 21, 2021, 10:23.24pm
// rtc.adjust(DateTime(2021, 1, 21, 22, 23, 24)); // set any time
// rtc.adjust(DateTime(2025, 1, 6, 0, 29, 55)); // set any time 5 seconds before one bell
rtc.adjust(DateTime(2025, 1, 6, 7, 59, 55)); // set any time 5 seconds before eight bells
}
void loop () {
now = rtc.now();
// double bells: minutes are 00 or 30 and greater than zero and evenly divisible by 4, or remainder of (hour mod 4)
int doublebell = ((!now.minute() || now.minute() == 30) && now.hour() && !(now.hour() % 4)) ? 4 : now.hour() % 4;
// single bells: half hours
int singlebell = now.minute() == 30;
Serial.print(doublebell);
for (int i = 0; i < doublebell; i++)
bell();
Serial.print(" ");
Serial.print(singlebell);
if (singlebell && !onetime)
bell();
Serial.println();
delay(250);
}
void bell() {
onetime = 1; // set onetime flag to only visit one time
digitalWrite(buzzerPin, HIGH);
digitalWrite(buzzerPin, LOW);
Serial.print("ding");
}
void humantime() {
onetime = 1; // set onetime flag to only visit one time
Serial.print("Current time: ");
Serial.print(now.year(), DEC);
Serial.print('/');
pad(now.month());
Serial.print(now.month(), DEC);
Serial.print('/');
pad(now.day());
Serial.print(now.day(), DEC);
Serial.print(" (");
Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
Serial.print(") ");
pad(now.hour());
Serial.print(now.hour(), DEC);
Serial.print(':');
pad(now.minute());
Serial.print(now.minute(), DEC);
Serial.print(':');
pad(now.second());
Serial.print(now.second(), DEC);
Serial.println();
}
void pad(int value) {
if (value < 10) // pad single digits
Serial.print("0");
}