Countdown Timer Problem

Hi All,

I'm trying to build a countdown timer using a 4x4 membrane keypad for Input and TM1637 7-Segment LED module for display. My problem is I want it to start counting down once I press the tact switch connected to pin 13, which it doesn't do. It just gets stuck to the input number decremented by 1. For example I will input 0025 for it to countdown 25 seconds to zero then press tact switch. It will only get down to 24 then it gets stuck there. Also, I would want to convert the input from the membrane switch to minutes such that if I input 25 and press start, it will have 25:00 display on the 7 segment and countdown to 24:59, 24:58, 24:57...etc. Would also like to add in a tact switch for stop later on.

I am fairly new to Arduino programming so I could use some help. :slight_smile:
Thank you in advance to those who will reply. ;D

Here is the code:

#include <Arduino.h>
#include <TM1637Display.h>
// Module connection pins (Digital Pins)
#define CLK 2
#define DIO 3

int NewKeyPadVal = 0;
const int StartTact = 13;

//-----Tact Switch Input-----
int StartState = 0;
int lastStartState = 0;

//----Input Code Digits-----
int InputDigit1 = 0;
int InputDigit2 = 0;
int InputDigit3 = 0;
int InputDigit4 = 0;

//----------------------

TM1637Display display(CLK, DIO);
uint8_t data[] = { 0xff, 0xff, 0xff, 0xff };

void setup()
{

display.setBrightness(0x01);//MAX - 0x0f

// Selectively set different digits
data[0] = display.encodeDigit(0);
data[1] = display.encodeDigit(0);
data[2] = display.encodeDigit(0);
data[3] = display.encodeDigit(0);
display.setSegments(data);

// initialize I/O pins.
pinMode(A0, OUTPUT); //Relay or LED blinking Output at 0000
pinMode(StartTact, INPUT);//Timer Start
//--------------------------4x4 Keypad------------------
//------4 columns-----
pinMode(A4, OUTPUT);
pinMode(A3, OUTPUT);
pinMode(A2, OUTPUT);
pinMode(A1, OUTPUT);

digitalWrite(A4, HIGH);
digitalWrite(A3, HIGH);
digitalWrite(A2, HIGH);
digitalWrite(A1, HIGH);
//-------4 rows-----------
pinMode(6, INPUT_PULLUP);
pinMode(7, INPUT_PULLUP);
pinMode(8, INPUT_PULLUP);
pinMode(9, INPUT_PULLUP);
//------------------------

}

void loop()
{
display.setSegments(data);
if(InputDigit1 == 0 && InputDigit2 == 0 && InputDigit3 == 0 && InputDigit4 == 0)
{
delay(400);
while(Scan_4x4_keypad() == 19)
{
delay(1);
IfZero();
}
NewKeyPadVal = Scan_4x4_keypad();
InputDigit1 = NewKeyPadVal;
data[0] = display.encodeDigit(InputDigit1);
display.setSegments(data);
//----------------------------------------------------
delay(400);
while(Scan_4x4_keypad() == 19)
delay(1);
NewKeyPadVal = Scan_4x4_keypad();
InputDigit2 = NewKeyPadVal;
data[1] = display.encodeDigit(InputDigit2);
display.setSegments(data);
//----------------------------------------------------
delay(400);
while(Scan_4x4_keypad() == 19)
delay(1);
NewKeyPadVal = Scan_4x4_keypad();
InputDigit3 = NewKeyPadVal;
data[2] = display.encodeDigit(InputDigit3);
display.setSegments(data);

//----------------------------------------------------
delay(400);
while(Scan_4x4_keypad() == 19)
delay(1);
NewKeyPadVal = Scan_4x4_keypad();
InputDigit4 = NewKeyPadVal;
data[3] = display.encodeDigit(InputDigit4);
display.setSegments(data);

//-----------------------------------------------------
StartState = digitalRead(StartTact);
if(StartState != lastStartState){
TimerCount();
}
}
}

int TimerCount()
{
InputDigit4--;
delay(1000);
if(InputDigit4 == -1)
{
InputDigit4 = 9;
InputDigit3--;
}
if(InputDigit3 == -1)
{
InputDigit3 = 9;
InputDigit2--;
}
if(InputDigit2 == -1)
{
InputDigit2 = 9;
InputDigit1--;
}
data[0] = display.encodeDigit(InputDigit1);
data[1] = display.encodeDigit(InputDigit2);
data[2] = display.encodeDigit(InputDigit3);
data[3] = display.encodeDigit(InputDigit4);

}

void IfZero()
{
if(InputDigit1 == 0 && InputDigit2 == 0 && InputDigit3 == 0 )
{
digitalWrite(A0, HIGH);
delay(100);
digitalWrite(A0, LOW);
delay(100);
}

}

int Scan_4x4_keypad()
{
int keypadVal = 19;
//----------Find P1, P2, R, M ----
digitalWrite(A4, LOW);
digitalWrite(A3, HIGH);
digitalWrite(A2, HIGH);
digitalWrite(A1, HIGH);
if(digitalRead(9) == LOW)
keypadVal = 12; // P1 = 12
if(digitalRead(8) == LOW)
keypadVal = 13; // P2 = 13
if(digitalRead(7) == LOW)
keypadVal = 14; // R = 14
if(digitalRead(6) == LOW)
keypadVal = 15;// M = 15
//---------------------------

//----------Find 3,6,9,E ----
digitalWrite(A4, HIGH);
digitalWrite(A3, LOW);
digitalWrite(A2, HIGH);
digitalWrite(A1, HIGH);
if(digitalRead(9) == LOW)
keypadVal = 3;
if(digitalRead(8) == LOW)
keypadVal = 6;
if(digitalRead(7) == LOW)
keypadVal = 9;
if(digitalRead(6) == LOW)
keypadVal = 10;// E
//---------------------------

//----------Find 2,5,8,0 ----
digitalWrite(A4, HIGH);
digitalWrite(A3, HIGH);
digitalWrite(A2, LOW);
digitalWrite(A1, HIGH);
if(digitalRead(9) == LOW)
keypadVal = 2;
if(digitalRead(8) == LOW)
keypadVal = 5;
if(digitalRead(7) == LOW)
keypadVal = 8;
if(digitalRead(6) == LOW)
keypadVal = 0;

//----------Find 1,4,7,C ----
digitalWrite(A4, HIGH);
digitalWrite(A3, HIGH);
digitalWrite(A2, HIGH);
digitalWrite(A1, LOW);
if(digitalRead(9) == LOW)
keypadVal = 1;
if(digitalRead(8) == LOW)
keypadVal = 4;
if(digitalRead(7) == LOW)
keypadVal = 7;
if(digitalRead(6) == LOW)
keypadVal = 11;// C

return keypadVal;
//---------------------------
}

i think your specific problem is that you only call TimerCount(), which looks like it's decrementing a count every second, only once when there is a change in StartState.

        StartState = digitalRead(StartTact);
        if(StartState != lastStartState){
            TimerCount();
        }

i believe you want a change in StartState to set a flag that determines if you run TimerCount() and that flag is reset by TimerCount () when it reaches zero

your code is not indented properly which makes it difficult to see potential bugs. In my professional experience, only constants start with capital letters; variables are always lowercase. You have quite a few significant delays which may throw off your timing

you have a log of redundant code. you may be interested in the attached files for scanning a button matrix.

keypad.cpp (2.84 KB)

keypad.h (484 Bytes)

Hi! Thanks for Replying. I modified the code. The input from tact switch can be detected now and the timer doesn;t start counting down unless you press the tact switch. But still got some problem though, 2nd press of the tact switch should supposedly restart the whole system, which it doesn't do. I tried declaring reset pin as output and write LOW status on it but it doesn't reset the system.

