I'm a relatively new Arduino user. I use Arduino uno, DS3231 rtc, 5v relay, keypad, and lcd for my project. I'm trying to make an automatic school bell, and my project uses a relay that ticks on and off in a pattern of schedule. When I made the value for length and length2 very short (about 6 seconds or so), the void buzzer() ticks based on the intended schedule, but when I put 3,600,000 (1 hour) as the value for length, the void buzzer() just doesn't function 1 hour later, but the current time still keeps showing in serial. Admittedly, I only power my Arduino with usb cable connected to my laptop, since the battery I ordered still hasn't arrived. Does the battery help with this problem, or is it some sort of a limitation or fault in the code?
#include <Wire.h>
#include <TimeLib.h>
#include <TimeAlarms.h>
#include <DS1307RTC.h>
#include <RTClib.h>
#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
RTC_DS3231 rtc;
#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] = { 12, 11, 10, 9 };
byte pin_column[numCols] = { 8, 7, 6 };
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;
char daysOfTheWeek[7][12] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
char code[] = { '6', '6', '0', '1' }; // password is 6601
int i = 0, a = 0, j = 0; // needed for password typing
int i1, i2, i3;
char c1, c2, c3;
unsigned long time = millis();
unsigned long time2 = millis();
int intervalMins = 60;
int intervalMillis = 6000;
int tentativeInt;
int length = 3000;
int length2 = 3000;
byte period;
byte period2;
char keypressed = myKeypad.getKey();
byte firstBell = 2;
bool buzzerOn = false;
bool displayTime = true;
bool alarmOngoing = false;
bool alarmOngoingPM = false;
bool isMorning = false;
bool isAfternoon = false;
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;
}
}
// put your setup code here, to run once:
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__)));
}
rtc.disable32K();
Alarm.alarmRepeat(7, 29, 50, firstPeriod);
Alarm.alarmRepeat(12, 59, 50, pmPeriod);
pinMode(2, OUTPUT);
digitalWrite(2, HIGH);
}
void loop() {
// put your main code here, to run repeatedly:
do {
alarmBegin();
digitalClockDisplay();
} while (alarmOngoing);
do {
alarmBegin2();
digitalClockDisplay();
} while (alarmOngoingPM);
do {
digitalClockDisplay2();
} while (displayTime);
if (keypressed == '*') {
displayTime = false;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter code:");
getPassCode();
if (a == sizeof(code)) {
setupMenu();
} else {
wrongPassCodeMsg();
}
displayTime = true;
}
}
void alarmBegin() {
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;
period = 2;
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;
}
}
}
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;
period2 = 2;
Serial.print("Period is now ");
Serial.println(period2);
break;
case 2: // recess
buzzer2();
length2 = 3000;
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(1000);
digitalWrite(2, HIGH);
}
void buzzer2() {
time2 = millis();
digitalWrite(2, LOW);
Serial.println("Bell");
Alarm.delay(1000);
digitalWrite(2, HIGH);
}
void firstPeriod() {
period = 0;
isMorning = true;
alarmOngoing = true;
displayTime = false;
Serial.println("AM bell starts now");
}
void pmPeriod() {
period2 = 0;
isAfternoon = true;
alarmOngoingPM = true;
displayTime = false;
Serial.println("PM bell starts now");
}
void wrongPassCodeMsg() {
lcd.clear();
lcd.print("Wrong. Try again");
delay(1500);
lcd.clear();
}
void getPassCode() {
i = 0;
a = 0;
j = 0;
char keypressed = NO_KEY;
while (keypressed != '#') {
keypressed = myKeypad.getKey();
if (keypressed != NO_KEY && keypressed != '#') {
lcd.setCursor(j, 1);
lcd.print("*");
j++;
if (keypressed == code[i] && i < sizeof(code)) {
a++;
i++;
} else
a--;
}
}
}
void setupMenu() {
lcd.clear();
lcd.print("Setting period");
lcd.setCursor(0, 1);
lcd.print("length...");
delay(1500);
lcd.clear();
lcd.print("Enter length:");
char keypressed3 = myKeypad.waitForKey();
if (keypressed3 != NO_KEY && keypressed3 != '#' && keypressed3 != '*') {
c1 = keypressed3;
lcd.setCursor(0, 1);
lcd.print(c1);
}
char keypressed4 = myKeypad.waitForKey();
if (keypressed4 != NO_KEY && keypressed4 != '#' && keypressed4 != '*') {
c2 = keypressed4;
lcd.setCursor(1, 1);
lcd.print(c2);
}
char keypressed5 = myKeypad.waitForKey();
if (keypressed5 != NO_KEY && keypressed5 != '#' && keypressed5 != '*') {
c3 = keypressed5;
lcd.setCursor(2, 1);
lcd.print(c3);
}
i1 = (c1 - 48) * 100;
i2 = (c2 - 48) * 10;
i3 = c3 - 48;
tentativeInt = i1 + i2 + i3;
delay(500);
lcd.clear();
if (tentativeInt > 180) {
lcd.print("Don't input more");
lcd.setCursor(0, 1);
lcd.print("than 3 hours");
} else if (tentativeInt <= 180 && tentativeInt != 0) {
lcd.print("Class interval");
lcd.setCursor(0, 1);
lcd.print("set!");
intervalMins = tentativeInt;
intervalMillis = intervalMins * 60000;
} else { // tentativeInt == 0
lcd.print("Input invalid");
}
delay(1500);
lcd.clear();
}
void digitalClockDisplay() {
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.println();
Alarm.delay(1000);
}
void printDigits(int digits) {
Serial.print(":");
if (digits < 10)
Serial.print('0');
Serial.print(digits);
}
void digitalClockDisplay2() {
lcd.clear();
lcd.print("Time: ");
Serial.print(hour());
lcd.print(hour());
printDigits2(minute());
printDigits2(second());
Serial.println();
Alarm.delay(1000);
}
void printDigits2(int digits) {
Serial.print(":");
lcd.print(":");
if (digits < 10)
Serial.print('0');
lcd.print('0');
Serial.print(digits);
lcd.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;
}