unsigned long millis()
unsigned long micros()
void delay(unsigned long milliseconds)
void delayMicroseconds(unsigned long microseconds)
See the elapsedMillis header for constructors and operators of that class. In short:
For very simple sketches, writing blocking code using
delayMicroseconds() can be appropriate. When things get more complex, using these functions can have some drawbacks. Some of these are:
delay()is called in subroutines that are not obviously called, for example in libraries you include.
millis() usually relies on a hardware timer that runs at a speed that's much higher than 1 kHz. When
millis() is called, the implementation returns some value, but you don't know how old that actually is. It's possible that the "current" millisecond just started, or that it will end right after that function call. That means that, when calculating the difference between two results from
millis(), you can be off by anything between almost zero and almost one millisecond. Use
micros() if higher precision is needed.
Looking into the source code of
elapsedMillis reveals that it indeed uses
millis() internally to compare two points in time, so it suffers from this effect as well. Again, there's the alternative
elapsedMicros for higher precision, from the same library.