Also, I'm trying to convert the countdown timer into mm:ss display and start decrementing from the last "second" digit. The result of the modified code however is, it only countsdown the first "minute" digit. So basically, if I input 15 and press tact switch my expected result is 15:00, 14:59, 14:58, 14:57...etc.
Right now, it's only looping count the first "minute" digit. So if I input 15, press tact switch the result I'm getting is 15:00, 0F:59, FF:59, EF:59, DF:59, CF:59, BF:59, AF:59, 9F:59, 8F:59, so on and so forth. Only the first digit changes. Really hope someboady can help me out. :confused:

Here's the modified code btw:

#include <Arduino.h>
#include <TM1637Display.h>
// Module connection pins (Digital Pins)
#define CLK 2
#define DIO 3

int NewKeyPadVal = 0;
int buttonPin = 13;
int reset = 12;

//-----Tact Switch Input-----
int buttonPushCounter = 0;
int buttonState = 0;
int lastButtonState = 0;

//----Input Code Digits-----
int InputDigit1 = 0;
int InputDigit2 = 0;
int InputDigit3 = 0;
int InputDigit4 = 0;
//----------------------

TM1637Display display(CLK, DIO);
uint8_t data[] = { 0xff, 0xff, 0xff, 0xff };

void setup()
{

display.setBrightness(0x01);//MAX - 0x0f

// Selectively set different digits
data[0] = display.encodeDigit(0);
data[1] = display.encodeDigit(0);
data[2] = display.encodeDigit(0);
data[3] = display.encodeDigit(0);
display.setSegments(data);

// initialize I/O pins.
pinMode(A0, OUTPUT); //Relay or LED blinking Output at 0000
pinMode(buttonPin, INPUT);//Timer Start Stop
pinMode(reset, OUTPUT);
//--------------------------4x4 Keypad------------------
//------4 columns-----
pinMode(A4, OUTPUT);
pinMode(A3, OUTPUT);
pinMode(A2, OUTPUT);
pinMode(A1, OUTPUT);

digitalWrite(A4, HIGH);
digitalWrite(A3, HIGH);
digitalWrite(A2, HIGH);
digitalWrite(A1, HIGH);
//-------4 rows-----------
pinMode(6, INPUT_PULLUP);
pinMode(7, INPUT_PULLUP);
pinMode(8, INPUT_PULLUP);
pinMode(9, INPUT_PULLUP);
//------------------------
Serial.begin(9600);
}

void loop()
{
display.setSegments(data);

while(InputDigit1 == 0 && InputDigit2 == 0)
{
delay(400);
while(Scan_4x4_keypad() == 19)
{
delay(1);
IfZero();
}
NewKeyPadVal = Scan_4x4_keypad();
InputDigit1 = NewKeyPadVal;
data[0] = display.encodeDigit(InputDigit1);
display.setSegments(data);
//----------------------------------------------------
delay(400);
while(Scan_4x4_keypad() == 19)
delay(1);
NewKeyPadVal = Scan_4x4_keypad();
InputDigit2 = NewKeyPadVal;
data[1] = display.encodeDigit(InputDigit2);
display.setSegments(data);
//----------------------------------------------------
}
buttonState = digitalRead(buttonPin);

// compare the buttonState to its previous state
if (buttonState != lastButtonState) {
// if the state has changed, increment the counter
if (buttonState == HIGH) {
// if the current state is HIGH then the button went from off to on:
buttonPushCounter++;
Serial.println("on");
Serial.print("number of button pushes: ");
Serial.println(buttonPushCounter);
} else {
// if the current state is LOW then the button went from on to off:
Serial.println("off");
}
// Delay a little bit to avoid bouncing
delay(50);
}
// save the current state as the last state, for next time through the loop

// turns on the LED every four button pushes by checking the modulo of the
// button push counter. the modulo function gives you the remainder of the
// division of two numbers:
if (buttonPushCounter % 2 != 0) {
TimerCount();
} else {
digitalWrite(reset, LOW);
}
}

int TimerCount()
{
InputDigit3 = 5;
InputDigit4 = 9;

delay(1000);
for(InputDigit2=InputDigit2; InputDigit2 > -1; InputDigit2--){
InputDigit4--;
if(InputDigit4 == -1)
{
InputDigit4 = 9;
InputDigit3--;
}
if(InputDigit3 == -1)
{
InputDigit3 = 5;
}
}
if(InputDigit2 == -1){
InputDigit1--;
}
data[0] = display.encodeDigit(InputDigit1);
data[1] = display.encodeDigit(InputDigit2);
data[2] = display.encodeDigit(InputDigit3);
data[3] = display.encodeDigit(InputDigit4);
}

void IfZero()
{
if(InputDigit1 == 0 && InputDigit2 == 0 && InputDigit3 == 0 )
{
digitalWrite(A0, HIGH);
delay(100);
digitalWrite(A0, LOW);
delay(100);
}

}

int Scan_4x4_keypad()
{
int keypadVal = 19;
//----------Find P1, P2, R, M ----
digitalWrite(A4, LOW);
digitalWrite(A3, HIGH);
digitalWrite(A2, HIGH);
digitalWrite(A1, HIGH);
if(digitalRead(9) == LOW)
keypadVal = 12; // P1 = 12
if(digitalRead(8) == LOW)
keypadVal = 13; // P2 = 13
if(digitalRead(7) == LOW)
keypadVal = 14; // R = 14
if(digitalRead(6) == LOW)
keypadVal = 15;// M = 15
//---------------------------

//----------Find 3,6,9,E ----
digitalWrite(A4, HIGH);
digitalWrite(A3, LOW);
digitalWrite(A2, HIGH);
digitalWrite(A1, HIGH);
if(digitalRead(9) == LOW)
keypadVal = 3;
if(digitalRead(8) == LOW)
keypadVal = 6;
if(digitalRead(7) == LOW)
keypadVal = 9;
if(digitalRead(6) == LOW)
keypadVal = 10;// E
//---------------------------

//----------Find 2,5,8,0 ----
digitalWrite(A4, HIGH);
digitalWrite(A3, HIGH);
digitalWrite(A2, LOW);
digitalWrite(A1, HIGH);
if(digitalRead(9) == LOW)
keypadVal = 2;
if(digitalRead(8) == LOW)
keypadVal = 5;
if(digitalRead(7) == LOW)
keypadVal = 8;
if(digitalRead(6) == LOW)
keypadVal = 0;

//----------Find 1,4,7,C ----
digitalWrite(A4, HIGH);
digitalWrite(A3, HIGH);
digitalWrite(A2, HIGH);
digitalWrite(A1, LOW);
if(digitalRead(9) == LOW)
keypadVal = 1;
if(digitalRead(8) == LOW)
keypadVal = 4;
if(digitalRead(7) == LOW)
keypadVal = 7;
if(digitalRead(6) == LOW)
keypadVal = 11;// C

return keypadVal;
//---------------------------
}

Your code is pretty long. That is not a problem.

This forum has a functionality to show code in a much easier to read way.
It is called code-section. A code-section can be easily inserted into your normal text.
There are two ways to do this:

first: use the reply-button instead of the quick-reply textwindow.

with clicking the reply-button you get a menu above the textwindow with formatting options.
And an option to insert a code-section. It is the most left button in the formatting menu
and looks like this <|>

second: write the "commands [ code] [ /code]
and insert your code between the two commands

[ code] paste your code here inbetween [ /code]

then it will look like this

 paste your code here inbetween

and even has a "select" function for easy copy & paste exactly just the code

I recommend reading this tutorial

Arduino Programming Course

