Start and Stop Timer Using Push Button

Hi There,

I am trying to make a count up timer with an Arduino UNO, that would start counting at the pressing of the button and stop when you press the button again. I would like to display the time between start and stop on the serial monitor as well.

could anyone help me with the code, I am trying to use millis() but I am lost after setting up the code:

const unsigned long period = 1000;
unsigned long previousTime = 0;

const int buttonPin = 2;

void setup()
{

Serial.begin(9600);
pinMode(buttonPin, INPUT);

}

void loop()
{
unsigned long currentTime = millis();

//whenever millis reaches period, previous time updates
if(currentTime - previousTime >= period)
previousTime = currentTime;

}

I see:

  • NO code tags
  • no attempt of doing what you say

As a hint, look at state change detection. Because a button becoming pressed isn't the same as a button that IS pressed. You can make that process easy by grabbing a library like Bounce2.

I am a beginner, I know how many times a button is pressed
I did it with the following code before:

void buttonPressCounter()
{
int buttonState = digitalRead (CountingButton);
delay(200);

if (buttonState == LOW)
buttonPress = count++; //counting the number of button press

if(buttonPress == 6)
{
AllGatesClosed();
Serial.print("Passengers are in Queue");
}
}

but I am just getting really confused about this programme, I don't know how to even start.

Attiq_Lone:
I am a beginner,

Even more reason to at least read the big fat sticky called "How to use the forum". :wink:

And that will NOT count how many times a button was pressed. It simply counts how many times 200ms passed while pressing the button.

So, for both issues please refer to reply #1.

I have solved the issue of counting the presses with:

void buttonPressCountF()
{
// read the button input pin:
currentButtonState = digitalRead(buttonPin);

// compare the buttonState to its previous state
if (currentButtonState != lastButtonState)
{
// if the state has changed, increment the counter
if (currentButtonState == LOW)
{
Count++;
Serial.print("Press Number: ");
Serial.println(Count);
}
//Delay to debounce
delay(100);
}
//lastButtonState updates to currentButtonState
lastButtonState = currentButtonState;

//After 6 presses reset count
if(Count == 6)
{
Serial.println("6 People have now entered ");

Count = 0;
}
}

I was trying to modify this into a code that if(Count== 1) then start the counter and if(Count == 2) then stop the counter and display the elapsed time (CurrentTime - LastTime), could you give any suggestion on this?

At least you read about state change detection. Pity reading the forum rules is to much effort :confused:

I have read it, but I am still so confused about the millis(), I have literally searched everywhere, but it doesn't seem to solve my issue, the maximum i am getting is finding the elapsed time.

I followed what you said about the Bounce2 library, but instead of using that I wrote a button state detection code.

I am very new to millis() function, and that is why having problem integrating it into the program I mentioned above.

Basically what I have to do is: I have three doors, which I am simulating with 3 red LEDs, when any LED is on means that the door is closed, and when any LED is off means that the door is open. I can let in 3 people in through the door, and I am simulating this with the button press.

I let in 3 people (so after 3 button presses) from the first door, and then close all the doors, and after a certain delay I open the second door to move the people in the next area, and again close the door. I want to display on the Serial monitor, how much time people waited in each area. My teacher suggested me to use the millis() function but he never taught that. and that is why i wanted help understanding this function, I am not getting much help from internet or youtube videos.

this is my whole programme so far:

const int buttonPin = 2;

const byte ledPin = 3;
const byte ledPinTwo = 4;
const byte ledPinThree = 5;

int currentButtonState = 0;
int lastButtonState = 0;
int buttonPressCount = 0;

int switchCase = -1;

enum switchCase{
  stateOne = 0,
  stateTwo = 1,
  stateThree = 2,
  stateFour = 3 
};

void setup()
{
  //initialising serial monitor
  Serial.begin(9600);

  //declaring input
  pinMode(buttonPin, INPUT_PULLUP); //INPUT_PULLUP enables the internal Pullup resistor of the microcontroller

  //declaring outputs
  pinMode(ledPin, OUTPUT);
  pinMode(ledPinTwo, OUTPUT);
  pinMode(ledPinThree, OUTPUT);

  //initial message
  Serial.println("Press button to enter 6 people");

  //switchCase begins from state one
  switchCase = stateOne;
}

void loop()
{
  //buttonPressCounterF();
  //limitingPress();
  StateMachine();
}

void buttonPressCounterF()
{
  
  //reading button pin
  currentButtonState = digitalRead(buttonPin);

  //comparison of current state with last state of the button
  if(currentButtonState != lastButtonState)
  
   //If button is pressed
   if(currentButtonState == LOW)
   {
    //increment button press counter
    buttonPressCount++; 
    
    //print the press number on lcd screen
   Serial.print("Press Number: ");
   Serial.println(buttonPressCount);
   }
   //delay to avoid bouncing
   delay(50);
  
   lastButtonState = currentButtonState;  
}

void limitingPress()
{
  //limiting the number of presses
  if(buttonPressCount == 6)
  {
    Serial.print("6 People are in");

    buttonPressCount = 0; //reset counter

    switchCase = stateTwo;
  }
}

void StateMachine()
{ 
  switch(switchCase)
  {
  case stateOne:
  firstGateOpenStateF();
  break;

  case stateTwo:
  Serial.println("State Two");
  allGatesClosedStateF();
  switchCase = stateThree;
  break;

  case stateThree:
  Serial.println("State Three");
  middleGateOpenStateF();
  switchCase = stateFour;
  break;

  case stateFour:
  Serial.println("State Four");
   allGatesClosedStateF();
  setup();
  break;
  
  default:
  Serial.println("Error, do something");
  break;
  }
}

void allGatesClosedStateF()
{
  digitalWrite(ledPin, HIGH);
  digitalWrite(ledPinTwo, HIGH);
  digitalWrite(ledPinThree, HIGH);
  delay(2000);
}

void firstGateOpenStateF()
{
  digitalWrite(ledPin, LOW);
  digitalWrite(ledPinTwo, HIGH);
  digitalWrite(ledPinThree, HIGH);
  
  buttonPressCounterF();
  limitingPress();
}

void middleGateOpenStateF()
{
  digitalWrite(ledPin, HIGH);
  digitalWrite(ledPinTwo, LOW);
  digitalWrite(ledPinThree, HIGH);
  delay(2000);
}

First of all, when you start numbering variables, array's are the answer :wink:

What I don't get is how the three doors (and if you suggest them to be doors, just all them that in the program as well!) and a single button is tied together. All doors are sequencial? When does a dor open? When does it close?

enum switchCase{
  stateOne = 0,
  stateTwo = 1,
  stateThree = 2,
  stateFour = 3
};

That is one piece of confusing code.... What's wrong with the real number?

And nothing wrong with making the state change detection yourself but the blocking solution for the debounce may give you trouble when expending the code.

If you are having problems writing a sketch directly then it may be worthwhile to draw a Petri Net diagram of your system and add the logic of your system as annotations to the diagram. Then write the sketch based on the Petri Net diagram and its annotations. It is the method I used to write the sketch for your system and the method I would use for all of my applications. Here is a link to a PDF document which includes the details of my software development workflow plus simulations of the system and the sketch: (PDF) A Sketch that Reports Time Using a Button | John Frederick Chionglo - Academia.edu