Go Down

Topic: Time between two events - no delay (Read 2847 times) previous topic - next topic

ebweiss2

Jan 26, 2017, 01:09 am Last Edit: Jan 27, 2017, 08:27 pm by ebweiss2
Without using "delay," how can one record the time between say one button push or interrupt and another?

I've tried using an interrupt and the Millis() function a few different ways but I'm stumped.  Either I get 0 or Millis() just keeps rolling.  I guess what I need to know is can I capture time at point a, then point b, and measure the elapsed time between the two?  Because Millis() doesn't start and stop real easy, I'm finding this vexing.


Delta_G

You don't need millis to stop.  You just need to know what value it had at any one point.  You call it and store the result in a variable at the beginning.  You call it and store the result in a different variable at the end.  The variables both need to be unsigned long type.  Then you just subtract to find out how far in between.

If that hasn't been working for you, then post up your code and maybe someone can see where you went wrong. 
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

MorganS

millis() is spelled with a small-'m'. If you've been coding with Millis() then you're using a library or something strange.
"The problem is in the code you didn't post."

manor_royal

If this was a Civil Engineering forum would there be posts like "I need to build a bridge. Someone send me drawings."

Robin2

@ebweiss2, post the program that is causing the problem


And when posting code please use the code button </>
Code: [Select]
so your code looks like thisand is easy to copy to a text editor See How to use the Forum

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

ebweiss2

Okay, this is one testing sketch that doesn't work.  It's a bit cobbled together.  If you run it, each button push just spits out what's in millis as it roles along like a runaway train.  I just can't seem to get solid time A and time B stamps.  Eventually, I want to trigger an interrupt with a Hall sensor and figure time between triggers.  I'm trying to use a button just for a mock-up.

Code: [Select]

volatile int start =0;
volatile int revs = 0;


void setup()
{
  pinMode (2,INPUT);
  digitalWrite(2,HIGH);
  Serial.begin(9600);
 

   
attachInterrupt(0,react,FALLING); 
digitalWrite(2, HIGH);

  //get the start time
  start = millis(); 
 
}

void loop()
{
  }

void react()
{
  long fin = millis();
  revs =(fin - start);
  Serial.println(revs);
 
}






UKHeliBob

There are problems using Serial.print() in an ISR because it uses interrupts and they are disabled whilst an interrupt is being serviced.  Instead, set a flag when the interrupt occurs and do the printing in loop() based on the value of the flag.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Robin2

In addition to what @UKHeliBob said, the variables associated with millis() must be defined as unsigned long

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Delta_G

Code: [Select]

void react()
{
  long fin = millis();
  revs =(fin - start);
  Serial.println(revs);
 
}


So each time through you subtract start from fin. start that you saved way back in setup and never change anywhere else in the program.  So what you are printing is the time between the current pulse and the end of the setup function.  If you want to see the time between this pulse and the last pulse then you need to update the start time appropriately. 
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

ebweiss2

My understanding is global variables used in the ISR must be "volatile."

The Serial.print in the function isn't the issue.

I understand the logic of taking the difference of two time stamps.  Truble is, I can't seem to make that happen.  My understanding is that millis () keeps going once started.  It does however stop in the ISR.  I don't know how to write code that can flag millis() or plug its value into a variable at a given time.  I've been trying and failing.  I can make it work by calculating start to a given point, but I cannot record time elapsed between ongoing button presses.  Anyone care to try?

ebweiss2

Code: [Select]

void react()
{
  long fin = millis();
  revs =(fin - start);
  Serial.println(revs);
  
}


So each time through you subtract start from fin. start that you saved way back in setup and never change anywhere else in the program.  So what you are printing is the time between the current pulse and the end of the setup function.  If you want to see the time between this pulse and the last pulse then you need to update the start time appropriately.  
Precisely, but I can't seem to make that happen.

ebweiss2

Ok, so the ISR stops millis().  What if I use two interrupt commands in a row with two functions and two variables?  Think funcA(), which makes time1 = millis() then funcB() which makes time2= millis().  The elapsed = time2 - time1.  Then I just loop it so I keep getting a new "elapsed."

This is the only way I can think of two get two time stamps.  Now I just have to figure out how to code that out to see if it works.  Anyone think it is feasible?

Delta_G

#12
Jan 27, 2017, 09:10 pm Last Edit: Jan 27, 2017, 09:14 pm by Delta_G
What do you mean can't make it happen?  It's just a variable assignment.  Do you want the time between interrupts?  So the fin time for this one should be the start time for the next one?

Code: [Select]

void react()
{
  long fin = millis();
  revs =(fin - start);
  start = fin;   // sets up start for the next interrupt
  Serial.println(revs);
 
}
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

AWOL

#13
Jan 27, 2017, 09:11 pm Last Edit: Jan 27, 2017, 09:16 pm by AWOL
Quote
What if I use two interrupt commands
What do you mean by an "interrupt command"?

Delta_G

You don't have to worry about the ISR stopping millis if it is really fast.  As long as the ISR doesn't take more than a few milliseconds then the next Timer0 overflow will catch millis up as soon as your ISR exits.  That's not a problem for you.  

Get the Serial.print line out of the ISR.  
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

Go Up