It is easy to understand and a good mixture between writing about important concepts
and get you going.

best regards Stefan

2nd press of the tact switch should supposedly restart the whole system, which it doesn't do.

when recognizing the button state change, the action of restarting the system needs to be invoked.

Also, I'm trying to convert the countdown timer into mm:ss display and start decrementing from the last "second" digit.

it's easier to deal with values representing hour, minute and seconds and using sprintf to generate ascii chars

 0 2 1 1
 0 2 1 0
 0 2 0 9
 0 2 0 8
 0 2 0 7
 0 2 0 6
 0 2 0 5
 0 2 0 4
 0 2 0 3
 0 2 0 2
 0 2 0 1
 0 2 0 0
 0 1 5 9
 0 1 5 8
 0 1 5 7
 0 1 5 6
 0 1 5 5
 0 1 5 4
 0 1 5 3
 0 1 5 2
 0 1 5 1
 0 1 5 0
 0 1 4 9
 0 1 4 8
 0 1 4 7
 0 1 4 6
 0 1 4 5
 0 1 4 4
 0 1 4 3
 0 1 4 2
 0 1 4 1
 0 1 4 0
 0 1 3 9
 0 1 3 8
 0 1 3 7
 0 1 3 6
 0 1 3 5
 0 1 3 4
 0 1 3 3
 0 1 3 2
 0 1 3 1
 0 1 3 0
 0 1 2 9
 0 1 2 8
 0 1 2 7
 0 1 2 6
 0 1 2 5
 0 1 2 4
 0 1 2 3
 0 1 2 2
 0 1 2 1
 0 1 2 0
 0 1 1 9
 0 1 1 8
 0 1 1 7
 0 1 1 6
 0 1 1 5
 0 1 1 4
 0 1 1 3
 0 1 1 2
 0 1 1 1
 0 1 1 0
 0 1 0 9
 0 1 0 8
 0 1 0 7
 0 1 0 6
 0 1 0 5
 0 1 0 4
 0 1 0 3
 0 1 0 2
 0 1 0 1
 0 1 0 0
 0 0 5 9
int hour   = 2;
int minute = 12;
int second = 0;

// -----------------------------------------------------------------------------
void disp ()
{
    char s[10];
    sprintf (s, "%02d %02d %02d", hour, minute, second);

    Serial.print (" "); Serial.print (s [0]);
    Serial.print (" "); Serial.print (s [1]);
    Serial.print (" "); Serial.print (s [3]);
    Serial.print (" "); Serial.print (s [4]);
    Serial.println ();
}

// -----------------------------------------------------------------------------
void timerCount ()
{
    if (0 > --second)  {
        second = 59;

        if (0 > -- minute)  {
            minute = 59;

            --hour;
        }

        disp ();
    }
}

// -----------------------------------------------------------------------------
void loop()
{
    if (hour)
        timerCount ();
}

// -----------------------------------------------------------------------------
void setup (void) {
    Serial.begin (115200);
}

use code tags, the "</>" top left

StefanL38:
second: write the "commands [ code] [ /code]
and insert your code between the two commands

[ code] paste your code here inbetween [ /code]

then it will look like this

 paste your code here inbetween

Or, even easier. Within the IDE, format your code (Ctrl-T) and then Edit -> Copy for Forum and it will insert the code tags for you. Just paste it in!

gcjr:

int hour   = 2;

int minute = 12;
int second = 0;

// -----------------------------------------------------------------------------
void disp ()
{
    char s[10];
    sprintf (s, "%02d %02d %02d", hour, minute, second);

Serial.print (" "); Serial.print (s [0]);
    Serial.print (" "); Serial.print (s [1]);
    Serial.print (" "); Serial.print (s [3]);
    Serial.print (" "); Serial.print (s [4]);
    Serial.println ();
}

// -----------------------------------------------------------------------------
void timerCount ()
{
    if (0 > --second)  {
        second = 59;

if (0 > -- minute)  {
            minute = 59;

--hour;
        }

disp ();
    }
}

// -----------------------------------------------------------------------------
void loop()
{
    if (hour)
        timerCount ();
}

// -----------------------------------------------------------------------------
void setup (void) {
    Serial.begin (115200);
}




use code tags, the "</>" top left

Hi Greg!

Thank you for replying. The code you have above, how can this be applied if the display is TM1637 7-Segment LED Module? Is there a way to use this code, without having to change my current Scan_4x4_keypad() function? I honestly, do not want to change this keypad code since it's already working.

Somehow, I managed, to get the tact switch to work. It will only begin the countdown process once I hit the tact switch and resets the values to default after 2nd press. However, I'm still stuck on the TimerCount() function. It is still incomplete.

int TimerCount()
{
   min2 = min2 - 1; 
   sec4--;
   delay(1000);
   if(sec4 == -1){
     sec4 = 9;
     sec3--;
   }
   if(sec3 == -1){
     sec3=5;
   }
}

What happens now, is if I input 15 from the membrane switch and press tact switch, it will only display 14:59 after one second and gets stuck there. Unless I press the tact switch 2nd time, that's when it will reset the values to 00:00. With this incomplete TimerCount() code, I was expecting atleast it will countdown on the seconds digits, such that it will display, 14:59, 14:58, 14: 57...so on and so forth. Do you have any idea how to fix this? Hope you can help me out. :slight_smile:

Here is the complete code:

#include <Arduino.h>
#include <TM1637Display.h>
// Module connection pins (Digital Pins)
#define CLK 2
#define DIO 3

int NewKeyPadVal = 0;
int buttonPin = 13;


//-----Tact Switch Input-----
int buttonPushCounter = 0;
int buttonState = 0;
int lastButtonState = 0;

//----Input Code Digits-----
int min1 =  0;
int min2 =  0;
int sec3 =  0;
int sec4 =  0;
int minutes = 0;
int seconds = 0;
//----------------------

TM1637Display display(CLK, DIO);
uint8_t data[] = { 0xff, 0xff, 0xff, 0xff };


