Introduction: Arduino - Periodic Interrupt

This Instructable is about using a periodic interrupt for timing in Arduino programs. This is a step for a budding Arduino programmer who knows that the Arduino can do more, but doesn't quite know how to make that happen.

If there's a performance problem I'm assuming that you're using one or more delay() functions. The trick is to get rid of the delay() function(s) and substitute an interrupt. The delay() function forces the Arduino to do nothing while waiting for the delay() to complete. Using an interrupt allows your program to do other things while waiting for the end of the delay. There is usually a huge amount of unused dead time that could be used for other things when using delay(). Using an interrupt solves this problem.

Step 1: Interrupt Handler

1. Add the interrupt handler to your program. Just copy and paste somewhere above setup();

const unsigned long TIMER0_COUNT = 500;    // 500 msec timer interval

// TIMER0 interrupt handler
volatile bool time = false;
ISR( TIMER0_COMPA_vect ) {
  static unsigned long count = 0;
  if ( ++count > TIMER0_COUNT ) {
    count = 0;
    time = true;                          // time is set to true every TIMER0_COUNT ms
  }                                       // (time needs to be cleared in the main routine)
}

Step 2: Set Periodic Time Interval

2. Set the time interval. This routine piggybacks itself onto the TIMER0 interrupt, which is set to fire every ~1 msec.

Your "interval" is the number of TIMER0 interrupts to process. Each interval is ~1 msec, so you're really setting how many TIMER0 interrupts to count before activating your interval. IOW, set the variable TIMER0_COUNT to however many milliseconds you want to wait. For example, use 500 for one half of a second. Use 3000 for 3 seconds.

Step 3: Interrupt Initialization

3. Add the "TIMER0 initialization" code to your setup() method. Again, just copy and paste in setup().

// *** TIMER0 initialization ***

  cli();                              // turn off all interrupts
  TIMSK0 = 0;                         // turn off timer0 for lower jitter
  OCR0A  = 0xBB;                      // arbitrary interrupt count
  TIMSK0 |= _BV( OCIE0A );            // piggy back onto interrupt
  sei();                              // turn interrupts back on

Step 4: Where to Add Your Code

4. Add the "time check" code to your loop() method. Copy and paste in loop().

if ( time ) { 
   time = false;
   // do something here
}

The "time = false;" line is important. Without this line the "do something here" line(s) would be executed every time the program executes loop().

Of course, you substitute your own activities in the "do something here" line. Start out with printing some text or flashing the LED.

You're done!