Arduino Forum

Topics => Science and Measurement => Topic started by: faruk_ultras on Mar 28, 2012, 10:25 am

Title: measuring time
Post by: faruk_ultras on Mar 28, 2012, 10:25 am
i have to measure time in arduino.I think i should use stopwatch library but i didn't include this library in my computer.Maybe you can help me.thanks
Title: Re: measuring time
Post by: johnwasser on Mar 28, 2012, 05:58 pm
Code: [Select]

unsigned long StartTime = millis();

later...

unsigned long CurrentTime = millis();
unsigned long ElapsedTime = CurrentTime - StartTime;


That will give you the elapsed time in milliseconds, up to about 40 days.  If you need more precise measurement you can use 'micros()' instead of ''millis()' to get microseconds, up to a couple of hours, I think.

The Arduino clock isn't very accurate so your timing may be off by minutes a day.
Title: Re: measuring time
Post by: robtillaart on Mar 28, 2012, 07:04 pm
Quote
get microseconds, up to a couple of hours, I think.

micros() last for 2^32 micros = 4295 seconds = ~71.5 minutes  so just more than one hour
Title: Re: measuring time
Post by: faruk_ultras on Mar 28, 2012, 11:04 pm
thanks all your replies :) i have another problem.I will make speedometer of te hydro car.Therefore i have to get time and measure the speed.i will use magnetic reed sensor.i use milis();

hiz =2*pi*r*3600/(elapsed time  ); 

my measuring time code is this. eplased time is ElapsedTime = CurrentTime - StartTime;
is it true approach?
Title: Re: measuring time
Post by: robtillaart on Mar 29, 2012, 12:01 am

you missed the factor 1000 as you measure in millis(). Just do the math for some known values and you see if a formula works.

e.g 1 second, 10 seconds 3600 seconds.

Partial code not tested
Code: [Select]

unsigned long prev = 0;

void loop()
{
  unsigned long now = millis();
  float speed = 2.0*pi*r * 3600 * 1000 / (now- prev);  speed in meters/hour
  prev = now;
  Serial.println(speed);
}
Title: Re: measuring time
Post by: Constantin on Mar 30, 2012, 04:10 pm
FWIW, once you get ready to finalize the code, try to compress all the math calcs in this example into a constant float or long up front. The reason being, there is no benefit to recalculating "2.0*pi* 3600 * 1000" over and over, it's 22619467.11... Ideally, Define R in that function as well and you may not even need to use a float.

Less calculations for Arduino to do = better responsiveness by Arduino.

If you want higher sampling speeds, look into the ways that are required to bypass Analog.read and have the ADC go directly to the pins in question. For example, you could set this up as a sub-routine with 100 samples taken, then return the speed based on the micro-seconds that have elapsed. One benefit of not using the analog.Read routines is that the ADC runs independently of the main CPU, you you can likely get some math done between each read (it's what I did with my energy logger - start sampling the voltage channel but work on the current data, then switch to measuring current while processing the just-sampled voltage data).
Title: Re: measuring time
Post by: CrossRoads on Mar 30, 2012, 06:39 pm
"The Arduino clock isn't very accurate so your timing may be off by minutes a day. "

I think that partly depends on whether the arduino uses a Crsytal vs a Resonator, and also how the seconds are tracked.

I have done tests with my duemilanove, it has tracked the official US time with no losses over a day.
http://www.time.gov/timezone.cgi?Eastern/d/-5/java

Code: [Select]

unsigned long previousTime = 0;
byte seconds ;
byte minutes ;
bytes hours ;
void setup(){
Serial.begin {9600);
}
// I  think using microseconds is even more accurate
if (millis() >= (previousTime)  ) {
previousTime = previousTime + 1000;  // use 100000 for uS
seconds = seconds +1;
if (seconds == 60)
{
seconds = 0;
minutes = minutes +1;
}
if (minutes == 60)
{
minutes = 0;
hours = hours +1;
}
if (hours == 13)
{
hours = 1;
}
Serial.print (hours, DEC);
Serial.print (":");
Serial.print (minutes,DEC);
Serial.print (":");
Serial.println(seconds,DEC);
} // end 1 second
} // end loop
Title: Re: measuring time
Post by: odometer on Apr 16, 2012, 12:18 am

FWIW, once you get ready to finalize the code, try to compress all the math calcs in this example into a constant float or long up front. The reason being, there is no benefit to recalculating "2.0*pi* 3600 * 1000" over and over, it's 22619467.11... Ideally, Define R in that function as well and you may not even need to use a float.