void setup() 
{
  
  display.setBrightness(0x01);//MAX - 0x0f

   // Selectively set different digits
  data[0] = display.encodeDigit(0);
  data[1] = display.encodeDigit(0);
  data[2] = display.encodeDigit(0);
  data[3] = display.encodeDigit(0);
  display.setSegments(data);


  
// initialize I/O pins.
   pinMode(A7, OUTPUT); //Relay or LED blinking Output at 0000
   pinMode(buttonPin, INPUT);//Timer Start Stop
//--------------------------4x4 Keypad------------------  
  //------4 columns-----
  pinMode(A4, OUTPUT);
  pinMode(A3, OUTPUT);
  pinMode(A2, OUTPUT);
  pinMode(A1, OUTPUT);

  digitalWrite(A4, HIGH);
  digitalWrite(A3, HIGH);
  digitalWrite(A2, HIGH);
  digitalWrite(A1, HIGH);
  //-------4 rows-----------
  pinMode(6, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  //------------------------ 
Serial.begin(9600);
}

void loop() 
{
display.setSegments(data);

while(min1 == 0 && min2 == 00 && sec3 == 0 && sec4 == 0)
{
  delay(400);
  while(Scan_4x4_keypad() == 19)
  {
  delay(1);
  IfZero();
  }
  NewKeyPadVal = Scan_4x4_keypad();
  min1 = NewKeyPadVal;
  data[0] = display.encodeDigit(min1);
  display.setSegments(data);
//----------------------------------------------------
delay(400);
  while(Scan_4x4_keypad() == 19)
  delay(1);
  NewKeyPadVal = Scan_4x4_keypad();
  min2 = NewKeyPadVal;
  data[1] = display.encodeDigit(min2);
  display.setSegments(data);
//----------------------------------------------------

}
 
buttonState = digitalRead(buttonPin); 
  if (buttonState != lastButtonState) // compare the buttonState to its previous state
  {
    if (buttonState == HIGH) // if the current state is HIGH then the button went from off to on:
    {
      buttonPushCounter++; // if the state has changed, increment the counter
       if (buttonPushCounter % 2 != 0)// if the buttonPushCounter is odd
       {
      Serial.println("timer is running");
      TimerCount();
       }
       else // if the buttonPushCounter is even
      {
      Serial.println("timer is off");
      min1 = 0;
      min2 = 0;
      sec3 = 0;
      sec4 = 0;
    }   
    }
    delay(50);// Delay a little bit to avoid bouncing
  data[0] = display.encodeDigit(min1);
  data[1] = display.encodeDigit(min2);
  data[2] = display.encodeDigit(sec3);
  data[3] = display.encodeDigit(sec4);
  }
  lastButtonState = buttonState; // setting buttonState back to LOW
} 
  
int TimerCount()
{
    min2 = min2 - 1; 
    sec4--;
    delay(1000);
    if(sec4 == -1){
      sec4 = 9;
      sec3--;
    }
    if(sec3 == -1){
      sec3=5;
    }
}
  
 void IfZero()
 {
 if(min1 == 0 && min2 == 0)a
 {
   digitalWrite(A7, HIGH); 
   delay(100);
   digitalWrite(A7, LOW); 
   delay(100);
 } 
 }

  int Scan_4x4_keypad()
{
  int keypadVal = 19;
  //----------Find P1, P2, R, M ----
  digitalWrite(A4, LOW);
  digitalWrite(A3, HIGH);
  digitalWrite(A2, HIGH);
  digitalWrite(A1, HIGH); 
  if(digitalRead(9) == LOW)   
  keypadVal = 12; // P1 = 12
  if(digitalRead(8) == LOW)
  keypadVal = 13; // P2 = 13 
  if(digitalRead(7) == LOW)
  keypadVal =  14; // R = 14
  if(digitalRead(6) == LOW)
  keypadVal = 15;// M = 15
  //---------------------------

  //----------Find 3,6,9,E ----
  digitalWrite(A4, HIGH);
  digitalWrite(A3, LOW);
  digitalWrite(A2, HIGH);
  digitalWrite(A1, HIGH); 
  if(digitalRead(9) == LOW)
  keypadVal = 3;
  if(digitalRead(8) == LOW)
  keypadVal = 6;
  if(digitalRead(7) == LOW)
  keypadVal = 9;
  if(digitalRead(6) == LOW)
  keypadVal = 10;// E
  //---------------------------

  //----------Find 2,5,8,0 ----
  digitalWrite(A4, HIGH);
  digitalWrite(A3, HIGH);
  digitalWrite(A2, LOW);
  digitalWrite(A1, HIGH); 
  if(digitalRead(9) == LOW)
  keypadVal = 2;
  if(digitalRead(8) == LOW)
  keypadVal = 5;
  if(digitalRead(7) == LOW)
  keypadVal = 8;
  if(digitalRead(6) == LOW)
  keypadVal = 0;
  
  //----------Find 1,4,7,C ----
  digitalWrite(A4, HIGH);
  digitalWrite(A3, HIGH);
  digitalWrite(A2, HIGH);
  digitalWrite(A1, LOW); 
  if(digitalRead(9) == LOW)
  keypadVal = 1;
  if(digitalRead(8) == LOW)
  keypadVal = 4;
  if(digitalRead(7) == LOW)
  keypadVal = 7;
  if(digitalRead(6) == LOW)
  keypadVal = 11;// C

  return keypadVal;
  //---------------------------
}

Thanks a lot! :slight_smile:

By the way, this is the code where there is no tact switch involved, and the input is in seconds (4 digits).
It just countsdown automatically after keying in the 4th digit input.

#include <Arduino.h>
#include <TM1637Display.h>
// Module connection pins (Digital Pins)
#define CLK 2
#define DIO 3

int NewKeyPadVal = 0;

//----Input Code Digits--
int InputDigit1 =  0;
int InputDigit2 =  0;
int InputDigit3 =  0;
int InputDigit4 =  0;

   //----------------------

TM1637Display display(CLK, DIO);
uint8_t data[] = { 0xff, 0xff, 0xff, 0xff };
void setup() 
{
  
  display.setBrightness(0x01);//MAX - 0x0f

   // Selectively set different digits
  data[0] = display.encodeDigit(0);
  data[1] = display.encodeDigit(0);
  data[2] = display.encodeDigit(0);
  data[3] = display.encodeDigit(0);
  display.setSegments(data);


  
// initialize I/O pins.
   pinMode(A0, OUTPUT); //Relay or LED blinking Output at 0000
//--------------------------4x4 Keypad------------------  
  //------4 columns-----
  pinMode(A4, OUTPUT);
  pinMode(A3, OUTPUT);
  pinMode(A2, OUTPUT);
  pinMode(A1, OUTPUT);

  digitalWrite(A4, HIGH);
  digitalWrite(A3, HIGH);
  digitalWrite(A2, HIGH);
  digitalWrite(A1, HIGH);
  //-------4 rows-----------
  pinMode(6, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  //------------------------ 

}

void loop() 
{
display.setSegments(data);
if(InputDigit1 == 0 && InputDigit2 == 0 && InputDigit3 == 0 && InputDigit4 == 0)
{
  delay(400);
  while(Scan_4x4_keypad() == 19)
  {
  delay(1);
  IfZero();
  }
  NewKeyPadVal = Scan_4x4_keypad();
  InputDigit1 = NewKeyPadVal;
  data[0] = display.encodeDigit(InputDigit1);
  display.setSegments(data);
//----------------------------------------------------
delay(400);
  while(Scan_4x4_keypad() == 19)
  delay(1);
  NewKeyPadVal = Scan_4x4_keypad();
  InputDigit2 = NewKeyPadVal;
   data[1] = display.encodeDigit(InputDigit2);
  display.setSegments(data);
//----------------------------------------------------
delay(400);
  while(Scan_4x4_keypad() == 19)
  delay(1);
  NewKeyPadVal = Scan_4x4_keypad();
  InputDigit3 = NewKeyPadVal;
   data[2] = display.encodeDigit(InputDigit3);
  display.setSegments(data);

//----------------------------------------------------
delay(400);
  while(Scan_4x4_keypad() == 19)
  delay(1);
  NewKeyPadVal = Scan_4x4_keypad();
  InputDigit4 = NewKeyPadVal;
   data[3] = display.encodeDigit(InputDigit4);
  display.setSegments(data);

//-----------------------------------------------------
}

TimerCount();
  
}

int TimerCount()
{
  InputDigit4--;
  delay(1000);
  if(InputDigit4 == -1)
  {
    InputDigit4 = 9;
    InputDigit3--;
  }
  if(InputDigit3 == -1)
  {
    InputDigit3 = 9;
    InputDigit2--;
  }
   if(InputDigit2 == -1)
  {
    InputDigit2 = 9;
    InputDigit1--;
  }
  data[0] = display.encodeDigit(InputDigit1);
  data[1] = display.encodeDigit(InputDigit2);
  data[2] = display.encodeDigit(InputDigit3);
  data[3] = display.encodeDigit(InputDigit4);
  
}

 void IfZero()
 {
 if(InputDigit1 == 0 && InputDigit2 == 0 && InputDigit3 == 0 )
 {
   digitalWrite(A0, HIGH); 
   delay(100);
   digitalWrite(A0, LOW); 
   delay(100);
 }
 
 }

  int Scan_4x4_keypad()
{
  int keypadVal = 19;
  //----------Find P1, P2, R, M ----
  digitalWrite(A4, LOW);
  digitalWrite(A3, HIGH);
  digitalWrite(A2, HIGH);
  digitalWrite(A1, HIGH); 
  if(digitalRead(9) == LOW)   
  keypadVal = 12; // P1 = 12
  if(digitalRead(8) == LOW)
  keypadVal = 13; // P2 = 13 
  if(digitalRead(7) == LOW)
  keypadVal =  14; // R = 14
  if(digitalRead(6) == LOW)
  keypadVal = 15;// M = 15
  //---------------------------

  //----------Find 3,6,9,E ----
  digitalWrite(A4, HIGH);
  digitalWrite(A3, LOW);
  digitalWrite(A2, HIGH);
  digitalWrite(A1, HIGH); 
  if(digitalRead(9) == LOW)
  keypadVal = 3;
  if(digitalRead(8) == LOW)
  keypadVal = 6;
  if(digitalRead(7) == LOW)
  keypadVal = 9;
  if(digitalRead(6) == LOW)
  keypadVal = 10;// E
  //---------------------------

  //----------Find 2,5,8,0 ----
  digitalWrite(A4, HIGH);
  digitalWrite(A3, HIGH);
  digitalWrite(A2, LOW);
  digitalWrite(A1, HIGH); 
  if(digitalRead(9) == LOW)
  keypadVal = 2;
  if(digitalRead(8) == LOW)
  keypadVal = 5;
  if(digitalRead(7) == LOW)
  keypadVal = 8;
  if(digitalRead(6) == LOW)
  keypadVal = 0;
  
  //----------Find 1,4,7,C ----
  digitalWrite(A4, HIGH);
  digitalWrite(A3, HIGH);
  digitalWrite(A2, HIGH);
  digitalWrite(A1, LOW); 
  if(digitalRead(9) == LOW)
  keypadVal = 1;
  if(digitalRead(8) == LOW)
  keypadVal = 4;
  if(digitalRead(7) == LOW)
  keypadVal = 7;
  if(digitalRead(6) == LOW)
  keypadVal = 11;// C

  return keypadVal;
  //---------------------------
}

Hi StefanL38 and blh64! Thanks for replying too! :smiley:

cbf06:
What happens now, is if I input 15 from the membrane switch and press tact switch, it will only display 14:59 after one second and gets stuck there.

the code only invokes TimerCount () when there is a button state change

   buttonState = digitalRead(buttonPin);
    if (buttonState != lastButtonState) // compare the buttonState to its previous state
    {
        if (buttonState == HIGH) // if the current state is HIGH then the button went from off to on:
        {
            buttonPushCounter++; // if the state has changed, increment the counter
            if (buttonPushCounter % 2 != 0)// if the buttonPushCounter is odd
            {
                Serial.println("timer is running");
                TimerCount();
            }

            else // if the buttonPushCounter is even
            {
                Serial.println("timer is off");
                min1 = 0;
                min2 = 0;
                sec3 = 0;
                sec4 = 0;
            }

        }

how about

if (! (buttonPushCounter % 2))
    TimerCount();

This should get you a bit closer

//#include <Arduino.h>
#include <TM1637Display.h>
// Module connection pins (Digital Pins)
#define CLK 2
#define DIO 3

int NewKeyPadVal = 0;
const int buttonPin = 13;


//-----Tact Switch Input-----
int buttonState = 0;
int lastButtonState = 0;

//----------------------

TM1637Display display(CLK, DIO);
uint8_t data[] = { 0xff, 0xff, 0xff, 0xff };
unsigned int timeValue = 0;

bool isRunning = false;

void displayTime()
{
  int minutes = timeValue / 60;
  int seconds = timeValue % 60;
  data[0] = display.encodeDigit(minutes / 10);
  data[1] = display.encodeDigit(minutes % 10);
  data[2] = display.encodeDigitseconds / 10);
  data[3] = display.encodeDigit(seconds % 10);
  display.setSegments(data);
}

void setup()
{
  display.setBrightness(0x01);//MAX - 0x0f

  // Selectively set different digits
  timeValue = 0;
  displayTime();

  // initialize I/O pins.

  // NOTE NOTE NOTE NOTE NOTE
  // A6 and A7 can not be used for digital input or output
  pinMode(A7, OUTPUT); //Relay or LED blinking Output at 0000
  pinMode(buttonPin, INPUT);//Timer Start Stop
  //--------------------------4x4 Keypad------------------
  //------4 columns-----
  pinMode(A4, OUTPUT);
  pinMode(A3, OUTPUT);
  pinMode(A2, OUTPUT);
  pinMode(A1, OUTPUT);

  digitalWrite(A4, HIGH);
  digitalWrite(A3, HIGH);
  digitalWrite(A2, HIGH);
  digitalWrite(A1, HIGH);
  //-------4 rows-----------
  pinMode(6, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  //------------------------
  Serial.begin(9600);
}


void loop()
{
  if ( isRunning == true )
  {
    displayTime();
    TimerCount();
  }
  else
  {
    delay(400);
    while (Scan_4x4_keypad() == 19)
    {
      delay(1);
      IfZero();
    }
    NewKeyPadVal = Scan_4x4_keypad();
    timeValue = NewKeyPadVal * 600;   // 10s minute
    displayTime();
    //----------------------------------------------------
    delay(400);
    while (Scan_4x4_keypad() == 19)
      delay(1);
    NewKeyPadVal = Scan_4x4_keypad();
    timeValue += NewKeyPadVal * 60;   // minutes
    displayTime();
    //----------------------------------------------------
    delay(400);
    while (Scan_4x4_keypad() == 19)
      delay(1);
    NewKeyPadVal = Scan_4x4_keypad();
    timeValue += NewKeyPadVal * 10;   // 10s seconds
    displayTime();
    //----------------------------------------------------
    delay(400);
    while (Scan_4x4_keypad() == 19)
      delay(1);
    NewKeyPadVal = Scan_4x4_keypad();
    timeValue += NewKeyPadVal;      // seconds
    displayTime();
    //----------------------------------------------------
    isRunning = true;
    lastUpdateTime = millis();
  }

  buttonState = digitalRead(buttonPin);
  if (buttonState != lastButtonState) // compare the buttonState to its previous state
  {
    if (buttonState == HIGH) // if the current state is HIGH then the button went from off to on:
    {
      isRunning = true;
      Serial.println("timer is running");
      lastUpdateTime = millis();
    }
    else
    {
      isRunning = false;
      Serial.println("timer is off");
      timeValue = 0;
    }
    delay(50);// Delay a little bit to avoid bouncing
  }
  lastButtonState = buttonState; // setting buttonState back to LOW
}

int TimerCount()
{
  while ( millis() - lastUpdateTime >= 1000 and timeValue > 0)
  {
    timeValue--;
    lastUpdateTime += 1000;
  }
}

void IfZero()
{
  if (timeValue == 0)
  {
    digitalWrite(A7, HIGH);
    delay(100);
    digitalWrite(A7, LOW);
    delay(100);
  }
}

int Scan_4x4_keypad()
{
  int keypadVal = 19;
  //----------Find P1, P2, R, M ----
  digitalWrite(A4, LOW);
  digitalWrite(A3, HIGH);
  digitalWrite(A2, HIGH);
  digitalWrite(A1, HIGH);
  if (digitalRead(9) == LOW)
    keypadVal = 12; // P1 = 12
  if (digitalRead(8) == LOW)
    keypadVal = 13; // P2 = 13
  if (digitalRead(7) == LOW)
    keypadVal =  14; // R = 14
  if (digitalRead(6) == LOW)
    keypadVal = 15;// M = 15
  //---------------------------

  //----------Find 3,6,9,E ----
  digitalWrite(A4, HIGH);
  digitalWrite(A3, LOW);
  digitalWrite(A2, HIGH);
  digitalWrite(A1, HIGH);
  if (digitalRead(9) == LOW)
    keypadVal = 3;
  if (digitalRead(8) == LOW)
    keypadVal = 6;
  if (digitalRead(7) == LOW)
    keypadVal = 9;
  if (digitalRead(6) == LOW)
    keypadVal = 10;// E
  //---------------------------

  //----------Find 2,5,8,0 ----
  digitalWrite(A4, HIGH);
  digitalWrite(A3, HIGH);
  digitalWrite(A2, LOW);
  digitalWrite(A1, HIGH);
  if (digitalRead(9) == LOW)
    keypadVal = 2;
  if (digitalRead(8) == LOW)
    keypadVal = 5;
  if (digitalRead(7) == LOW)
    keypadVal = 8;
  if (digitalRead(6) == LOW)
    keypadVal = 0;

  //----------Find 1,4,7,C ----
  digitalWrite(A4, HIGH);
  digitalWrite(A3, HIGH);
  digitalWrite(A2, HIGH);
  digitalWrite(A1, LOW);
  if (digitalRead(9) == LOW)
    keypadVal = 1;
  if (digitalRead(8) == LOW)
    keypadVal = 4;
  if (digitalRead(7) == LOW)
    keypadVal = 7;
  if (digitalRead(6) == LOW)
    keypadVal = 11;// C

  return keypadVal;
  //---------------------------
}

Hi blh64, thanks for the code. I just made some modifications:

data[2] = display.encodeDigitseconds / 10); >>> data[2] = display.encodeDigit(seconds / 10);

Declared variable for lastButtonState

int lastButtonState = 0;

Then compile and upload. The result however is, if I type in 15 and press tact switch, the display is stuck at 15:00. There's also no output on serial monitor.

The code I posted requires you input MMSS - 4 digits. No more, no less. If you press less, it is stuck in the input section and not reading/reacting to the button press.

If you want to have a variable number of inputs, you can not keep the code within the else() clause of the loop(). It needs to run repeatedly so it can check the state of the button. Each time through loop(), you will need to check and see if a digit has been pressed and keep track of which one (min10, min, sec10, sec) and do some math.

Give it a try. If/when you get stuck, post back with your best effort (and use code tags to post your code! You have seen several examples now. Learn how to do it by reading the sticky post at the top of the forum.)

Okay, I tried 4-digit input just like what you said. 15:00 (15 minutes), it automatically started counting down without even pressing the tact switch). Also, it only counted down until 14:37 then it went back to 00:00.

Will have to modify the existing code and post it here later.
Thanks so much for the input. :slight_smile:

cbf06:
Okay, I tried 4-digit input just like what you said. 15:00 (15 minutes), it automatically started counting down without even pressing the tact switch).

