I tested my code at about 7:25, and waited for 7:30 for the bell to work. The Alarm.alarmRepeat(7, 29, 50, firstPeriod); does not trigger the void firstPeriod(), so it did not write the "AM bell starts now" in the serial comms. Did I do something wrong in my code? (pls ignore the comments)
#include <Wire.h> // Libraries needed
#include <TimeLib.h>
#include <TimeAlarms.h>
#include <DS1307RTC.h>
#include <RTClib.h>
#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
RTC_DS3231 rtc;
AlarmId;
#define I2C_ADDR 0x27 // LCD i2c address
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
// LCD setup
LiquidCrystal_I2C lcd(I2C_ADDR, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin, D7_pin);
// Keypad setup
const byte numRows = 4; // 4 rows
const byte numCols = 3; // 3 columns
char keymap[numRows][numCols] = {
{ '1', '2', '3' },
{ '4', '5', '6' },
{ '7', '8', '9' },
{ '*', '0', '#' }
};
byte pin_rows[numRows] = { 11, 6, 7, 9 };
byte pin_column[numCols] = { 10, 12, 8 };
Keypad myKeypad = Keypad(makeKeymap(keymap), pin_rows, pin_column, numRows, numCols);
// RTC setup
const char *monthName[12] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
tmElements_t tm;
// Variables list
char code[] = { '6', '6', '0', '1' }; // password is 6601
int i = 0, a = 0, j = 0; // needed for password typing
int i1, i2, i3; // needed for calculations
char c1, c2, c3;
unsigned long time = millis(); // needed for the bell to function properly
unsigned long time2 = millis();
unsigned long displayTime = millis();
int intervalMins = 60; // number of minutes in a class
unsigned long intervalMillis = 3600000; // intervalMins in milliseconds
int tentativeInt; // placeholder number in calculations
unsigned long length = 3000;
unsigned long length2 = 3000;
int customMins = 60; // number of minutes between 6:30 and the first bell
unsigned long customMillis = 3600000; // 6:30 in 3600s is 7:30
char keypressed = myKeypad.getKey();
byte period;
byte period2;
bool alarmOngoing = false; // not yet in a class day
bool alarmOngoingPM = false;
bool isMorning = false; // for turning on morning alarms
bool isAfternoon = false; // isMorning but afternoon
bool recessOn = true; // customize whether to include recess in schedule
bool recessOnPM = true;
bool customTime = false; // 6:30 is the start time
void setup() {
bool parse = false;
bool config = false;
// get the date and time the compiler was run
if (getDate(__DATE__) && getTime(__TIME__)) {
parse = true;
// and configure the RTC with this info
if (RTC.write(tm)) {
config = true;
}
}
Serial.begin(9600);
while (!Serial)
; // wait for Arduino Serial Monitor
setSyncProvider(RTC.get);
setTime(tm.Hour, tm.Minute, tm.Second, tm.Day, tm.Month, tm.Year);
if (!rtc.begin()) {
Serial.println("Couldn't find RTC!");
Serial.flush();
while (1) delay(10);
}
if (rtc.lostPower()) {
Serial.println("RTC lost power. Setting time...");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
// We don't need this
rtc.disable32K();
Alarm.alarmRepeat(7, 29, 50, firstPeriod); // 6:30
Alarm.alarmRepeat(12, 59, 50, pmPeriod); // 1:00 pm
pinMode(2, OUTPUT);
digitalWrite(2, HIGH);
}
void loop() {
goToMenu();
digitalClockDisplay();
do {
goToMenu();
alarmBegin();
} while (alarmOngoing);
do {
goToMenu();
alarmBegin2();
} while (alarmOngoingPM);
}
void goToMenu() {
if (keypressed == '*') {
Serial.println("Enter code:");
getPassCode();
if (a == sizeof(code)) {
setupMenu();
} else {
wrongPassCodeMsg();
}
}
if (keypressed == '#') {
Serial.println("Enter code:");
getPassCode();
if (a == sizeof(code)) {
customMenu();
} else {
wrongPassCodeMsg();
}
}
}
void alarmBegin() {
isMorning = true;
time = millis();
if (isMorning == true && millis() - time >= length) {
switch (period) {
case 0: // 1st period
buzzer();
length = intervalMillis;
period = 1;
Serial.print("Period is now ");
Serial.println(period);
break;
case 1: // 2nd period
buzzer();
length = intervalMillis;
if (recessOn) {
period = 2;
} else {
period = 3;
}
Serial.print("Period is now ");
Serial.println(period);
break;
case 2: // recess
buzzer();
length = 3000;
period = 3;
Serial.print("Period is now ");
Serial.println(period);
break;
case 3: // 3rd period
buzzer();
length = intervalMillis;
period = 4;
Serial.print("Period is now ");
Serial.println(period);
break;
case 4: // 4th period
buzzer();
length = intervalMillis;
period = 5;
Serial.print("Period is now ");
Serial.println(period);
break;
case 5: // lunch
buzzer();
length = 0;
period = 6;
Serial.println("End of morning class");
alarmOngoing = false;
isMorning = false;
break;
case 12:
time = millis();
length = customMillis;
period = 0;
Serial.println("Not time yet");
}
}
}
void alarmBegin2() {
if (isAfternoon == true && millis() - time2 >= length2) {
switch (period2) {
case 0: // 1st period pm
buzzer2();
length2 = intervalMillis;
period2 = 1;
Serial.print("Period is now ");
Serial.println(period2);
break;
case 1: // 2nd period pm
buzzer2();
length2 = intervalMillis;
if (recessOnPM) {
period2 = 2;
} else {
period2 = 3;
}
Serial.print("Period is now ");
Serial.println(period2);
break;
case 2: // recess
buzzer2();
length2 = 900000;
period2 = 3;
Serial.print("Period is now ");
Serial.println(period2);
break;
case 3: // 3rd period pm
buzzer2();
length2 = intervalMillis;
period2 = 4;
Serial.print("Period is now ");
Serial.println(period2);
break;
case 4: // after class
buzzer2();
length2 = 0;
period2 = 5;
Serial.println("End of afternoon class");
alarmOngoingPM = false;
isAfternoon = false;
break;
}
}
}
void buzzer() {
time = millis();
digitalWrite(2, LOW);
Serial.println("Bell");
Alarm.delay(2000);
digitalWrite(2, HIGH);
}
void buzzer2() {
time2 = millis();
digitalWrite(2, LOW);
Serial.println("Bell");
Alarm.delay(2000);
digitalWrite(2, HIGH);
}
void firstPeriod() {
period = 0;
isMorning = true;
alarmOngoing = true;
Serial.println("AM bell starts now");
}
void pmPeriod() {
period2 = 0;
isAfternoon = true;
alarmOngoingPM = true;
Serial.println("PM bell starts now");
}
void wrongPassCodeMsg() {
Serial.println("Wrong");
}
void getPassCode() {
i = 0;
a = 0;
j = 0;
char keypressed = NO_KEY;
while (keypressed != '#') {
keypressed = myKeypad.getKey();
if (keypressed != NO_KEY && keypressed != '#') {
Serial.print("*");
j++;
if (keypressed == code[i] && i < sizeof(code)) {
a++;
i++;
} else
a--;
}
}
}
void setupMenu() {
Serial.println("* - set start time # - set period length");
char keypressed2 = myKeypad.waitForKey();
if (keypressed2 == '*') {
Serial.println("Setting start time");
delay(1500);
Serial.println("Enter time of first bell");
char keypressed3 = myKeypad.waitForKey();
if (keypressed3 >= '6' && keypressed3 <= '8') { // only accept numbers 6, 7, and 8
c1 = keypressed3;
Serial.print(c1);
Serial.print(":");
}
char keypressed4 = myKeypad.waitForKey();
if (keypressed3 == '6') { // keypressed3 is 6
if (keypressed4 >= '3' && keypressed4 <= '5') { // unsigned long customMillis does not accept negative numbers
c2 = keypressed4;
Serial.print(c2);
}
}
if (keypressed3 == '7' || keypressed3 == '8') { // keypressed3 is 7 or 8
if (keypressed4 >= '0' && keypressed4 <= '5') {
c2 = keypressed4;
Serial.print(c2);
}
}
char keypressed5 = myKeypad.waitForKey();
if (keypressed5 >= '0' && keypressed5 <= '9') {
c3 = keypressed5;
Serial.println(c3);
}
i1 = (c1 - 54) * 60; // calculation from time into minutes
i2 = ((c2 - 48) * 10) - 30;
i3 = c3 - 48;
tentativeInt = i1 + i2 + i3;
delay(500);
if (tentativeInt >= 1) {
Serial.print("Time period from 6:30 to bell: ");
Serial.print(tentativeInt);
Serial.println(" minutes");
customMins = tentativeInt;
customMillis = customMins * 60000; // conversion from mins to milliseconds
customTime = true;
} else { // tentativeInt is 0
Serial.println("Returning to 6:30 bell");
customTime = false;
}
} else if (keypressed2 == '#') {
Serial.println("Setting period");
delay(1500);
Serial.println("Enter length:");
char keypressed3 = myKeypad.waitForKey();
if (keypressed3 != NO_KEY && keypressed3 != '#' && keypressed3 != '*') {
c1 = keypressed3;
Serial.print(c1);
}
char keypressed4 = myKeypad.waitForKey();
if (keypressed4 != NO_KEY && keypressed4 != '#' && keypressed4 != '*') {
c2 = keypressed4;
Serial.println(c2);
}
i1 = (c1 - 48) * 10;
i2 = c2 - 48;
tentativeInt = i1 + i2;
delay(500);
if (tentativeInt > 60) {
Serial.println("Don't input more than 1 hour");
} else if (tentativeInt <= 60 && tentativeInt >= 2) {
Serial.print("Class interval: ");
Serial.print(tentativeInt);
Serial.println(" minutes");
intervalMins = tentativeInt;
intervalMillis = intervalMins * 60000;
} else { // tentativeInt is 1 or 0
Serial.println("Input invalid");
}
} else {
Serial.println("Returning to time display");
}
}
void customMenu() {
Serial.println("* - toggle recess # - time status");
char keypressed2 = myKeypad.waitForKey();
if (keypressed2 == '*') {
Serial.println("AM recess on?");
Serial.println("* - yes # - no");
char keypressed3 = myKeypad.waitForKey();
if (keypressed3 == '*') {
recessOn = true;
Serial.println("AM recess on");
delay(1500);
pmRecessToggle();
}
if (keypressed3 == '#') {
recessOn = false;
Serial.println("AM recess off");
delay(1500);
pmRecessToggle();
}
} else if (keypressed2 == '#') {
Serial.print("Time: ");
Serial.print(hour());
printDigits(minute());
printDigits(second());
delay(1000);
} else {
Serial.println("Returning to time display");
}
}
void pmRecessToggle() {
Serial.println("PM recess on?");
Serial.println("* - yes # - no");
char keypressed4 = myKeypad.waitForKey();
if (keypressed4 == '*') {
recessOnPM = true;
Serial.println("PM recess on");
}
if (keypressed4 == '#') {
recessOnPM = false;
Serial.println("PM recess off");
}
}
void digitalClockDisplay() {
if (millis() - displayTime >= 1000) {
lcd.clear();
lcd.print("Time: ");
Serial.print(hour());
lcd.print(hour());
printDigits(minute());
printDigits(second());
Serial.println();
displayTime = millis();
}
}
void printDigits(int digits) {
Serial.print(":");
lcd.print(":");
if (digits < 10)
Serial.print('0');
lcd.print('0');
Serial.print(digits);
lcd.print(digits);
}
void digitalClockDisplay2() {
Serial.print(hour());
printDigits2(minute());
printDigits2(second());
Serial.println();
Alarm.delay(1000);
}
void printDigits2(int digits) {
Serial.print(":");
if (digits < 10)
Serial.print('0');
Serial.print(digits);
}
bool getTime(const char *str) {
int Hour, Min, Sec;
if (sscanf(str, "%d:%d:%d", &Hour, &Min, &Sec) != 3) return false;
tm.Hour = Hour;
tm.Minute = Min;
tm.Second = Sec;
return true;
}
bool getDate(const char *str) {
char Month[12];
int Day, Year;
uint8_t monthIndex;
if (sscanf(str, "%s %d %d", Month, &Day, &Year) != 3) return false;
for (monthIndex = 0; monthIndex < 12; monthIndex++) {
if (strcmp(Month, monthName[monthIndex]) == 0) break;
}
if (monthIndex >= 12) return false;
tm.Day = Day;
tm.Month = monthIndex + 1;
tm.Year = CalendarYrToTm(Year);
return true;
}