delayMicroseconds(0) = 16383µs

bperrybap:
The real question is if you want a delay of 1us when the delay you are asking for is 0?

And my question of curiosity is why are you asking for a delay of zero?
Is this caused by some sort calculation that results in truncation?

No, this is a real glaring bug and it should be fixed in the library source. There are many times
you will want to calculate a delay and don't want to have to deal with zero as a special case.
The restriction on the argument size is also a bit yucky and incompletely documented - it depends on the system
clock speed whether delayMicroseconds(20000) does what you expect, for instance!

MarkT:

bperrybap:
The real question is if you want a delay of 1us when the delay you are asking for is 0?

And my question of curiosity is why are you asking for a delay of zero?
Is this caused by some sort calculation that results in truncation?

No, this is a real glaring bug and it should be fixed in the library source. There are many times
you will want to calculate a delay and don't want to have to deal with zero as a special case.
The restriction on the argument size is also a bit yucky and incompletely documented - it depends on the system
clock speed whether delayMicroseconds(20000) does what you expect, for instance!

My questions were totally separate from the question as to whether the library should be fixed.
And we still don't know if k7michal needs a delay of 1us rather than no delay when a delay of zero
was asked for.

Whether it should be fixed could be argued either way. It could be documented as explicitly not
working for 0 or it could be fixed, but fixing it may have side effects like reducing the minimum supported delay.

I always try to do as much at compile time as possible so
typically when I have code that does sub millisecond or even sub microsecond delays, there is no calculation occurring runtime
because the delay is usually do to some hardware constraint that is known in advance.
Any needed delay value calculations are all done at compile time.
Where cycles really matter, I use macros that ensure that if the delay is zero or not needed,
that any delay related code is completely eliminated.

--- bill

My questions were totally separate from the question as to whether the library should be fixed.
And we still don't know if k7michal needs a delay of 1us rather than no delay when a delay of zero
was asked for.

If the alternative is ~15 thousand times worse, the 1.1us overhead isn't a hard pill to swallow, If
I called delayMicroseconds(0) I'd expect it to return quickly, I wouldn't expect it to take 0us though
as I have enough common sense to understand that it can't.

Remember it is the sister function to delay() which has no such whackiness.

MarkT:
Remember it is the sister function to delay() which has no such whackiness.

That is probably the best argument to fix it.

My concern is that fixing it makes some normal cases no longer work as well or not at all.
That is what happened when pulsein() was "fixed".
Resolution was lost and it still has some "gotchyas" in it.

--- bill

bperrybap:

MarkT:
Remember it is the sister function to delay() which has no such whackiness.

That is probably the best argument to fix it.

My concern is that fixing it makes some normal cases no longer work as well or not at all.
That is what happened when pulsein() was "fixed".
Resolution was lost and it still has some "gotchyas" in it.

--- bill

Well that wouldn't be a fix would it? I wasn't claiming its necessarily straightforward to fix (which
is presumably the reason its incompletely implemented in the first place)

my appologies for the delayMicroseconds(0) in replying.... pun intended.

I'm working on an ignition timing circuit which has a potentiometer on A0 that essentially translates into a delay that is the inverse of the Timing Advance. So, if I want all 20 degrees advance then my pot is set to 0 and that is translated into delayMicroseconds(0).

I'm using this function because I want as much resolution as possible... and adding say 20-40us of programming overhead is still acceptable compared to being limited to a 1ms resolution..

This is how I've been coping with the 0 and 16383 limit:

 if (u_offsetTime == 0){    //when delayMicroseconds(0) = 16383µs.. glitch in library.
    u_offsetTime = 1;}
    
  if (u_offsetTime >= 0x3ffe){ //delayMicroseconds limit is 0x3fff, so we seperate the number into 2 variables.
    u1_offsetTime = (u_offsetTime - 0x3ffe); //made this 1 less than 0x3fff because I want to be EXTRA sure that it doesn't do funny things.
    u_offsetTime = 0x3ffe;
     
    if (u1_offsetTime >= 0x3ffe){
      u2_offsetTime = (u1_offsetTime - 0x3ffe);
      u1_offsetTime = 0x3ffe;}
      else { u2_offsetTime = 1;}        
}
  else {
    u1_offsetTime = 1;
  }

so far it seems to be working fine and I'm able to have (16382 * 3)us of delay if I need it...

I feel like I'm trying to cut a turkey with a fork. It's crewed but it seems to be working.

Thanks for all the replies.

Sidetrack:

Why is anyone calling delayMicroseconds(0) in the first place?

MarkT:

bperrybap:

MarkT:
Remember it is the sister function to delay() which has no such whackiness.

That is probably the best argument to fix it.

My concern is that fixing it makes some normal cases no longer work as well or not at all.
That is what happened when pulsein() was "fixed".
Resolution was lost and it still has some "gotchyas" in it.

--- bill

Well that wouldn't be a fix would it? I wasn't claiming its necessarily straightforward to fix (which
is presumably the reason its incompletely implemented in the first place)

But the Arduino team is notorious for these kinds of "fixes"
because one mans "fix" is potentially another mans "bug" or loss of
functionality.
pulsein() was considered "fixed" even though some functionality was lost.
Example: accuracy of using certain ultrasonic distance finders.

There were many "fixes" put into Arduino 1.0 at the last minute.
Look at the Serial flush(), it used to work by purging the rx buffer. Now
HardwareSerial tries to wait for the transmitted characters to be transmitted
but it doesn't. It only waits for the s/w buffer to empty (there are still characters
inside the AVR) and then to make matters worse, the SoftSerial still has the old flush() functionality.
Then there is the Print class, that was "fixed" in 1.0 to return characters on write() which broke
100% of the 3rd party s/w and sketches that used write().
Then there is the changing of the wire library in 1.0 to rename send() to write()
again breaking 100% of the 3rd party s/w that used the wire library.
Several of these types of "fixes" (changes/updates) could have been implemented in other
ways that wouldn't have broken things or lost functionality, and in a few
like the write() vs send() change in the wire library, the Arduino knew about it,
knew the simple change that could be done to not break anything, and yet
stated that they wanted to blaze forward with a path
that intentionally breaks all the s/w that used wire as
a method of forcing everyone to "fix" their code.

Just saying be very careful what you wish for. You may just get it at
the expense of losing something else.

--- bill

JimEli:
Sidetrack:

Why is anyone calling delayMicroseconds(0) in the first place?

Because sometimes 1ms is WAY too long of a delay.

I have a glcd library where even 1us is WAY too long.

For that I use a cycle accurate delay routine that self adjust based on
the MCU clock rate.

--- bill

If I wanted a super short and accurate delay I would probably activate a Timer and do a Capture Match sequence directly in the hardware.

However I used this delayMicroseconds() function because I have conditions which require long delays (as a generator starts) and eventually once the generator is up to speed the delays have to be within a 0.025 ms accuracy.

K7

If I wanted a super short and accurate delay

Turning off interrupts and using NOP would do that.

Quote
If I wanted a super short and accurate delay

Turning off interrupts and using NOP would do that.

yeah, but interrupts are fun and you can have the Timer do it's thing while executing a few commands.

K7

Interrupts suffer from latency (well into us range) so it wouldn't be suitable for short delays.

If you have to use timers, you can simply wait for a timer to run up a desired number of ticks.