This is exactly as designed. If you want it to wait, you will need some other variable to signal input complete or something like that

Also, it only counted down until 14:37 then it went back to 00:00.

How do you have your button wired? You have it declared as INPUT which means you will need an external pull-up or pull-down resistor connected. If you don't have one, the input pin is not connected to anything and "floats" which means it can go HIGH/LOW based on whatever.

blh64:
This is exactly as designed. If you want it to wait, you will need some other variable to signal input complete or something like that

I actually only want it to start counting down when I press the tact switch and reset the time to 00:00 after I press it the 2nd time.

blh64:
How do you have your button wired? You have it declared as INPUT which means you will need an external pull-up or pull-down resistor connected. If you don't have one, the input pin is not connected to anything and "floats" which means it can go HIGH/LOW based on whatever.

One of the tact switch pins is connected to VCC(5V), the other end is connected to Arduino Pin 13 and a 10K resistor whose other pin is connected to GND. I also tried changing resistor to 2K. Result is the same. All the pins of the membrane switch is connected straight to Arduino pins. The TM1637 module pins are also connected straight to Arduino.

By the way, it wasn't the lastButtonState I declared as variable, it was the

int lastUpdateTime = 0;

I also closely observed the timer, it will only countdown 30 seconds before it resets back to 00:00. For example, I'll input 15:00, after 14:30 it will already reset back to 00:00.

