Testing the Function at micros()

monday Apr 18 2011

To test the micros() fuction I run the following progrm.


unsigned long time;

void setup(){
Serial.begin(9600);

}
void loop(){

Serial.print("Time: ");
time = micros();
//prints time since program started
Serial.println(time);
// wait 1/1000 second to see how much will change at micros().
delay(1);
}


This progtram is to test, during 1/1000 second what is the value of micros(). I got the result that is unexpected.

First:
I run this program in about one second. I got information from the serial monitor
...

Time: 11945552
Time: 11962192
Time: 11978832
Time: 11995472

...

so the micros()'s value at 1/1000 second is

11962192 - 11945552 = 16640

but after about 10 second I got information that had changed a lot from the serial monitor
...
Time: 102355872
Time: 102373552
Time: 102391232
Time: 102408912

...
so the micros()'s value at 1/1000 second is

102373552 - 102355872 = 17680

this change is more than 5%
(17680 - 16640 )/17680 = 0.0588

I test this for a few times. The result is almost the same: at start, the micros() value is small---close to 15600, and after about ten sedond the micros() value will change to biger ---- close to 17680.

why ?

second , I noted the Arduino Uno microprocessor's working frequence is 16 MHz

so during 1/1000 second the micros() value should be 16000. That is correct ?

Third, what is the physical tolerance of the part---- 16 MHz crystal oscillator ?

The difference in values that you see includes the time it takes to output the serial data - a non-trivial amount of time at 9600 baud.

so during 1/1000 second the micros() value should be 16000. That is correct ?

No. A call to micros(), a 1 millisecond delay, and another call to micros() should result in a difference of little more than 1000.

The Serial.print()s are what is killing you.

micros() has a resolution of microseconds, so you will never see (or you should not expect to see) an exact value when comparing two calls to micros().

In the loop you are running, the time you delay versus the time it takes to do all of the Serial.print()s may be affecting your results. You might try running your test in a for loop over a large number of values (like 100) and only doing a print of the results.

Why don't you try this one out. It takes out all the delay caused by the serial printing. My output prints a consistent 1008 per loop. Recall that micros() has a 4 usec resolution.

From the arduino reference on micros() :

"On 16 MHz Arduino boards (e.g. Duemilanove and Nano), this function has a resolution of four microseconds (i.e. the value returned is always a multiple of four). "

unsigned long start_time;
unsigned long stop_time;
unsigned long elapsed_time;


void setup(){
  Serial.begin(9600);
  
}
void loop(){

  start_time = micros();
  delay(1);                   // wait 1/1000 second to see how much will change at micros().
  stop_time = micros();
  elapsed_time = stop_time - start_time;
  Serial.print("Time: ");
  Serial.println(elapsed_time);

  }

Lefty

Thank you guys
retrolefty , your program is so beautiful, I run it again, get 1008(most) and 1004(a few). It is great to help me to understand micros().