In a way, it is good that he is using "float", because this way there is less chance of overflow.
Also, I highly recommend using "micros()" here instead of "millis()".
You will probably also want to check for switch bounce (that is, when the sensor registers twice when it should only register once). If the "elapsed time" for one revolution of the wheel is less than 5 milliseconds, then the measurement should be rejected.
You will also need to check for speeds close to zero (that is, a long time without the wheel moving).
Title: Re: measuring time
Post by: runaway_pancake on May 13, 2012, 08:16 am
Hi, CrossRoads
There were a couple of typos, oversights in your code; it didn't compile.
I took the liberty of fixing that.
It works good!

Code: [Select]

/*  CrossRoads Time-clock  */

unsigned long previousTime = 0;
byte seconds ;
byte minutes ;
byte hours ;
void setup()
{
Serial.begin (9600);
}

void loop ()
{
// I  think using microseconds is even more accurate
  if (millis() >= (previousTime))
  {
     previousTime = previousTime + 1000;  // use 100000 for uS
     seconds = seconds +1;
     if (seconds == 60)
     {
        seconds = 0;
        minutes = minutes +1;
     }
     if (minutes == 60)
     {
        minutes = 0;
        hours = hours +1;
     }
     if (hours == 13)
     {
        hours = 1;
     }
  Serial.print (hours, DEC);
  Serial.print (":");
  Serial.print (minutes,DEC);
  Serial.print (":");
  Serial.println(seconds,DEC);
  } // end 1 second
} // end loop
Title: Re: measuring time
Post by: CrossRoads on May 13, 2012, 09:25 am
Well, making it from scratch at work while on a short break without a chance to compile will do that.
Can't believe I left out void loop(){ !
Title: Re: measuring time
Post by: robtillaart on May 13, 2012, 12:00 pm
Quote
// use 100000 for uS

100000 ?  ==> 1000000 :)
Title: Re: measuring time
Post by: CrossRoads on May 13, 2012, 06:05 pm
Yeah 5 zeroes, 6 zereos, whatever it takes 8)
Title: Re: measuring time
Post by: 2014sideline on Feb 18, 2016, 09:41 am
Hello,

Though this comment is too late but it might be helpful as knowledge base for newbies.

The above code is only correct if the loop is ticked every 1 second. Hence, you have to add delay(1000); as last row at the end of the loop() function.

Så the final version of lovely CrossRoad's code looks like below:

/*  CrossRoads Time-clock  */

unsigned long previousTime = 0;
byte seconds ;
byte minutes ;
byte hours ;
void setup()
{
Serial.begin (9600);
}

void loop ()
{
// I  think using microseconds is even more accurate
  if (millis() >= (previousTime))
  {
     previousTime = previousTime + 1000;  // use 1000000 for uS
     seconds = seconds +1;
     if (seconds == 60)
     {
        seconds = 0;
        minutes = minutes +1;
     }
     if (minutes == 60)
     {
        minutes = 0;
        hours = hours +1;
     }
     if (hours == 13)
     {
        hours = 1;
     }
  Serial.print (hours, DEC);
  Serial.print (":");
  Serial.print (minutes,DEC);
  Serial.print (":");
  Serial.println(seconds,DEC);
  } // end 1 second

  delay(1000); //This will ensure one loop per second

} // end loop
Title: Re: measuring time
Post by: JohnLincoln on Feb 19, 2016, 08:54 pm
The above code is only correct if the loop is ticked every 1 second. Hence, you have to add delay(1000); as last row at the end of the loop() function.
I have to disagree with you, 2014sideline.

If you use the function delay(1000), then the sketch will wait for 1 second (=1000 ms), during which time it can't do anything else, and then after that time has elapsed it has to update the hours, minutes and seconds, and then send the results to the serial monitor. 

This will take a finite time, so I think that means that your solution will always run slow (maybe not a lot).
Title: Re: measuring time
Post by: avalon90 on Aug 19, 2016, 09:10 am
Hi there, I'm new to arduino, I need some help trying to measure time between actuating to different switches.
ie. press  sw1 once and the press sw2 later. The time in between can be milliseconds.

Thanks.
Title: Re: measuring time
Post by: allanhurst on Aug 19, 2016, 09:22 am
Some arduinos use a ceramic resonator, which could be +/-  3%%

