Go Down

Topic: delayMicroseconds(0) (Read 5898 times) previous topic - next topic


Nov 18, 2007, 04:37 am Last Edit: Nov 18, 2007, 05:36 am by paulb Reason: 1
"Then that's where the check needs to be - not in the library!"

Except that the language is supposed to be easy to use for beginners. The function dumbs down the resolution to 1 us from .25 us (ostensibly to make it easier to use) so what the heck is one more check. (.25 us?).

Anyone using the language could easily expect delayMicroseconds(0) to generate as-close-to-zero-as-possible a delay not 1023 us.

BTW - negative numbers are also going to generate long delays I think.
Checking for errors in this function makes for one more place the code can't screw up. If you want to argue for efficient machine code fine - but you've got to explain all the other inefficiencies, of which the 1 us resolution is only one. And also the stated philosohpy of making something for beginner coders.

It's been traumatic for certain parties to even see documentation of C and AVR arcana in the reference section.

I repeat - fix this ______ instead of documenting it.

if (--us < 2)

Doesn't that fix it? Predecrement and one comparison.
You've got your predecrement to bring to the party!

Would making the parameter a signed long also fix negative numbers this way?
How does that playout with the right bitshift 2 dumbdown (er ease of use feature)

Anyway the rumor is that we're due to get a whole new timing system for Arduino 0011. Is this still on track?

Yours in tightly balanced tradeoffs,



Dec 23, 2007, 06:50 pm Last Edit: Dec 23, 2007, 06:54 pm by paulb Reason: 1

I did some testing of the code change and (surprisingly) it seems to make no difference in timing.

Here's the relevant code in delayMicroseconds function

     // code A
//      if (--us == 0)          // decrement to offset function overhead
//      return;

Here's the code fix

     // code B
     if ((int)us < 2 )      // cast cures negative number rollover
        us--;                   // decrement to offset function overhead

code A is the original and code B is the fix.

I can detect absolutely no difference in the testing I did except code B fixes the issues.

Here's the test setup (I can see your eyes glazing over - snap out of it!)

/* Test delayMicroseconds() with param of zero

int tdelay;
unsigned long i, hz;
unsigned long start, TotalLoopTime;
int outPin = 11;

void setup(){
 pinMode(outPin, OUTPUT);

void loop() {
   start = millis();                      // get start time of  loop
   for (i = 0; i < 1000000; i++){         // a million times through the loop
   TotalLoopTime = millis() - start;      // compute time through inner loop in milliseconds
 Serial.print("time = ");
 Serial.println(TotalLoopTime, DEC);

Here's the results

value of param        0         1            2              4
Code A             rolls over  3011         3953       5959        results in milliseconds

Code B               3011      3011         3953        5959

All of the numbers jitter randomly by one or two, presumably because of interrupt firings or serial.print or some other unknown (to me) phenomenon.

Please replicate my results on this if you care, then can we finally fix the code and move on?

A more patient math-head than me might also want to see if the function is as advertised, with about 1 us going into the function overhead.

There is another decrement farther down in the code that could be combined with the decrement to tweak timing. Should anyone care to get into it. I imagine it's only going to be possible to confirm this through some patient work with an oscilloscope or through sorting through the machine code and counting instructions, though. I'm not up for either at this point.

Yours in easy-to-use microcontroller code,

Paul Badger


Jan 27, 2009, 04:33 am Last Edit: Jan 27, 2009, 12:48 pm by paulb Reason: 1
I'm writing to see if I can get some of the amazing coders who are currently reading this list to test this proposed fix and confirm my results. It's possible that the fix works differently now since it was last tested with Arduino 10/11.

According to my results this fix is FREE and works EXACTLY LIKE THE ORIGINAL function except without the nasty surprise when using zero or neg numbers for a parameter.

Perhaps someone could decompile and look at the machine code to confirm that the two are equivalent.

If this is the case, then the reason for leaving in this irritating bug in a language / project whose stated goals is to make programming easy for beginners is perplexing. Or at least it tends to make one wonder if there are other reasons....


Go Up