-1

i just experimented with the timing accuracy of my Arduino Uno R3 using this code:

unsigned long beginTime;
unsigned long endTime;

void setup() { Serial.begin(9600); // open a serial port }

void loop() { beginTime = micros(); delayMicroseconds(200); endTime = micros(); delay(500); Serial.println(endTime-beginTime); delay(500); }

The results I got are (just an excerpt):

200
204
200
200
204
204
204
200
212
208
212
204
204

I tried to understand this behavior, read this link Can I make delayMicroseconds more accurate?.

Due to the timing of micros (4 µs) I would understand values between 200 and 208. But why do I get occasional values of 212 microseconds? I'm kinda curious, since I bought the Arduino because of bare-metal programming and bounded execution times.

Michael S
  • 101
  • 2

1 Answers1

2

The Arduino core uses hardware Timer0 with its ISR (Interrupt Service Routine) for timekeeping. While delayMicroseconds() directly uses the value of the hardware timer, delay() and millis() are handled by the ISR. It will be called regularly.

If the ISR is getting executed during your measurement, then the execution time of the ISR will add to the execution time of your measured code. Thus you get a higher count occasionally.

To prevent this you can either deactivate all interrupts (via noInterrupts()) or deactivate this specific interrupt, either by stopping Timer0:

TCCR0B &= ~( (1 << CS02) | (1 << CS01) | (1 << CS00) );

or by letting the timer run, but deactivating its interrupts:

TIMSK0 = 0;

For details about this have a look at the datasheet of the Atmega328p, which is the microcontroller on the Arduino Uno.

chrisl
  • 16,622
  • 2
  • 18
  • 27