some use crystals, which could be as bad as +/- 100ppm - ie  0.01%

if this isn't good enough, buy a 30ppm crystal  - 0.003%

if you want better than this is it gets more expensive

regards

Allan
Title: Re: measuring time
Post by: MarkT on Aug 19, 2016, 12:48 pm
Call millis(), remember the result on each press, then you can subtract one from the other.
Title: Re: measuring time
Post by: dwightthinker on Aug 24, 2016, 07:21 am
When I needed accurate time, I use a DS3231 board
that I got from ebay. I set it to do a one second interrupt.
In the interrupt, I take a micros() reading.
When the code is running, I watch for an update from the one
second interrupt, while doing other things that take less than a second.
I take the result of the interrupts time reading from the
uPs clock and calculate the error. I apply it to the current
one second time span.
Even though the uP is running on a resonator, it is relatively
constant over a one second time span.
The drift rate is mostly related to temperature changes.
The change in rate is a little higher for the first 15 minutes
after power up and then slows down a lot.
Dwight
Title: Re: measuring time
Post by: it91 on Apr 25, 2017, 10:10 am
Hi everybody!

I'm almost new in Arduino and I'm trying to send a sample of an Ultrasonic (HC-SR04) sensor to PC over Bluetooth. The main problem is that time the pulseIn function I am using to work out the distance depends on the distance. I mean, the more distance, the more time it takes.

Any idea of how I can set the sampling time? I don't mind if it's not too quick because I will interpolate the signal in matlab.

I have tried using millis() but it doesn't work.

Thanks
Title: Re: measuring time
Post by: AWOL on Apr 25, 2017, 11:17 am
Quote
I have tried using millis() but it doesn't work
I can absolutely assure you that the millis function does work.

If the delay caused by increased range is a problem, you have at least two solutions:
A) reduce the range
B) increase the speed of sound - try an atmosphere of helium.
Title: Re: measuring time
Post by: mu234 on Sep 18, 2018, 02:09 pm
Code: [Select]

unsigned long StartTime = millis();

later...

unsigned long CurrentTime = millis();
unsigned long ElapsedTime = CurrentTime - StartTime;


That will give you the elapsed time in milliseconds, up to about 40 days.  If you need more precise measurement you can use 'micros()' instead of ''millis()' to get microseconds, up to a couple of hours, I think.

The Arduino clock isn't very accurate so your timing may be off by minutes a day.
Hello cheers for posting this!

I am using this code, but when I printout the elapsedTime sometimes I get the number which is not "useful" e.g.

StartTime: 313239   CurrentTime: 313247   ElapsedTime: 4294967288

Any idea what this is, and how to avoid this, if I want to use the elapsedTime in further code. For example, I would like to make a decision with regard to ElapsedTime, namely, if it is above certain time, below, etc.

Any ideas are welcome!

Best.

 



Title: Re: measuring time
Post by: Wawa on Sep 20, 2018, 08:54 am
It just calculates and displays the ElapsedTime in milliseconds.
Up to you to convert/print that in a human readable time format.
Look at this thread (https://forum.arduino.cc/index.php?topic=568923.0) how I did that for a laptime sketch.

If you want to make a decision, e.g for 10 minutes,
10 minutes = 10 * 60 * 1000 = 600000 milliseconds.
Then use an if/else statement to compare that to the ElapsedTime you got.
Leo..
Title: Re: measuring time
Post by: odometer on Sep 20, 2018, 02:38 pm
I am using this code, but when I printout the elapsedTime sometimes I get the number which is not "useful" e.g.

StartTime: 313239 CurrentTime: 313247 ElapsedTime: 4294967288

Any idea what this is, and how to avoid this, if I want to use the elapsedTime in further code.

Sure, I have an idea what it is.

You did the subtraction the wrong way around. What you did was StartTime minus CurrentTime. What you should have done would have been CurrentTime minus StartTime.
Title: Re: measuring time
Post by: MarkT on Sep 27, 2018, 11:08 pm
FWIW, once you get ready to finalize the code, try to compress all the math calcs in this example into a constant float or long up front. The reason being, there is no benefit to recalculating "2.0*pi* 3600 * 1000" over and over, it's 22619467.11... Ideally, Define R in that function as well and you may not even need to use a float.

Less calculations for Arduino to do = better responsiveness by Arduino.
The compiler does constant folding for you, its not the 1970's any more!!