Source: https://mokxi.com/learn/arduino-delaymicroseconds

Learn

# Arduino delayMicroseconds(): short waits, measured

Beginner

Written by the Mokxi team

Start building free Open the editor

Or see every lesson.

- 455 parts on the bench
- 43 boards running now
- 1.00x real time, on every board

Click to open it in the editor

The slider sets the angle; every pulse to the servo is timed with delayMicroseconds().

delayMicroseconds(us) waits for that many millionths of a second, then carries on. Use it for the short, exact waits that delay() is too coarse for: the 10 µs trigger pulse of an ultrasonic sensor, a servo’s 1 to 2 ms pulse, the step pulses of a stepper driver. For anything over about 16 milliseconds, use delay() instead: on an Uno, delayMicroseconds() cannot count that high.

The circuit above is the servo fader. Press Run and drag the slider. The servo follows, and the serial monitor prints each angle, such as "fader 1000 -> 175 degrees". The servo code underneath makes every pulse with delayMicroseconds(): 544 µs for 0 degrees, 2400 µs for 180, fifty times a second.

Below is how long it really waits, the limit and what happens past it, a servo pulse made by hand, and the mistakes people make with it, each run on an Uno with micros() timing it.

## delay() or delayMicroseconds()

delay() counts in milliseconds and delayMicroseconds() in microseconds, a thousand times smaller. delay(1) and delayMicroseconds(1000) are both a millisecond: timed with micros(), they both took 1020 µs. Both stop the sketch while they wait, so neither is a way to do two things at once. That is a job for millis().

micros() itself counts in steps of 4 µs on a 16 MHz Uno, so every time below is a multiple of 4. That is also the finest step you can measure with it: to time something shorter, run it a thousand times and divide, as the short waits below do.

## How long it really waits

This sketch times seven waits with micros(). It printed "10 us took 16", "100 us took 104", "1000 us took 1016" and "10000 us took 10140". The extra few microseconds are the call itself and micros(). The longer waits come out 1 to 2 percent long because the timer interrupt that keeps millis() going runs every 1024 µs and the wait does not stop for it.

Then the limit. "16383 us took 16608", and 16384 took 16612. 20000 took 3668. That is not a typo: delayMicroseconds() on an Uno counts in a 16-bit number of quarter microseconds, so anything past 16383 wraps around. 20000 is 3616 past the limit, so it waited about 3.6 ms.

Time seven waits

## Very short waits

Under about 3 µs the call itself takes longer than the wait. This sketch runs each value a thousand times. 0 took 1376 µs in total, 1 took 1380 and 2 took 1388, then 3 took 3408, 4 took 4432 and 5 took 5444. So 1 and 2 wait no longer than 0 (the few microseconds between the three are where the timer interrupt landed), and from 3 up each call is the value plus about 0.4 µs.

Mokxi’s Uno core returns at once for 0, 1 and 2, because the call alone already takes about that long; the Arduino core does the same for 0 and 1. If you need a pulse shorter than a few microseconds, write the port register directly rather than calling digitalWrite() and delayMicroseconds().

A thousand short waits

## A servo pulse by hand

A servo reads the width of a pulse, sent about 50 times a second: about 544 µs for 0 degrees and 2400 µs for 180. This sketch makes the pulse itself, with no library. With 1500 the servo went to 94.0 degrees. With 1000 it went to 45.5 and with 2400 to 180.

1472 µs is the exact middle, and that put the servo at 91.3 degrees, not 90. The extra degree comes from digitalWrite(): each call takes a few microseconds, so the pulse comes out about 12 µs wider than the number you wrote. The Servo library allows for that, which is one reason to use it.

A servo pulse with no library

## A square wave, and why it comes out slow

Two waits of 50 µs should make a 10 kHz square wave. A frequency counter on pin 9 read 8732 Hz. The same sketch with 500 µs waits read 980 Hz instead of 1000. The gap is the same few microseconds of digitalWrite() and loop() on every half wave, which matters more the shorter the wait.

For a steady frequency, let the hardware do it: tone() for sound and analogWrite() for PWM run on a timer and do not drift with your code.

A square wave on pin 9

## Common mistakes

Passing more than 16383. delayMicroseconds(20000) waited 3668 µs here. For the 20 ms gap between servo pulses, use delay(20); with delayMicroseconds(20000) the servo sketch above sent 194 pulses a second instead of 46.

Using it to time long things. A loop of a thousand delayMicroseconds(10) calls took 10388 µs, not 10000. The errors add up; use micros() to check the time instead of adding waits.

Expecting 1 µs to be 1 µs. The call itself is longer than that.

Using it to do two things at once. Like delay(), it blocks. Use millis() or micros() and check the time instead.

## Questions

What is the maximum value for delayMicroseconds?

16383 on a 16 MHz Uno. Larger values wrap around: delayMicroseconds(20000) waited about 3.6 ms here. Use delay() for anything longer than about 16 ms.

What is the difference between delay and delayMicroseconds?

delay() waits in milliseconds and delayMicroseconds() in microseconds, a thousand times shorter. delay(1) and delayMicroseconds(1000) both wait about a millisecond. Both block the sketch while they wait.

How accurate is delayMicroseconds?

Within a few microseconds for short waits: 100 took 104 µs here. Longer waits run 1 to 2 percent long because the millis() timer interrupt keeps running, and waits of 1 and 2 µs take no longer than 0.

Does delayMicroseconds block other code?

Yes. Nothing else in loop() runs until it returns, the same as delay(). Interrupts still run, which is why long waits come out a little long.

Related

## Keep going

Arduino millis(): Timers and Multiple Tasks Arduino Blink Without Delay: Two LEDs, Two Rates Arduino Servo Motor with a Potentiometer Arduino Ultrasonic Sensor (HC-SR04) Tutorial Arduino PWM Frequency: 490 Hz, 980 Hz, How to Change The servo fader project Beginner The free Arduino simulator The project page, with the full sketch Beginner

Sources

## Where the facts on this page come from

- Arduino reference: delayMicroseconds()
- Arduino reference: micros()

## Build this for real

Open the editor, change a value and watch the number move with it. Nothing to install, and no account needed.

Start building free Open the editor
