From Arduino reference on delayMicroseonds
:
Currently, the largest value that will produce an accurate delay is 16383. This could change in future Arduino releases. For delays longer than a few thousand microseconds, you should use delay() instead.
Although the reference does not specify further what happens if delay > 16383
, a look at the actual code explains this (in wiring.c
):
/* Delay for the given number of microseconds. Assumes a 1, 8, 12, 16, 20 or 24 MHz clock. */
void delayMicroseconds(unsigned int us)
{
...
#elif F_CPU >= 16000000L
// for the 16 MHz clock on most Arduino boards
// for a one-microsecond delay, simply return. the overhead
// of the function call takes 14 (16) cycles, which is 1us
if (us <= 1) return; // = 3 cycles, (4 when true)
// the following loop takes 1/4 of a microsecond (4 cycles)
// per iteration, so execute it four times for each microsecond of
// delay requested.
us <<= 2; // x4 us, = 4 cycles
// account for the time taken in the preceeding commands.
// we just burned 19 (21) cycles above, remove 5, (5*4=20)
// us is at least 8 so we can substract 5
us -= 5; // = 2 cycles,
...
// busy wait
__asm__ __volatile__ (
"1: sbiw %0,1" "\n\t" // 2 cycles
"brne 1b" : "=w" (us) : "0" (us) // 2 cycles
);
// return = 4 cycles
}
The line us <<= 2;
explains why us
should not exceed 16383, otherwise the left-shifted value will overflow (unsigned int
is 16 bits on AVR).
In your situation, (20000-2500) << 2
will not be 70000
or 0x11170
in hexa (that does not fit into unsigned int
), hence the result will be truncated to 0x1170
i.e. 4464
, which will make the last part of the function (the busy wait) wait for the wrong duration.
In order to fix it, you have to split your second delayMicroseconds
in one delay
in milliseconds plus one delayMicroseconds
:
delay(17);
delayMicroseconds(500);