A Countdown Timer with Buttons to Activate

Hey everyone! I’m programming a countdown timer to act as the timer for an escape room. Their goal is to press button2 and “disarm” it (which will trigger the “Mission Successful”) within the hour.

The issue I’m having right now, is that if you press button3 (which I’ve set up just to start the timer, the timer will start, but then stops two seconds later.

I’m not entirely sure what’s going on, any suggestions would be appreciated!

Here’s the button to start the countdown timer:

 if (buttonState3 != lastbuttonState3) {
      
     lcd.clear();
     lcd.setCursor(1,0);
     lcd.print("Time remaining:");
     lcd.setCursor(6,1);
     lcd.print(":");
     lcd.setCursor(9,1);
     lcd.print(":");

 S--;
 delay(1000);
  
 if(S<0)
 {
   M--;
   S=59;
 }
 if(M<0)
 {
   H--;
   M=59;
 }
 if(H<0) { H=23; M=59; S=59; } if(M>9)
 {
   lcd.setCursor(7,1);
   lcd.print(M);
 }
 else
 {
   lcd.setCursor(7,1);
   lcd.print("0"); 
   lcd.setCursor(8,1);
   lcd.print(M);
   lcd.setCursor(9,1);
   lcd.print(":");
 }
  
 if(S>9)
 {
   lcd.setCursor(10,1);
   lcd.print(S);
 }
 else
 {
   lcd.setCursor(10,1);
   lcd.print("0"); 
   lcd.setCursor(11,1);
   lcd.print(S);
   lcd.setCursor(12,1);
   lcd.print(" ");
 }
  
 if(H>9)
 {
   lcd.setCursor(4,1);
   lcd.print (H);
 }
 else
 {
   lcd.setCursor(4,1);
   lcd.print("0"); 
   lcd.setCursor(5,1);
   lcd.print(H);
   lcd.setCursor(6,1);
   lcd.print(":");
 }
  
lastbuttonState3 = buttonState3;
 
  }
  }

And here’s the whole code:

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display
int S = 0; // count seconds 
int M = 0; // count minutes
int H = 1; // count hours

const int button2 = 2;
const int button3 = 3;
const int ledPin =  13;
int buttonState2 = 0; 
int buttonState3 = 0;
int lastbuttonState2 = 0;
int lastbuttonState3 = 0;

void setup()
{
  lcd.init();
  lcd.backlight();

  pinMode(ledPin, OUTPUT);
  pinMode(button2, INPUT);
  pinMode(button3, INPUT);

}

void loop()
{
   buttonState2 = digitalRead(button2);
   buttonState3 = digitalRead(button3);




   if (buttonState2 != lastbuttonState2) {
     lcd.clear();
     lcd.setCursor(4,0);
     lcd.print("Mission");
     lcd.setCursor(2,1);
     lcd.print("Successful!");
         lastbuttonState2 = buttonState2;}





 
    if (buttonState3 != lastbuttonState3) {
      
     lcd.clear();
     lcd.setCursor(1,0);
     lcd.print("Time remaining:");
     lcd.setCursor(6,1);
     lcd.print(":");
     lcd.setCursor(9,1);
     lcd.print(":");

 S--;
 delay(1000);
  
 if(S<0)
 {
   M--;
   S=59;
 }
 if(M<0)
 {
   H--;
   M=59;
 }
 if(H<0) { H=23; M=59; S=59; } if(M>9)
 {
   lcd.setCursor(7,1);
   lcd.print(M);
 }
 else
 {
   lcd.setCursor(7,1);
   lcd.print("0"); 
   lcd.setCursor(8,1);
   lcd.print(M);
   lcd.setCursor(9,1);
   lcd.print(":");
 }
  
 if(S>9)
 {
   lcd.setCursor(10,1);
   lcd.print(S);
 }
 else
 {
   lcd.setCursor(10,1);
   lcd.print("0"); 
   lcd.setCursor(11,1);
   lcd.print(S);
   lcd.setCursor(12,1);
   lcd.print(" ");
 }
  
 if(H>9)
 {
   lcd.setCursor(4,1);
   lcd.print (H);
 }
 else
 {
   lcd.setCursor(4,1);
   lcd.print("0"); 
   lcd.setCursor(5,1);
   lcd.print(H);
   lcd.setCursor(6,1);
   lcd.print(":");
 }
  
lastbuttonState3 = buttonState3;
 
  }
  }

How are your buttons wired up? You have them declared as INPUT so that requires external pull-up/pull-down resistors? Are they present? Also, buttons are noisy, you have no debouncing in your code. When you detect a transistion, you should delay 25-50 msec so you don't get multiple false positive hits.

You can also simply your code by making your timer just track seconds. Then, every second, decrement the countdown and then convert this value into H/M/S.

I would also suggest you use better names for your buttons. 'button2' just because it is connected to pin2 is a poor choice. Maybe something like 'disarmButton' that describes the function.

did you forget a brace, “}”?

all that code that decrements H:M:S is conditional on a button state change. if there’s no button press, it doesn’t execute

shouldn’t your button 3 reset the timer, code outside your button state checks check if the timer is not zero and decrement it and if the timer reaches zero, report a failure?i