Alarm clock code. Almost working but need help.

Hello, I am building an alarm clock using a lcd, keypad, and rtc. The objective is when the alarm goes off, you have to enter the current time and a passcode via the keypad to turn off the alarm. So far, everything works as intended, however when the alarm sounds the keypad inputs don't register.

Here is the code. Any help is appreciated.

/*
 * Alarm Clock
 * Displays Date and Time On LCD Screen
 * Enter Passcode To Turn Off Alarm
 */

#include <Time.h>  
#include <Wire.h>  
#include <DS1307RTC.h>
#include <LiquidCrystal.h>
#include <Tone.h>
#include <Keypad.h>


// 4-Digit passcode to turn off the alarm
int PassCodeDigit1 = 1;
int PassCodeDigit2 = 2;
int PassCodeDigit3 = 3;
int PassCodeDigit4 = 4;

// Varibales to hold time entry passcode
int timeEntry1;
int timeEntry2;
int timeEntry3;
int timeEntry4;
int passEntry1;
int passEntry2;
int passEntry3;
int passEntry4;

//Variables to count the passcode and time digit
int tCounter = 1;
int pCounter = 1;

//Variable for final time/passcode entry
int passcodeHrs;
int passcodeMins;

//Alarm time
int alarmHr = 17;
int alarmMin = 33;


// Initialize keypad
const byte ROWS = 4; //four rows
const byte COLS = 3; //four columns
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'#','0','*'}
};

byte rowPins[ROWS] = {14, 15, 16, 17}; 
byte colPins[COLS] = {10, 9, 8}; 

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

char key = keypad.getKey();
KeypadState getState();

// Initialize LCD
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// Initialize Tone
Tone alarmTone;

// Enter date, time, and passcode when alarm sounds 
boolean enterTime = false;
boolean enterDate = false;
boolean enterPass = false;

// Alarm status
boolean alarmOn = false;

// Time without delay
long interval = 1000;
long previousMillis = 0;
unsigned long currentMillis = millis();

void setup()  {
  Serial.begin(9600);
  setSyncProvider(RTC.get);   // the function to get the time from the RTC
  if(timeStatus() != timeSet)
    Serial.println("Unable to sync with the RTC");
  else
    Serial.println("RTC has set the system time");      

  lcd.begin(16,2);
  lcd.clear();

  alarmTone.begin(6);

}

void loop(){
   digitalClockDisplay();  
    alarmCheck();
    delay(1000);
  
  /* This doesnt seem to want to work, also overflow issues so delay is used
  
  if(currentMillis - previousMillis > interval){ 
    digitalClockDisplay();  
    alarmCheck();
    previousMillis = currentMillis;
  
  } */

}

//Disply the time on the LCD

void digitalClockDisplay(){
  setSyncProvider(RTC.get);
  printHours(hour());
  printMinutes(minute());
  printSeconds(second());
}

//How to print hours
void printHours(int hrs){
  lcd.setCursor(4,0);
  if(hrs < 10){
    lcd.print("0");
    lcd.setCursor(5,0);
    lcd.print(hrs);
  }
  else{
    lcd.print(hrs);
  }
}

//How to print mins
void printMinutes(int mins){
  lcd.setCursor(6,0);
  lcd.print(":");
  lcd.setCursor(7,0);
  if(mins < 10){
    lcd.print('0');
    lcd.setCursor(8,0);
    lcd.print(mins);
  }
  else{
    lcd.print(mins);
  }
}

//How to print secs
void printSeconds(int secs){
  lcd.setCursor(9,0);
  lcd.print(":");
  lcd.setCursor(10,0);
  if(secs < 10){
    lcd.print("0");
    lcd.setCursor(11,0);
    lcd.print(secs);
  }
  else{
    lcd.print(secs);
  }
}

//Check if the alam time == curent time
void alarmCheck(){
  lcd.setCursor(5,1);
  if(alarmHr == hour() && alarmMin == minute()){
    alarmOn = true;
  }
  if(alarmOn == true){
    alarm();
  }
}

//Sound the alarm
void alarm(){
  if (alarmOn == true){
    alarmTone.play(NOTE_A4);
    enterTime = true;
    TimeEntry();
  }
}

