IntervalTimer

IntervalTimer uses interrupts to call a function at a precise timing interval.

Advanced programming is required to properly use
IntervalTimer, because your function runs as an interrupt. See
below for details.

IntervalTimer is generally recommended for use only in libraries
and advanced applications which require highly precise timing. Usually the
Metro library
or an elapsedMillis variables
are easier to use, because they avoid the pitfalls of interrupt programming.

IntervalTimer Usage

IntervalTimer myTimer;

Create an IntervalTimer object. You may create as many IntervalTimers
as needed, but only a limited number may be active simultaneously.
Normally IntervalTimer objects should be created as global variables.

myTimer.begin(function, microseconds);

Begin calling the function. The interval is specified in microseconds, which
may be an integer or floating point number, for more highly precise timing.
This functions returns true if successful. False is returned if all hardware
resources are busy, used by other IntervalTimer objects.

myTimer.priority(number);

Set the interrupt priority level, controlling which other interrupts this
timer is allowed to interrupt. Lower numbers are higher priority, with
0 the highest and 255 the lowest. Most other interrupts default to 128. As a
general guideline, interrupt routines that run longer should be given
lower priority (higher numerical values).

myTimer.update(microseconds);

Change the interval. For an active IntervalTimer, the current timing interval
completes as scheduled, then this new interval is automatically used for the
next timing interval. To immediately begin a new interval, without completion
of the current interval as scheduled, use begin(). For an inactive
IntervalTimer, this function does nothing.

myTimer.end();

Stop calling the function. The hardware resource becomes available for use
by other IntervalTimer objects.

Example Program

// Create an IntervalTimer object IntervalTimermyTimer;constintledPin=LED_BUILTIN;// the pin with a LEDvoidsetup(){pinMode(ledPin,OUTPUT);Serial.begin(9600);myTimer.begin(blinkLED,150000);// blinkLED to run every 0.15 seconds}// The interrupt will blink the LED, and keep// track of how many times it has blinked.intledState=LOW;volatileunsignedlongblinkCount=0;// use volatile for shared variables// functions called by IntervalTimer should be short, run as quickly as// possible, and should avoid calling other functions if possible.voidblinkLED(){if(ledState==LOW){ledState=HIGH;blinkCount=blinkCount+1;// increase when LED turns on}else{ledState=LOW;}digitalWrite(ledPin,ledState);}// The main program will print the blink count// to the Arduino Serial Monitorvoidloop(){unsignedlongblinkCopy;// holds a copy of the blinkCount// to read a variable which the interrupt code writes, we// must temporarily disable interrupts, to be sure it will// not change while we are reading. To minimize the time// with interrupts off, just quickly make a copy, and then// use the copy while allowing the interrupt to keep working.noInterrupts();blinkCopy=blinkCount;interrupts();Serial.print("blinkCount = ");Serial.println(blinkCopy);delay(100);}

IntervalTimer will call you function from interrupt context.
Because it can interrupt your program at any moment, special design is
necessary to share data with the rest of your program.

Many ordinary functions are not designed to work properly from
interrupt context. String objects should be avoided. A general
guideline is to keep your function short and avoid calling other
functions if possible.

Variables usually need to be "volatile" types. Volatile tells the compiler to avoid optimizations that assume variable can not spontaneously change. Because your function may change variables while your program is using them, the compiler needs this hint. But volatile alone is often not enough.

When accessing shared variables, usually interrupts must be disabled. Even with volatile, if the interrupt changes a multi-byte variable between a sequence of instructions, it can be read incorrectly. If your data is multiple variables, such as an array and a count, usually interrupts need to be disabled for the entire sequence of your code which accesses the data.