Alarm Clock with snooze button. Is it possible?

Hi. Does anyone know if it is possible to make the button in my code operate like a snooze button? Currently when I press the button it stops the buzzer which is what I had intended but it does not make the buzzer go high again after delay(60000) like I hoped it hoped it would.

I have attempted to replace the delay with millis but I must have made a mistake. Can anyone help please?

#include <Wire.h>                   // for I2C communication
#include <LiquidCrystal_I2C.h>      // for LCD
#include <RTClib.h>                 // for RTC
#define Alarm3Pin 3

const int buttonPin = 4;

int buttonState = 0;


LiquidCrystal_I2C lcd(0x27, 16, 2); // create LCD with I2C address 0x27, 16 characters per line, 2 lines
RTC_DS3231 rtc;                     // create rtc for the DS3231 RTC module, address is fixed at 0x68


char daysOfTheWeek[7][12] = {
  "Sunday",
  "Monday",
  "Tuesday",
  "Wednesday",
  "Thursday",
  "Friday",
  "Saturday"
};



void setup()
{
  pinMode(Alarm3Pin,OUTPUT);
  pinMode(buttonPin, INPUT);

  Serial.begin(9600);
  Serial.println("Initialize rtc");;
  while (!Serial) ; // wait for Arduino Serial Monitor
  
  lcd.init();       // initialize lcd
  lcd.backlight();  // switch-on lcd backlight
  lcd.clear();  // clear LCD display
  rtc.begin();       // initialize rtc
  
  //rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); 
}



void loop()
{
DateTime now = rtc.now();

    if (now.hour() == 20 && now.minute() == 58 && now.second()==00)
    {
      digitalWrite(Alarm3Pin,HIGH);
      delay(60000);
      digitalWrite(Alarm3Pin,LOW);
    }

    // read the state of the pushbutton value:
    buttonState = digitalRead(buttonPin);

    
    // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
    if (buttonState == HIGH) 
    {
    // turn Alarm3Pin off:
    digitalWrite(Alarm3Pin, LOW);
    delay(60000);
    digitalWrite(Alarm3Pin,HIGH);
    delay(60000);
    digitalWrite(Alarm3Pin, LOW);
    }


  if (!rtc.begin()) lcd.print("error");
  if (now.day() < 10) lcd.print("0");
  lcd.print(now.day(), DEC);
  Serial.print(now.day(), DEC);
  lcd.print('/');
  Serial.print('/');
  if (now.month() < 10) lcd.print("0");
  if (now.month() < 10) Serial.print("0");
  lcd.print(now.month(), DEC);
  Serial.print(now.month(), DEC);
  lcd.print('/');
  Serial.print('/');
  lcd.print(now.year(), DEC);
  Serial.print(now.year(), DEC);
  lcd.print(" (");
  Serial.print(" (");
  lcd.print(daysOfTheWeek[now.dayOfTheWeek()]);
  Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
  lcd.print(") ");
  Serial.print(") ");
  if (now.hour() < 10) lcd.print("0");
  lcd.print(now.hour(), DEC);
  Serial.print(now.hour(), DEC);
  lcd.print(':');
  Serial.print(':');
  if (now.minute() < 10) lcd.print("0");
  lcd.print(now.minute(), DEC);
  Serial.print(now.minute(), DEC);
  lcd.print(':');
  Serial.print(':');
  if (now.second() < 10) lcd.print("0");
  lcd.println(now.second(), DEC);
  Serial.println(now.second(), DEC);

  delay(1000); // delay 1 seconds
  lcd.clear();
  lcd.setCursor(0, 0);
  
}

The rtc.begin should be placed in setup. However that doesn't change the alarm on/off.

Use flowcharts, a kind o block diagram, to design the flow of the code. Just hitting the keyboard is no good.

The rtc.begin is placed in the setup. (Or am I being silly)

You're being silly. This line is in loop().

Yes, you forgot to remove "delay()" in dozens of places. You can generally use millis() or delay() for timing, but not both. The method in which each is used, is incompatible with the other.

I completely replaced all reference to delay and used alternative code. (Not the one listed here)

This is the closest i can get to achieving the required outcome.
Currently the button works but as a reset only.

Any ideas how it should look?

Yet didn't tell us. How are we supposed to read your mind?

have removed this line from loop.

This has made no difference

rtc.begin was always in setup.

Button currently works as reset to cancel initial 60000 delay.
Any other ideas what it might be?

Please, post your updated code. The code you want us to evaluate.

Are you sure??? I don't see any way to stop the buzzer from sounding for a full minute when the alarm goes off:

It appears that when you press the button, the buzzer will be off for 60 seconds, and then on for 60 seconds, before anything else happens:

Yes, you can have a button that turns off the alarm for a specified amount of time without clearing the alarm, but not by using delay().

What is this down in loop?

My apologies. I have been working on this relentlessly for days. And its driving me crazy.

Apology accepted. However it really doesn't help solve the problem.

On one point, do you fully understand, when you 'delay(60000)', the processor can't do anything but twiddle its thumbs for a full minute?

When the button is pressed the buzzer goes off. (I'm certain of this)

What you have described

"It appears that when you press the button, the buzzer will be off for 60 seconds, and then on for 60 seconds, before anything else happens"

is exactly what i want to achieve

Fantastic! You can edit the thread title and mark it [solved].

For a while, it sounded like you wanted a "snooze button", which usually turns the alarm off for an interval...

It is not solved

In theory yes i do understand the concept of blocking. But it does not appear to be happening here if i am able to cancel the buzzer within the delay which i can

That might be true, but not in the code you showed us.

Yes, you can't start a 60 second delay and read the button during that time.

So then, is it non-blocking that you don't understand?

1 Like