//Enter current time. hours and minutes 
void TimeEntry(){
  if(enterTime == true){
    digitalClockDisplay();
    lcd.setCursor(0,1);
    lcd.print("Enter Time");
    lcd.setCursor(11,1);
    lcd.blink();
    tCounter = 1;
    if (tCounter == 1){ 
     if (key != NO_KEY){
      timeEntry1 = key;                //First digit of time entry is the first key pressed 
      lcd.print(timeEntry1);
      lcd.setCursor(12,1);
      tCounter = 2;
    }
   }
      else{
      if (tCounter == 2){
        if (key != NO_KEY){
          timeEntry2 = key;            //Second digit of time entry is second key pressed
          lcd.print(timeEntry2);
          lcd.setCursor(13,1);
          lcd.print(":");
          lcd.setCursor(14,1);
          tCounter = 3;
        }
      }
          else{
          if(tCounter == 3){
            if(key != NO_KEY){
              timeEntry3 = key;        //etc.
              lcd.print(timeEntry3);    
              lcd.setCursor(15,1);
              tCounter = 4;
            }
          }
           else{   
              if(tCounter == 4){
                if(key != NO_KEY){
                  timeEntry4 = key;
                  lcd.print(timeEntry4);
                  lcd.noBlink();
                  tCounter = 1;
                }
              }
            }
          }
        }
      }
    
  if (timeEntry1 == 0){
    passcodeHrs = timeEntry2;
}
  else{
    passcodeHrs = (timeEntry1 * 10) + timeEntry2;
  }
  if (timeEntry3 == 0){
    passcodeMins = timeEntry4;
}
  else{
    passcodeMins = (timeEntry3 * 10) + timeEntry4;
}
  if (passcodeHrs == hour() && passcodeMins == minute()){
    enterPass = true;
    PassEntry();
  }
  else{
    return;
  }
}

void PassEntry(){
  if (enterPass == true){
    lcd.clear();
    digitalClockDisplay();
    lcd.setCursor(1,1);
    lcd.print("Passcode");
    lcd.setCursor(9,1);
    lcd.blink();
    if (pCounter == 1){
     if (key != NO_KEY){
      passEntry1 = key;        //Same idea as time entry
      lcd.print("*");
      lcd.setCursor(10,1);
      pCounter = 2;
     }
    }
     else{
      if (pCounter == 2){
        if (key != NO_KEY){
          passEntry2 = key;
          pCounter = 3;
          lcd.print("*");
          lcd.setCursor(11,1);
        }
      }
         else{
          if (pCounter == 3){
            if (key != NO_KEY){
              passEntry3 = key;
              pCounter = 4;
              lcd.print("*");
              lcd.setCursor(12,1);
            }
          }
             else{ 
              if (pCounter == 4){
                if (key != NO_KEY){
                  passEntry4 = key;
                  pCounter = 1;
                  lcd.print("*");
                  lcd.noBlink();
                }
              }
            }
          }
        }
      }
   if (passEntry1 == PassCodeDigit1 && passEntry2 == PassCodeDigit2 && passEntry3 == PassCodeDigit3 && passEntry4 == PassCodeDigit4){
    alarmOn = false;
    lcd.clear();
  }
  else{
    return;
  }
}
char key = keypad.getKey();

You only put a value in key once during initialization. getKey needs to be called again to get new keys.

Also, please take a look at arrays. It is bad practice to duplicate the code to handle each key/digit since you then need to make any future change in multiple places.

Maybe I'm reading this wrong, but it looks to me like there could be some simplification here:

void alarmCheck(){
  lcd.setCursor(5,1);
  if(alarmHr == hour() && alarmMin == minute()){
    alarmOn = true;
  }
  if(alarmOn == true){
    alarm();
  }
}

