Go Down

Topic: Accuracy of Arduino delay() command (Read 6101 times) previous topic - next topic

Fudge

Hello all. Not sure if this is in the correct place, sorry if it's not...

I have been searching for a few hours on this, but cannot seem to find a reasonable answer to this.

Basically, I am doing a assignment and am using short(ish) pulses, from 1ms to 100ms. I have two questions:


  • Is there any way to get shorter pulses, such as 0.5 or even 0.2ms pulses?

and
  • how accurate is the pulse command?



The first one is not crucial, I can live with 1ms pulses.

However, as this is a formal lab report, I need to state my error margins. To what extent is the delay command accurate? I would imagine something like 0.01ms, however I really have no clue on what it might be.

Any help would be greatly appreciated.

Thanks in advance,
Fudge.

Coding Badly

Quote
Is there any way to get shorter pulses, such as 0.5 or even 0.2ms pulses?


delayMicroseconds

Quote
how accurate is the pulse command?


Which "pulse commnad"?  pulseIn?

Fudge

Oops... my bad. Proofreading failure.

By pulse command, I meant delay. Basically, my code turns on, delays for however many milliseconds, then turns off. How accurate is the delay command?

robtillaart


for shorter pulses you may need to use direct port manipulation as digitalWrite itself takes some time too. Or use digitalWriteFast (google for it on the forum) which does just that but works only for fixed pins.
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Coding Badly

Quote
How accurate is the delay command?


For long time spans, it is very accurate.  For short time spans, not so much.  Given your concern for accuracy, you should be using delayMicroseconds and, as @robtillaart mentioned, direct port manipulation.

WillR

To assess accuracy you need an external time standard.

As for the rest... what board, what speed what crystal? is it 8MHZ or 16MHz...

Not sure how to help.
Just another Hacker

MarkT

I believe delay() has 1ms jitter as it just waits for millis() to increase by the appropriate value.

delayMicroseconds() is good but disables interrupts...

Suggest you compromise between the two and have a loop waiting for micros() to increase - jitter/granularity will be poorer than delayMicroseconds() but doesn't stop interrupts.
Code: [Select]

long target = micros() + delay_in_us ;
while (micros () < target) {}

[ I won't respond to messages, use the forum please ]

BenF

#7
Mar 02, 2011, 02:31 pm Last Edit: Mar 02, 2011, 02:42 pm by BenF Reason: 1
The delay() function is accurate to within +/- 4us for 16MHz Arduino's and to within +/- 8us for the 8MHz flavor irrespective of delay duration.

The delayMicroseconds function can be used for delays in the sub millisecond range. Exact timing however requires interrupts to be disabled (you have to code for this) when delayMicroseconds is running.

MarkT

Ah, I was wrong - delay() already uses the approach I gave - so the jitter is much less than 1ms.  The accuracy of delay() is affected by any slow interrupt handlers that you have running though, note.
[ I won't respond to messages, use the forum please ]

Coding Badly

Quote
RE: delay ... For long time spans, it is very accurate.  For short time spans, not so much.


What was I thinking!  That is definitely no longer correct.  My apologies.

westfw

delay() was changed in the 0020 release (first version supporting Uno.)
I'm actually not all that fond of the change.  It's bigger and less elegant, and I think it's no longer true that the time read from millis() will differ by N after you delay() for N milliseconds (though I'm not sure where that would matter.)

BenF


I'm actually not all that fond of the change.  It's bigger and less elegant, and I think it's no longer true that the time read from millis() will differ by N after you delay() for N milliseconds (though I'm not sure where that would matter.)

I believe we concluded at the time that the new delay() function was shorter by 20 bytes than what we replaced and also that accuracy improved from +/- 2ms to +/- 4us (16MHz). There were a number of posts complaining about short delay inaccuracy prior to the change and I haven't seen any since.

The millis() difference after delay(N) was as much an issue before as it is now (+/- 2ms accuracy).

So then what is the better general purpose millisecond delay() function?

Go Up