Hi blh64 and all,

Somehow, I managed to get the thing working according to how I want it to function.
If I input 2 digits as minutes, it only starts counting down once I press the tact switch.
However, I want to introduce another button/tact switch as stop interrupt, such that when I press this button at the middle of count down, it will reset my timer back to 00:00.

Any idea how I can implement this?

Anyway, here's my current code:

#include <Arduino.h>
#include <TM1637Display.h>
// Module connection pins (Digital Pins)
#define CLK 2
#define DIO 3

int NewKeyPadVal = 0;
int buttonPin = 13;


//-----Tact Switch Input-----
int buttonPushCounter = 0;
int buttonState = 0;
int lastButtonState = 0;

//----Input Code Digits-----
int min1 =  0;
int min2 =  0;
int sec3 =  0;
int sec4 =  0;
int minutes = 0;
int seconds = 0;
int timeValue  = 0;
//----------------------

TM1637Display display(CLK, DIO);
uint8_t data[] = { 0xff, 0xff, 0xff, 0xff };


void setup() 
{
  
  display.setBrightness(0x01);//MAX - 0x0f

   // Selectively set different digits
  data[0] = display.encodeDigit(0);
  data[1] = display.encodeDigit(0);
  data[2] = display.encodeDigit(0);
  data[3] = display.encodeDigit(0);
  display.setSegments(data);


  
// initialize I/O pins.
   pinMode(A7, OUTPUT); //Relay or LED blinking Output at 0000
   pinMode(buttonPin, INPUT);//Timer Start Stop
//--------------------------4x4 Keypad------------------  
  //------4 columns-----
  pinMode(A4, OUTPUT);
  pinMode(A3, OUTPUT);
  pinMode(A2, OUTPUT);
  pinMode(A1, OUTPUT);

  digitalWrite(A4, HIGH);
  digitalWrite(A3, HIGH);
  digitalWrite(A2, HIGH);
  digitalWrite(A1, HIGH);
  //-------4 rows-----------
  pinMode(6, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  //------------------------ 
Serial.begin(9600);
}

void loop() 
{
display.setSegments(data);

  while(min1 == 0 && min2 == 00 && sec3 == 0 && sec4 == 0)
  {
    Serial.println("timer is off");
    delay(400);
    while(Scan_4x4_keypad() == 19)
    {
    delay(1);
    IfZero();
    }
  NewKeyPadVal = Scan_4x4_keypad();
  min1 = NewKeyPadVal;
  timeValue = min1 * 600; // 10s minutes
  data[0] = display.encodeDigit(min1);
  display.setSegments(data);
//----------------------------------------------------
delay(400);
  while(Scan_4x4_keypad() == 19)
  delay(1);
  NewKeyPadVal = Scan_4x4_keypad();
  min2 = NewKeyPadVal;
  timeValue += NewKeyPadVal * 60;// minutes
  data[1] = display.encodeDigit(min2);
  display.setSegments(data);
//----------------------------------------------------
  }
  buttonState = digitalRead(buttonPin); 
  if (buttonState != lastButtonState) // compare the buttonState to its previous state
    {
    if (buttonState == HIGH) // if the current state is HIGH then the button went from off to on:
      {
      Serial.println("timer is running");
      TimerCount();   
      }
    delay(50);// Delay a little bit to avoid bouncing
    lastButtonState = buttonState; // setting buttonState back to LOW
    } 
}
  
int TimerCount()
{
  minutes = timeValue / 60;
  delay(1000);
  for(int minCount = minutes - 1; minCount > -1; minCount--){
    min1 = minCount / 10;
    min2 = minCount % 10;
    seconds = timeValue % 60; 
    int secCount = seconds + 60;
      while(secCount != 0){ 
        delay(1000);
        secCount--;
        sec3 = secCount / 10;
        sec4 = secCount % 10;

        buttonState = digitalRead(buttonPin); 
        if (buttonState != lastButtonState) // compare the buttonState to its previous state
        {
          if (buttonState == HIGH) // if the current state is HIGH then the button went from off to on:
          {
          break;
          min1 = 0;
          min2 = 0;
          sec3 = 0;
          sec4 = 0;
          }
        delay(50);// Delay a little bit to avoid bouncing
        lastButtonState = buttonState; // setting buttonState back to LOW
        } 
    
      data[0] = display.encodeDigit(min1);
      data[1] = display.encodeDigit(min2);
      data[2] = display.encodeDigit(sec3);
      data[3] = display.encodeDigit(sec4);
      display.setSegments(data);
      }
     }
   }
 
 void IfZero()
 {
 if(min1 == 0 && min2 == 0)
 {
   digitalWrite(A7, HIGH); 
   delay(100);
   digitalWrite(A7, LOW); 
   delay(100); 
 } 
 }

  int Scan_4x4_keypad()
{
  int keypadVal = 19;
  //----------Find P1, P2, R, M ----
  digitalWrite(A4, LOW);
  digitalWrite(A3, HIGH);
  digitalWrite(A2, HIGH);
  digitalWrite(A1, HIGH); 
  if(digitalRead(9) == LOW)   
  keypadVal = 12; // P1 = 12
  if(digitalRead(8) == LOW)
  keypadVal = 13; // P2 = 13 
  if(digitalRead(7) == LOW)
  keypadVal =  14; // R = 14
  if(digitalRead(6) == LOW)
  keypadVal = 15;// M = 15
  //---------------------------

  //----------Find 3,6,9,E ----
  digitalWrite(A4, HIGH);
  digitalWrite(A3, LOW);
  digitalWrite(A2, HIGH);
  digitalWrite(A1, HIGH); 
  if(digitalRead(9) == LOW)
  keypadVal = 3;
  if(digitalRead(8) == LOW)
  keypadVal = 6;
  if(digitalRead(7) == LOW)
  keypadVal = 9;
  if(digitalRead(6) == LOW)
  keypadVal = 10;// E
  //---------------------------

  //----------Find 2,5,8,0 ----
  digitalWrite(A4, HIGH);
  digitalWrite(A3, HIGH);
  digitalWrite(A2, LOW);
  digitalWrite(A1, HIGH); 
  if(digitalRead(9) == LOW)
  keypadVal = 2;
  if(digitalRead(8) == LOW)
  keypadVal = 5;
  if(digitalRead(7) == LOW)
  keypadVal = 8;
  if(digitalRead(6) == LOW)
  keypadVal = 0;
  
  //----------Find 1,4,7,C ----
  digitalWrite(A4, HIGH);
  digitalWrite(A3, HIGH);
  digitalWrite(A2, HIGH);
  digitalWrite(A1, LOW); 
  if(digitalRead(9) == LOW)
  keypadVal = 1;
  if(digitalRead(8) == LOW)
  keypadVal = 4;
  if(digitalRead(7) == LOW)
  keypadVal = 7;
  if(digitalRead(6) == LOW)
  keypadVal = 11;// C

  return keypadVal;
  //---------------------------
}

cbf06:
Somehow, I managed to get the thing working according to how I want it to function.

Congratulations on getting it working.

However, I want to introduce another button/tact switch as stop interrupt, such that when I press this button at the middle of count down, it will reset my timer back to 00:00.

Interrupts (if that's what you are thinking of using) aren't going to help you here.

Your main problem is your program works by using internal loops and delays. This will only get you so far in Arduino programming. Sooner or later you want to do two things at once, e.g. run a countdown timer AND continuously at the same time check for a button press, and you are stuck.

To have a key stop something, and have it work everywhere, then everywhere you are looping or waiting you also have to also be checking for the key press. That gets progressively more complex the more loops and waits you introduce.

Sooner or later you have to bite the bullet and us millis() for timing and a state machine.

Any idea how I can implement this?

There's ways you can try and shoehorn it into your current code and go further down the rabbit hole of an incorrect starting point. Personally I wouldn't recommend it...

Review the "state machine" and "blink without delay" examples in the tutorials sticky thread.

take a look at this (as an example for handling 1+ buttons)

// Keypad2
// recognize multiple button presses; tgl LED when pressed

byte butPins [] = { A1, A2, A3 };
byte ledPins [] = { 10, 11, 12 };

#define N_PINS sizeof(butPins)

byte butLst [N_PINS] = {};

// -----------------------------------------------------------------------------
void setup (void)
{
    for (unsigned n = 0; n < N_PINS; n++)  {
        digitalWrite (ledPins [n], OFF);
        pinMode      (ledPins [n], OUTPUT);

        pinMode      (butPins [n], INPUT_PULLUP);
        butLst [n]  = digitalRead (butPins [n]);
    }
}

// -----------------------------------------------------------------------------
void loop (void)
{
    for (unsigned n = 0; n < N_PINS; n++)  {
        byte but = digitalRead (butPins [n]);

        if (butLst [n] != but)  {
            butLst [n] = but;

            if (LOW == but)     // button pressed
                digitalWrite (ledPins [n], ! digitalRead (ledPins [n]));
        }
    }

    delay (10);         // debounce
}

Hello all,

Hope you're all doing great. :slight_smile:
So now my timer basically accepts 2 digit input from membrane keypad and will convert to minutes and start counting down until zero. Just a question though, what if I want to accept either 1 or 2 digits as input? For example if I press 1 on the keypad and press start button, it will read it as 1 minute and count down to 59, 58, 57...0 seconds. But if I dont press the start button it will wait for the second digit and start button to be pressed before count down. For example I press 1 (start button not pressed) then I press 2, program will read it as 12 minutes and will start count down as soon as I press start button. Any idea how I can implement this?

Hope you can help me out. Thank you. :slight_smile:

Here's the code:

void loop()
{
int select = ((digitalRead(probeSelect)<<1) | (digitalRead(chamberSelect)));
 delay(1000);
 Serial.print("\n""Select Value: ");
 Serial.println(select);

switch(select){

case 0: //----Selector at NEUTRAL position----
digitalWrite(chamberLED, LOW);
digitalWrite(probeLED, LOW);
break;

case 1: //----Selector at CHAMBER position----
digitalWrite(chamberLED, HIGH);
digitalWrite(probeLED, LOW);
break;

case 2: //----Selector at PROBE position----
digitalWrite(chamberLED, LOW);
digitalWrite(probeLED, HIGH);
break;
 }
delay(100);
Serial.print("\n""Select Value: ");
Serial.println(select);
//----Selector at NEUTRAL position----

 if (select == 0){
 Serial.println("None is selected.");
 IfZero();
 }

//----Selector at CHAMBER position----
 else if (select == 1){
 Serial.println("Chamber is selected.");
 digitalWrite(chamberLED, HIGH);
 chamberStartState = digitalRead(chamberStart);   
    if (chamberStartState == HIGH) // if the current state is HIGH then the chamberStartState went from off to on:
    {
      delay(100);
      min1 = 0;
      min2 = 3; 
      sec3 = 0;
      sec4 = 0;

      data[0] = display.encodeDigit(min1);
      data[1] = display.encodeDigit(min2);
      data[2] = display.encodeDigit(sec3);
      data[3] = display.encodeDigit(sec4);
      display.setSegments(data);
      Serial.println("Chamber treatment starting...");
      TimerCount_Chamber();
      delay(50);
      IfZero();
    } 
    // Delay a little bit to avoid bouncing
    delay(50);
    }

//----Selector at PROBE position----
 else if (select == 2){
 Serial.println("Probe is selected.");
 digitalWrite(probeLED, HIGH);
 
//--------MEMBRANE PANEL INPUT--------3
delay(400);
  while(Scan_4x4_keypad() == 19)
  delay(1);
  NewKeyPadVal = Scan_4x4_keypad();
  min1 = NewKeyPadVal;
  timeValue = min1 * 600; // 10s minutes
  data[0] = display.encodeDigit(min1);
  display.setSegments(data);
//----------------------------------------------------
delay(400);
  while(Scan_4x4_keypad() == 19) 
  delay(1);
  NewKeyPadVal = Scan_4x4_keypad();
  min2 = NewKeyPadVal;
  timeValue += NewKeyPadVal * 60;// minutes
  data[1] = display.encodeDigit(min2);
  display.setSegments(data);
  
  delay(1000);
  Serial.print("timeValue: ");
  Serial.println(timeValue);

int probeTime = timeValue;

while (probeTime == timeValue){
  
//-------- PROBE START--------
probeStartState = digitalRead(probeStart);
if (probeStartState == HIGH) // if the current state is HIGH then the probeStart went from off to on:
      {
      Serial.println("Probe treatment starting...");
      TimerCount_Probe();
      }
delay(50);
}
IfZero();
}
}
  

//============FUNCTIONS============
//-----------Default-----------
void IfZero()
{ 
digitalWrite(ACRelay, HIGH); 
digitalWrite(solenoid, HIGH); 
digitalWrite(probeLED, LOW);
digitalWrite(chamberLED, LOW);
Serial.println("Please select an option.");  
}

//-----------Chamber Timer-----------
int TimerCount_Chamber()
{
  timeValue = 180;
  minutes = timeValue / 60;
  delay(1000);
  for(minCount = minutes - 1; minCount > -1; minCount--){
   
    min1 = minCount / 10;
    min2 = min2 = minCount % 10;
    seconds = timeValue % 60; 
    secCount = seconds + 60;
      while(secCount != 0){ 
        delay(1000);
        secCount--;
        sec3 = secCount / 10;
        sec4 = secCount % 10;

        digitalWrite(ACRelay, LOW);
        digitalWrite(solenoid, LOW);
        digitalWrite(chamberLED, HIGH);
        Serial.println("AC Relay is on");
        Serial.println("Solenoid is on");
        Serial.println("Chamber Led is on");
        
      data[0] = display.encodeDigit(min1);
      data[1] = display.encodeDigit(min2);
      data[2] = display.encodeDigit(sec3);
      data[3] = display.encodeDigit(sec4);
      display.setSegments(data);
      }
      }
  timeValue = 0;
  if (timeValue == 0){
  digitalWrite(buzzer, HIGH);   // Turn the Buzzer on
  delay(1000); // Turn the Buzzer off                       
  digitalWrite(buzzer, LOW);    // Turn the Buzzer on 
  delay(1000); // Turn the Buzzer off  
  digitalWrite(buzzer, HIGH);   // Turn the Buzzer on
  delay(1000); // Turn the Buzzer off                       
  digitalWrite(buzzer, LOW);    // Turn the Buzzer on 
  delay(1000); // Turn the Buzzer off
  digitalWrite(buzzer, HIGH);   // Turn the Buzzer on
  delay(1000); // Turn the Buzzer off                       
  digitalWrite(buzzer, LOW);    // Turn the Buzzer on 
  delay(1000); // Turn the Buzzer off
  }
  
   Serial.print("timeValue: ");
   Serial.println(timeValue);
   Serial.print("minutes: ");
   Serial.println(minutes);
   Serial.print("seconds: ");
   Serial.println(seconds); 
   Serial.println("Chamber treatment ended.");
   Serial.println("Nothing is selected."); 
    }

 //-----------Membrane Keypad-----------

int Scan_4x4_keypad()
{
  int keypadVal = 19;

  //----------Find 3,6,9,E ----
  digitalWrite(A4, HIGH);
  digitalWrite(A3, LOW);
  digitalWrite(A2, HIGH);
  digitalWrite(A1, HIGH); 
  if(digitalRead(9) == LOW)
  keypadVal = 3;
  if(digitalRead(8) == LOW)
  keypadVal = 6;
  if(digitalRead(7) == LOW)
  keypadVal = 9;
  if(digitalRead(6) == LOW)
  //---------------------------

  //----------Find 2,5,8,0 ----
  digitalWrite(A4, HIGH);
  digitalWrite(A3, HIGH);
  digitalWrite(A2, LOW);
  digitalWrite(A1, HIGH); 
  if(digitalRead(9) == LOW)
  keypadVal = 2;
  if(digitalRead(8) == LOW)
  keypadVal = 5;
  if(digitalRead(7) == LOW)
  keypadVal = 8;
  if(digitalRead(6) == LOW)
  keypadVal = 0;
  
  //----------Find 1,4,7,C ----
  digitalWrite(A4, HIGH);
  digitalWrite(A3, HIGH);
  digitalWrite(A2, HIGH);
  digitalWrite(A1, LOW); 
  if(digitalRead(9) == LOW)
  keypadVal = 1;
  if(digitalRead(8) == LOW)
  keypadVal = 4;
  if(digitalRead(7) == LOW)
  keypadVal = 7;
  if(digitalRead(6) == LOW)

  return keypadVal;
  //---------------------------
}

//-----------Probe Timer-----------
int TimerCount_Probe()
{
  minutes = timeValue / 60;
  delay(1000); 
  for(minCount = minutes - 1; minCount > -1; minCount--){
   
    min1 = minCount / 10;
    min2 = minCount % 10;
    seconds = timeValue % 60; 
    secCount = seconds + 60;
      while(secCount != 0){ 
        delay(1000);
        secCount--;
        sec3 = secCount / 10;
        sec4 = secCount % 10;

        digitalWrite(ACRelay, LOW);
        digitalWrite(probeLED, HIGH);
        Serial.println("AC Relay is on");
        Serial.println("Probe Led is on");
        
      data[0] = display.encodeDigit(min1);
      data[1] = display.encodeDigit(min2);
      data[2] = display.encodeDigit(sec3);
      data[3] = display.encodeDigit(sec4);
      display.setSegments(data);
      }
     }

  timeValue = 0;
  if (timeValue == 0){
  digitalWrite(buzzer, HIGH);   // Turn the Buzzer on
  delay(1000); // Turn the Buzzer off                       
  digitalWrite(buzzer, LOW);    // Turn the Buzzer on 
  delay(1000); // Turn the Buzzer off  
  digitalWrite(buzzer, HIGH);   // Turn the Buzzer on
  delay(1000); // Turn the Buzzer off                       
  digitalWrite(buzzer, LOW);    // Turn the Buzzer on 
  delay(1000); // Turn the Buzzer off
  digitalWrite(buzzer, HIGH);   // Turn the Buzzer on
  delay(1000); // Turn the Buzzer off                       
  digitalWrite(buzzer, LOW);    // Turn the Buzzer on 
  delay(1000); // Turn the Buzzer off                       
  }
   
   Serial.print("timeValue: ");
   Serial.println(timeValue);
   Serial.print("minutes: ");
   Serial.println(minutes);
   Serial.print("seconds: ");
   Serial.println(seconds);
   Serial.println("Probe treatment ended.");
   Serial.println("Nothing is selected.");
    }
   
[\code]