Interrupt Programming in Arduino

From ESE205 Wiki
Jump to navigation Jump to search

Searching for Stability

Interrupts are useful for making things happen automatically in microcontroller programs. They can be particularly useful for tasks such as reading a rotary encoder or monitoring the state of a button.

Notes to consider when using interrupts:

  • Inside the function, delay() will not work and millis() will not increment, so if your function takes too long, you might skip values. Calling millis() will briefly turn any interrupt running off.
  • Serial data received while the function is running may be lost. Additionally, serial prints (eg. Serial.println(" ");) will increase the time spent in the interrupt function and potentially mess up the timing in the rest of your program. As such, interrupts should not be used for debugging.
  • Interrupt routines have no parameters and should not return anything; they only modify global variables used to pass data between the interrupt routine and the main program. To ensure that these global variables are updated correctly, they should be declared as volatile when initially instantiated.
  • If the sketch uses multiple interrupts, only one can run at a time. For this reason, interrupts should be short so as not to delay the servicing of other interrupts.


Protocol:

  1. Determine which pins on your Arduino are interrupt compatible. On the Arduino Uno, these pins are 2 & 3. The Mega allows interrupts on pins 2, 3, 18, 19, 20, and 21.
  2. Declare any variables you wish to alter in the interrupt as volatile, thus informing the computer that these variables can change at any time and must be reloaded whenever referenced.
  3. Write the body of the interrupt service routine (ISR) above void setup() or below void loop(). An example ISR might look like this:
    1. void updateEncoder() {
    2. //body of the interrupt
    3. //change global variable(s)
    4. }
  4. Attach the interrupt to the correct pins and indicate when the interrupt should be run in void setup(). There are four options for this: RISING, FALLING, LOW, or CHANGE.
  • RISING: triggers when the pin goes from low to high
  • FALLING: triggers when the pin goes from high to low
  • LOW: triggers the interrupt when the pin is low
  • CHANGE: triggers whenever the pin changes value

The attachment statement is formatted like follows: attachInterrupt(digitalPinToInterrupt(pin), ISR, mode);

For the ISR above, an attachment statement might look like this: attachInterrupt(digitalPinToInterrupt(18), updateEncoder, CHANGE);