//Sound the alarm
void alarm(){
  if (alarmOn == true){

Thanks for the quick replies. As far as some of the code goes, it is quite redundant. However I had some problems with the minutes rolling over and the sketch not executing properly.

drhex, i am not quite sure I understand. Do I need to define getKey inside each function or just call it each time I want a new key? I have a very similar sketch that I used to test the keypad entering 4 digit passcodes that works as expected where getKey is defined only once.

thanks for your help

Do I need to define getKey inside each function or just call it each time I want a new key?

You need to call the function for each key that you want to read.

I have a very similar sketch that I used to test the keypad entering 4 digit passcodes that works as expected where getKey is defined only once.

Does that code call getKey in loop()?

Fixed the code calling keypad.getKey() to call the key. However any input from the keypad results in the LCD reading 0 : . Here is the new code. I've looked it over a few times and it seems to me that everything is in order but it still prints the wrong input. Thanks for the help.

/*
 * Alarm Clock
 * Displays Date and Time On LCD Screen
 * Enter Passcode To Turn Off Alarm
 */

#include <Time.h>  
#include <Wire.h>  
#include <DS1307RTC.h>
#include <LiquidCrystal.h>
#include <Tone.h>
#include <Keypad.h>


// 4-Digit passcode to turn off the alarm
int PassCodeDigit1 = 1;
int PassCodeDigit2 = 2;
int PassCodeDigit3 = 3;
int PassCodeDigit4 = 4;

// Varibales to hold time entry passcode
int timeEntry1;
int timeEntry2;
int timeEntry3;
int timeEntry4;
int passEntry1;
int passEntry2;
int passEntry3;
int passEntry4;

//Variables to count the passcode and time digit
int tCounter = 1;
int pCounter = 1;

//Variable for final time/passcode entry
int passcodeHrs;
int passcodeMins;

//Alarm time
int alarmHr = 18;
int alarmMin = 45;


// Initialize keypad
const byte ROWS = 4; //four rows
const byte COLS = 3; //four columns
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};

byte rowPins[ROWS] = {14, 15, 16, 17}; 
byte colPins[COLS] = {10, 9, 8}; 

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

// Initialize LCD
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// Initialize Tone
Tone alarmTone;

// Enter date, time, and passcode when alarm sounds 
boolean enterTime = false;
boolean enterDate = false;
boolean enterPass = false;

// Alarm status
boolean alarmOn = false;

// Time without delay
long interval = 1000;
long previousMillis = 0;
unsigned long currentMillis = millis();

void setup()  {
  Serial.begin(9600);
  setSyncProvider(RTC.get);   // the function to get the time from the RTC
  if(timeStatus() != timeSet)
    Serial.println("Unable to sync with the RTC");
  else
    Serial.println("RTC has set the system time");      

  lcd.begin(16,2);
  lcd.clear();

  alarmTone.begin(6);

}

void loop(){
    digitalClockDisplay();  
    alarmCheck();
  
  /* This doesnt seem to want to work, also overflow issues so delay is used
  
  if(currentMillis - previousMillis > interval){ 
    digitalClockDisplay();  
    alarmCheck();
    previousMillis = currentMillis;
  
  } */

}

//Disply the time on the LCD

void digitalClockDisplay(){
  setSyncProvider(RTC.get);
  printHours(hour());
  printMinutes(minute());
  printSeconds(second());
}

//How to print hours
void printHours(int hrs){
  lcd.setCursor(4,0);
  if(hrs < 10){
    lcd.print("0");
    lcd.setCursor(5,0);
    lcd.print(hrs);
  }
  else{
    lcd.print(hrs);
  }
}

//How to print mins
void printMinutes(int mins){
  lcd.setCursor(6,0);
  lcd.print(":");
  lcd.setCursor(7,0);
  if(mins < 10){
    lcd.print('0');
    lcd.setCursor(8,0);
    lcd.print(mins);
  }
  else{
    lcd.print(mins);
  }
}

//How to print secs
void printSeconds(int secs){
  lcd.setCursor(9,0);
  lcd.print(":");
  lcd.setCursor(10,0);
  if(secs < 10){
    lcd.print("0");
    lcd.setCursor(11,0);
    lcd.print(secs);
  }
  else{
    lcd.print(secs);
  }
}

//Check if the alam time == curent time
void alarmCheck(){
  lcd.setCursor(5,1);
  if(alarmHr == hour() && alarmMin == minute()){
    alarmOn = true;
  }
  if(alarmOn == true){
    alarm();
  }
}

//Sound the alarm
void alarm(){
  if (alarmOn == true){
    alarmTone.play(NOTE_A4);
    enterTime = true;
    TimeEntry();
  }
}

//Enter current time. hours and minutes 
void TimeEntry(){
  if(enterTime == true){
    digitalClockDisplay();
    lcd.setCursor(0,1);
    lcd.print("Enter Time");
    lcd.setCursor(11,1);
    lcd.blink();
    if (tCounter == 1){ 
     if (keypad.getKey() != NO_KEY){
      timeEntry1 = keypad.getKey();                //First digit of time entry is the first key pressed 
      lcd.print(timeEntry1);
      lcd.setCursor(12,1);
      tCounter = 2;
    }
   }
      else{
      if (tCounter == 2){
        if (keypad.getKey() != NO_KEY){
          timeEntry2 = keypad.getKey();            //Second digit of time entry is second key pressed
          lcd.print(timeEntry2);
          lcd.setCursor(13,1);
          lcd.print(":");
          lcd.setCursor(14,1);
          tCounter = 3;
        }
      }
          else{
          if(tCounter == 3){
            if(keypad.getKey() != NO_KEY){
              timeEntry3 = keypad.getKey();        //etc.
              lcd.print(timeEntry3);    
              lcd.setCursor(15,1);
              tCounter = 4;
            }
          }
           else{   
              if(tCounter == 4){
                if(keypad.getKey() != NO_KEY){
                  timeEntry4 = keypad.getKey();
                  lcd.print(timeEntry4);
                  lcd.noBlink();
                  tCounter = 1;
                }
              }
            }
          }
        }
      }
    
  if (timeEntry1 == 0){
    passcodeHrs = timeEntry2;
}
  else{
    passcodeHrs = (timeEntry1 * 10) + timeEntry2;
  }
  if (timeEntry3 == 0){
    passcodeMins = timeEntry4;
}
  else{
    passcodeMins = (timeEntry3 * 10) + timeEntry4;
}
  if (passcodeHrs == hour() && passcodeMins == minute()){
    enterPass = true;
    PassEntry();
  }
  else{
    return;
  }
}

void PassEntry(){
  if (enterPass == true){
    lcd.clear();
    digitalClockDisplay();
    lcd.setCursor(1,1);
    lcd.print("Passcode");
    lcd.setCursor(9,1);
    lcd.blink();
    if (pCounter == 1){
     if (keypad.getKey() != NO_KEY){
      passEntry1 = keypad.getKey();        //Same idea as time entry
      lcd.print("*");
      lcd.setCursor(10,1);
      pCounter = 2;
     }
    }
     else{
      if (pCounter == 2){
        if (keypad.getKey() != NO_KEY){
          passEntry2 = keypad.getKey();
          pCounter = 3;
          lcd.print("*");
          lcd.setCursor(11,1);
        }
      }
         else{
          if (pCounter == 3){
            if (keypad.getKey() != NO_KEY){
              passEntry3 = keypad.getKey();
              pCounter = 4;
              lcd.print("*");
              lcd.setCursor(12,1);
            }
          }
             else{ 
              if (pCounter == 4){
                if (keypad.getKey() != NO_KEY){
                  passEntry4 = keypad.getKey();
                  pCounter = 1;
                  lcd.print("*");
                  lcd.noBlink();
                }
              }
            }
          }
        }
      }
   if (passEntry1 == PassCodeDigit1 && passEntry2 == PassCodeDigit2 && passEntry3 == PassCodeDigit3 && passEntry4 == PassCodeDigit4){
    alarmOn = false;
    alarm();             //turn the alarm off
    lcd.clear();
  }
  else{
    return;
  }
}

As I'm reading through your code, I notice something that I thought I'd mention.

You have functions like printHours(), printMinutes(), etc. Presumably, these were functions that were written early, and tested, and you know they work.

Instead of having to scroll past them to get to the code that is having issues, might I respectfully suggest that you put utility type, fully tested functions at the bottom of the sketch. This means that the code that is the heart of the application is at the top.

Now, for your issue. You have this code in TimeEntry():

if (tCounter == 1){
     if (keypad.getKey() != NO_KEY){
      timeEntry1 = keypad.getKey();                //First digit of time entry is the first key pressed
      lcd.print(timeEntry1);
      lcd.setCursor(12,1);
      tCounter = 2;
    }

Whoops, did you get a key entered in time? I didn't think so.

What else should the Arduino be doing while waiting for a new time to be entered? I don't see that it should be doing anything, so there should be a while loop that does nothing until a key is pressed.

You have a number of places where you are expecting a key press. Create a function to get the key press and return the pressed key. You could check when the function is called, and only wait for a fixed or variable amount of time, or you could wait forever for the key press. That's your choice, but the function is necessary.

alarmOn is a boolean. In alarmCheck(), you have this:

  if(alarmOn == true)

The value in alarmOn is compared to the value true. If they match, the return value from the equality operator is true, to the body of the if test is executed. If they don't match, the return value from the equality operator is false, to the body of the if test is not executed. Since the return value from the equality operator is exactly the same as the value in alarmOn, you could (and should) simply write:

  if(alarmOn)

In alarm(), you start playing a note. Does that note then play forever, or does it stop after a fixed period of time? I've never used the Tone class, so I don't know, but I don't see anywhere where you tell it to shut up, so I presume it plays for a fixed period of time. If not, you might want it to shut up at some point.

Thanks for your help PaulS. I am not sure I completely understand what you are suggesting. I have not had time to test, but are you suggesting something along the lines of this?

//get pressed key and return
void keyPress(){
  if (keypad.getKey() != NO_KEY){
    key = keypad.getKey();
  }
}



//Enter current time. hours and minutes 
void TimeEntry(){
  if(enterTime){
    digitalClockDisplay();
    lcd.setCursor(0,1);
    lcd.print("Enter Time");
    if (tCounter == 1){ 
      lcd.setCursor(11,1);
      lcd.blink();
      while(keypad.getKey == NO_KEY){
      digitalClockDisplay();   //keep showing the current time
    }
      keyPress();
      timeEntry1 = key;        //First digit of time entry is the first key pressed 
      lcd.print(timeEntry1);
      lcd.setCursor(12,1);
      tCounter = 2;
    }

You could check when the function is called, and only wait for a fixed or variable amount of time, or you could wait forever for the key press.

I don't quite understand what you mean. Do you mean check when the function that returns a key is called and wait some time for the next key press?

I don't see anywhere where you tell it to shut up, so I presume it plays for a fixed period of time.

Yeah, I'll fix the alarm to turn off after the passcode is input. Just trying to fix one thing at a time.

void keyPress(){
  if (keypad.getKey() != NO_KEY){
    key = keypad.getKey();
  }
}

This code still won't wait for a key press.

void keyPress(){
  while ((key = keypad.getKey()) == NO_KEY)
  {
     // Do nothing
  }
  // We get here only when there has been a key press
}

This code will wait forever for a key press. It could be modified to wait only for a fixed length of time, if that ever becomes an issue.

In your alarm example, when the alarm goes off, the user is expected to enter a new time for the next alarm. Perhaps the user wants the alarm to go off again at the same time tomorrow. Rather than have to enter the same time again, the user could just do nothing for 15 seconds, for example. Having gotten no new time, you'd then reset the alarm for the same time tomorrow.

I see that you have added this

      while(keypad.getKey == NO_KEY){
      digitalClockDisplay();   //keep showing the current time
    }

While this is good, there is no indication to the user that pressing a button will do anything, or what is expected to be entered.

I'd suggest that rather than keep trying to fix this code, you re-examine what you want to do, using pencil and paper to list the steps, or to draw a flow chart. Having an overall vision, and a map makes it much easier to get where you want to go.

Maybe I should have been more clear on how the alarm clock is (supposed) to function. The alarm time is set to some time in the sketch. The alarm will go off at this time everyday. When the alarm goes off the user enters the current time on they keypad. The alarm will not turn off until the time and a passcode are entered. This is to avoid pressing a single button in a half-sleep-state and going back to sleep. The alarm then turns off and waits until that time again the next day and repeats.

I reexamined the test code that I have working for the key press/return and realized that it works because it is in void loop. Instead of doing nothing over and over until a key is pressed, it asks for the first key over and over until it is pressed. Then the second and so on. I had a chance to test both of these ideas and they both give the same result. When any key is pressed the display still shows 0 : (zero blank : blank blank).

Here is the revised code. Maybe (hopefully) something simple is missing or in the wrong place. Thanks again for the help.

/*
 * Alarm Clock
 * Displays Date and Time On LCD Screen
 * Enter Passcode To Turn Off Alarm
 */

#include <Time.h>  
#include <Wire.h>  
#include <DS1307RTC.h>
#include <LiquidCrystal.h>
#include <Tone.h>
#include <Keypad.h>


// 4-Digit passcode to turn off the alarm
int PassCodeDigit1 = 1;
int PassCodeDigit2 = 2;
int PassCodeDigit3 = 3;
int PassCodeDigit4 = 4;

// Varibales to hold time entry passcode
int timeEntry1;
int timeEntry2;
int timeEntry3;
int timeEntry4;
int passEntry1;
int passEntry2;
int passEntry3;
int passEntry4;
int key;

//Variables to count the passcode and time digit
int tCounter = 1;
int pCounter = 1;

//Variable for final time/passcode entry
int passcodeHrs;
int passcodeMins;

//Alarm time
int alarmHr = 16;
int alarmMin = 40;


// Initialize keypad
const byte ROWS = 4; //four rows
const byte COLS = 3; //four columns
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'#','0','*'}
};

byte rowPins[ROWS] = {14, 15, 16, 17}; 
byte colPins[COLS] = {10, 9, 8}; 

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

// Initialize LCD
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// Initialize Tone
Tone alarmTone;

// Enter date, time, and passcode when alarm sounds 
boolean enterTime = false;
boolean enterDate = false;
boolean enterPass = false;

//While loop
boolean timeLoop = false;
boolean passLoop = false;

// Alarm status
boolean alarmOn = false;

// Time without delay
long interval = 1000;
long previousMillis = 0;
unsigned long currentMillis = millis();

void setup()  {
  Serial.begin(9600);
  setSyncProvider(RTC.get);   // the function to get the time from the RTC
  if(timeStatus() != timeSet)
    Serial.println("Unable to sync with the RTC");
  else
    Serial.println("RTC has set the system time");      

  lcd.begin(16,2);
  lcd.clear();

  alarmTone.begin(6);

}

void loop(){
    digitalClockDisplay();  
    alarmCheck();
}

//get pressed key and return
void keyPress(){
  if (keypad.getKey() != NO_KEY){
    key = keypad.getKey();
  }
}

//Enter current time. hours and minutes 
void TimeEntry(){
  if(enterTime){
    digitalClockDisplay();
    lcd.setCursor(0,1);
    lcd.print("Enter Time");
    while(timeLoop){
    if (tCounter == 1){ 
      lcd.setCursor(11,1);
      lcd.blink();
      keyPress();
      timeEntry1 = key;        //First digit of time entry is the first key pressed 
      lcd.print(timeEntry1);
      lcd.setCursor(12,1);
      tCounter = 2;
    }
      else{
      if (tCounter == 2){
          keyPress();           //Second digit of time entry is second key pressed
          timeEntry2 = key;
          lcd.print(timeEntry2);
          lcd.setCursor(13,1);
          lcd.print(":");
          lcd.setCursor(14,1);
          tCounter = 3;
      }
          else{
          if(tCounter == 3){
              keyPress();
              timeEntry3 = key;
              lcd.print(timeEntry3);    
              lcd.setCursor(15,1);
              tCounter = 4;
            }

           else{   
              if(tCounter == 4){
                  keyPress();                  
                  timeEntry4 = key;                
                  lcd.print(timeEntry4);
                  lcd.noBlink();
                  tCounter = 1;
                  timeLoop = false;
              }
            }
          }
        }
      }
  if (timeEntry1 == 0){
    passcodeHrs = timeEntry2;
}
  else{
    passcodeHrs = (timeEntry1 * 10) + timeEntry2;
  }
  if (timeEntry3 == 0){
    passcodeMins = timeEntry4;
}
  else{
    passcodeMins = (timeEntry3 * 10) + timeEntry4;
}
  if (passcodeHrs == hour() && passcodeMins == minute()){
    enterPass = true;
    PassEntry();
    passLoop = true;
  }
  else{
    return;
  }
 }
}

void PassEntry(){
  if (enterPass){
    lcd.clear();
    digitalClockDisplay();
    lcd.setCursor(1,1);
    lcd.print("Passcode");
    lcd.setCursor(9,1);
    lcd.blink();
    while(passLoop){
    if (pCounter == 1){
      keyPress();
      passEntry1 = key;        //Same idea as time entry
      lcd.print("*");
      lcd.setCursor(10,1);
      pCounter = 2;
     }
    
     else{
      if (pCounter == 2){
          keyPress();
          passEntry2 = key;
          pCounter = 3;
          lcd.print("*");
          lcd.setCursor(11,1);
        }
         else{
          if (pCounter == 3){
              keyPress();
              passEntry3 = key;
              pCounter = 4;
              lcd.print("*");
              lcd.setCursor(12,1);
            
          }
             else{ 
              if (pCounter == 4){
                  keyPress();
                  passEntry4 = key;
                  pCounter = 1;
                  lcd.print("*");
                  lcd.noBlink();
                  passLoop = false;
                }
              }
            }
          }
        }
      
   if (passEntry1 == PassCodeDigit1 && passEntry2 == PassCodeDigit2 && passEntry3 == PassCodeDigit3 && passEntry4 == PassCodeDigit4){
    alarmOn = false;
    alarm();             //turn the alarm off
    lcd.clear();
  }
  else{
    return;
  }
 }
}


//Disply the time on the LCD

void digitalClockDisplay(){
  setSyncProvider(RTC.get);
  printHours(hour());
  printMinutes(minute());
  printSeconds(second());
}

//How to print hours
void printHours(int hrs){
  lcd.setCursor(4,0);
  if(hrs < 10){
    lcd.print("0");
    lcd.setCursor(5,0);
    lcd.print(hrs);
  }
  else{
    lcd.print(hrs);
  }
}

//How to print mins
void printMinutes(int mins){
  lcd.setCursor(6,0);
  lcd.print(":");
  lcd.setCursor(7,0);
  if(mins < 10){
    lcd.print('0');
    lcd.setCursor(8,0);
    lcd.print(mins);
  }
  else{
    lcd.print(mins);
  }
}

//How to print secs
void printSeconds(int secs){
  lcd.setCursor(9,0);
  lcd.print(":");
  lcd.setCursor(10,0);
  if(secs < 10){
    lcd.print("0");
    lcd.setCursor(11,0);
    lcd.print(secs);
  }
  else{
    lcd.print(secs);
  }
}

//Check if the alam time == curent time
void alarmCheck(){
  lcd.setCursor(5,1);
  if(alarmHr == hour() && alarmMin == minute()){
    alarmOn = true;
  }
  if(alarmOn){
    alarm();
    timeLoop = true;
 }
}

//Sound the alarm
void alarm(){
  if (alarmOn == true){
    alarmTone.play(NOTE_A4);
    enterTime = true;
    TimeEntry();
  }
}

In digitalClockDisplay(), you call setSyncProvider(). Potentially millions of times per second, you are registering the function to be called when the Arduino time needs to be synced. This needs to be done once, in setup(), not every time you want to display the time.

Look at your while loop in TimeEntry. tCounter is initially 1. Since tCounter is 1, the cursor is positioned to 11, 1, and set blinking. Then, there is a function called to get a key press. The key being pressed at the time that the function is called is stored in timeEntry1 and written to the LCD, and tCounter is incremented.

What happens if no key is being pressed when the keyPress function is called? The value in key, whatever it is, is not changed, and the function returns.

So, very quickly, and I mean VERY quickly, 4 calls are made to see if a key is being pressed. This happens so quickly that you can not react fast enough when the alarm goes off to even begin moving your finger before the TimeEntry function ends.

Can't you see that keyPress needs to wait for a key to be pressed?