Problem with delayMicroseconds - inconsistent intervals

The test I describe below has been done on several boards:
Arduino Uno and Arduino nano AT328p.

I need a micro second accuracy to properly control a stepper motor, and I came across inconsistent delays as the delay increases.

Program:

void f_Delay_Micro_Sec( unsigned int Delay)
{
unsigned long useconds, useconds_Dif;
char Buffout[30];
useconds = micros();
delayMicroseconds(Delay);
useconds_Dif = micros() - useconds;
sprintf(Buffout, "\n Requested=%4u Real=%4lu",Delay, useconds_Dif);
Serial.print(Buffout);
}

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

f_Delay_Micro_Sec( 10 );
f_Delay_Micro_Sec( 50 );
f_Delay_Micro_Sec( 100 );
f_Delay_Micro_Sec( 200 );
f_Delay_Micro_Sec( 250 );
f_Delay_Micro_Sec( 300 );
f_Delay_Micro_Sec( 500 );
f_Delay_Micro_Sec( 800 );
f_Delay_Micro_Sec( 900 );
f_Delay_Micro_Sec( 1000 );
f_Delay_Micro_Sec( 1100 );
f_Delay_Micro_Sec( 1200 );
f_Delay_Micro_Sec( 1500 );
f_Delay_Micro_Sec( 2000 );
f_Delay_Micro_Sec( 2500 );
f_Delay_Micro_Sec( 3000 );
f_Delay_Micro_Sec( 4000 );
}

Results:

Requested= 10 Real= 12
Requested= 50 Real= 52
Requested= 100 Real= 120
R Reqsted= 200 Real= 220
Requested= 250 Real= 276
Requested= 300 Real= 336
Requested= 500 Real= 556
Requested= 800 Real= 888
Requested= 900 Real= 996
Requested=1000 Real=1112
Requested=1100 Real=1216
Requested=1200 Real=1328
Requested=1500 Real=1664
Requested=2000 Real=2224
Requested=2500 Real=2772
Requested=3000 Real=3332
Requested=4000 Real=4232

Why is this happening ?

Could it be something to do with the serial output?

Try a serial flush at the end of your timing function.

Also, check the documentation for delayMicroseconds

See the micros() documentation.

Guys, the delay is in microseconds, not percentage of the processor speed.

if you look at the results, you will see that when increasing the number of microseconds, the real delay is increasing by an increasing percentage until it reaches hundreds of micro seconds.

Did you try the flush?

It is not a question o flushing the serial, because when data is sent to serial, all the calculation and preparation of the buffer was done before no matter how long it takes to send to serial

So, you didn't try the flush.

As you can see, the program is very simple, did you try in your board ?

flushing serial results in cleaning the serial content. The content is ok, and the the timing that takes to send to serial does not interfere in this result.

Foco_Arduino:
As you can see, the program is very simple, did you try in your board ?

I'm on a train, with my phone - I don't have a board.
I'm just chucking out ideas.

I don't think filling the serial buffer explains this, as the serial buffer bottleneck would leave the code getting hung up at the calls to Serial.print - but that's outside of the part being timed.....

That said, you should still flush the serial port after each round. Or just delay() long enough to make sure the serial data has a chance to send.

The people who post suggestions on this forum generally do so when we're not at our workshop - on train, during lunch, while waiting for stuff. When we're at home in our workshop, we usually have more compelling things to do, like working on our own projects.

Home now.
With Serial flush 8)

 Requested=  10 Real=  12
 Requested=  50 Real=  52
 Requested= 100 Real= 104
 Requested= 200 Real= 204
 Requested= 250 Real= 256
 Requested= 300 Real= 304
 Requested= 500 Real= 500
 Requested= 800 Real= 808
 Requested= 900 Real= 908
 Requested=1000 Real=1008
 Requested=1100 Real=1112
 Requested=1200 Real=1208
 Requested=1500 Real=1508
 Requested=2000 Real=2016
 Requested=2500 Real=2524
 Requested=3000 Real=3020
 Requested=4000 Real=4024

Please remember to use code tags when posting code.

AWOL:
Home now.
With Serial flush 8)

 Requested=  10 Real=  12

Requested=  50 Real=  52
Requested= 100 Real= 104
Requested= 200 Real= 204
Requested= 250 Real= 256
Requested= 300 Real= 304
Requested= 500 Real= 500
Requested= 800 Real= 808
Requested= 900 Real= 908
Requested=1000 Real=1008
Requested=1100 Real=1112
Requested=1200 Real=1208
Requested=1500 Real=1508
Requested=2000 Real=2016
Requested=2500 Real=2524
Requested=3000 Real=3020
Requested=4000 Real=4024




Please remember to use code tags when posting code.

I stand corrected. Interesting.

DrAzzy:
Interesting.

. . . but not unexpected.

I just tested with flush and you were right.

Although time collection is done immediately before and after the delay request, there are interrupts occurring in the background with the serial that interfere with the result.

Thank you very much for the information and your time.

Sometimes we forget that background activities interfere.

Foco_Arduino:
Sometimes we forget that background activities interfere.

...and sometimes, we just forget to listen