Stopwatch for calculating time between functions

Hi guys, as you can see I am new here.

I have been doing some general messing with my arduino and wanted to get a simple program running where I want to time how long it takes from pressing a button to an infra red beam being broken.

I have the following code but I know there are some big things wrong as the serial monitor just shows "0" each time.

int switchPin = 10;
int spkPin = 13;

int irPin = 1;
int lastDist = 0;
int currentDist = 0;
int thresh = 200;

long startTime ;
long stoptime;
long elapsedTime ;                  

void setup()
{
   pinMode(switchPin, INPUT);
   Serial.begin(9600);
}

void loop()
{
  currentDist = analogRead(irPin);
  
  if (digitalRead(switchPin) == HIGH);
  {
    startTime = millis();                                   
  }
  if (currentDist > lastDist + thresh || currentDist < lastDist - thresh)
  {
    stopTime = millis()
    elapsedTime =   stopTime - startTime;
    Serial.print((int)elapsedTime);         
    delay(5000);
  }
}

Am I right in thinking that I need to store the elapsed time in a better way?

could anybody help or point me in the right direction?

many thanks.

if (digitalRead(switchPin) == HIGH);
  {
    startTime = millis();                                   
  }

You need to remember when it became high (ie. was low, is now high).

Anyway, how is this button wired up? Do you have any pull-up or pull-down resistors?

Also, is the switch wired correctly - i.e. do you have a simpler sketch that shows you that you can read the switch state correctly?

Edit: Nick! Get out of my head!

Variables that store the output of millis() should be 'unsigned long'.

If the time interval is measuring as 0 milliseconds you might want to try measuring in microseconds (micros()) instead. The Arduino can execute about 16000 instructions per milliseconds (16 per microsecond) so it is possible a millisecond timer is too crude to detect the time.

Have a look at my stopwatch class - Arduino Playground - StopWatchClass -

I made for measuring time, incl leaptimes .

wildbill:
Edit: Nick! Get out of my head!

I know what you are thinking ...

Thanks for the replies!

I think I have added the code to read when the button state changes as suggested by Nick, I have a 10k pull down resistor wired in to the button and have been able to read the button state correctly.

I have just seen rob's stopwatch class so will read into that now.

Im sure there's still a lot more holes in my code though :~ as it still displays zero's at whatever delay interval I set when i only want to print to the serial monitor when the time is stopped and an elapsed time value can be shown.

Thanks for all the help though, I'm learning slowly!

int switchPin = 10;
int buttonState;
int lastButtonState;
int spkPin = 13;
int timing;
int irPin = 1;
int lastDist = 0;
int currentDist = 0;
int thresh = 200;

unsigned long startTime ;
unsigned long stopTime;
unsigned long elapsedTime ;  


void setup()
{
   pinMode(switchPin, INPUT);
   Serial.begin(9600);
}

void loop()
{
  currentDist = analogRead(irPin);
  buttonState = digitalRead(switchPin); 
  if (buttonState == HIGH && lastButtonState == LOW);
  {
    startTime = millis();
    timing = true;
    lastButtonState = buttonState;
  }
  
  if (currentDist > lastDist + thresh || currentDist < lastDist - thresh && timing == true);
  {
    stopTime = millis();
    elapsedTime =   stopTime - startTime;
    Serial.print((int)elapsedTime);
    delay(1000);
    timing = false;
  }
}
  if (currentDist > lastDist + thresh || currentDist < lastDist - thresh && timing == true);

Lose the semicolon.

Starting to get somewhere now that I sorted a few silly mistakes.

Now I have it printing the elapsed time, but it prints the elapsed time since the program started running every time the beam is broken instead of only printing when the button has been pressed and then the beam is broken, any ideas?

int switchPin = 10;
int buttonState;
int lastButtonState;
int spkPin = 13;
int timing;
int irPin = 1;
int lastDist = 0;
int currentDist = 0;
int thresh = 200;

unsigned long startTime ;
unsigned long stopTime;
unsigned long elapsedTime ;  


void setup()
{
   pinMode(switchPin, INPUT);
   pinMode(irPin, INPUT);
   Serial.begin(9600);
}

void loop()
{
  currentDist = analogRead(irPin);
  buttonState = digitalRead(switchPin); 
  if (buttonState == HIGH && lastButtonState == LOW && timing == false)
  {
    startTime = millis();
    timing = true;
    lastButtonState = buttonState;
  }
  
  
  if (currentDist > lastDist + thresh || currentDist < lastDist - thresh && timing == true)
  {
    stopTime = millis();
    elapsedTime =   stopTime - startTime;
    Serial.print((int)elapsedTime);
    timing = false;
    delay(10);
    
  }
  lastDist = currentDist;
}

Think about what the variables are doing ...

  buttonState = digitalRead(switchPin); 
  if (buttonState == HIGH && lastButtonState == LOW && timing == false)
  {
    startTime = millis();
    timing = true;
    lastButtonState = buttonState;
  }

You only ever change lastButtonState this once. After that, then lastButtonState will be HIGH and you will never enter this test again.

Try:

  buttonState = digitalRead(switchPin); 
  if (buttonState == HIGH && lastButtonState == LOW && timing == false)
  {
    startTime = millis();
    timing = true;
  }
  lastButtonState = buttonState;

Thanks Nick, that helped a lot!

I also found that being a bit more careful with my if statements by using brackets to properly section off the calcs sorted the last bits of trouble I was having.

Again thanks very much to all that helped!