The compiler has realized that your loop doesn't do anything useful and therefore optimized the whole thing away. Thus you are just timing how long it takes to do nothing. (You didn't get a result of zero, because calling micros
will itself take time).
BTW, the granularity of micros
is 4 µs, so you won't get a reading of 1 or 2. The code actually probably only took a couple of microseconds.
You need to do something that the compiler thinks "does something", like this:
void setup() {
Serial.begin(115200);
}
volatile byte b;
void loop() {
unsigned long a = micros();
for (unsigned long j = 0; j < 100; ++j)
b++;
Serial.println ((micros() - a));
delay(1000);
}
By making b
volatile the compiler cannot decide that b
isn't doing anything useful, so now the timings make sense.
I got 72 for 100 iterations and 144 for 200 iterations.
Is there a function which I can use to measure time properly in arduino?
Your time measurement is fine. Your interpretation of the results indicates you didn't realize how smart the compiler is. :)
You can see what the compiler did if you examine the generated code:
unsigned long a = micros();
d8: 0e 94 d2 00 call 0x1a4 ; 0x1a4 <micros>
dc: 6b 01 movw r12, r22
de: 7c 01 movw r14, r24
for (unsigned long j = 0; j < 100; ++j);
Serial.println ((micros() - a));
e0: 0e 94 d2 00 call 0x1a4 ; 0x1a4 <micros>
e4: ab 01 movw r20, r22
e6: bc 01 movw r22, r24
As you can see, between the two calls to micros
there isn't any sort of loop.
To find the assembled code you can follow the steps documented here.
Basically, turn on "verbose compiling" which will show near the end of the verbose output the full pathname of the ".elf" file. Then use a command (terminal) window to enter this command:
avr-objdump -S xxx.elf
You may want to redirect the output to a file:
avr-objdump -S xxx.elf > myfile.txt
Depending on how the Arduino IDE was installed you may have to find the pull pathname of avr-objdump
and use that instead of just the program name.