Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents

Interrupts

Image Added

Image Added

Image Added

Image Added


Interrupt Code Sample

Sample Code to to toggle an LED when a button triggers an interrupt.

Code Block
languagecpp
//Define LED and switch connections
const byte ledPin = 13;
const byte buttonPin = 2;

// Boolean to represent toggle state
volatile bool toggleState = false;

void checkSwitch@) {

  //Check status of switch
  // Toggle LED if button pressed

  if (digitalRead(buttonPin) == LOW) {
    // Switch was pressed
    // Change state of toggle 
    toggleState = !toggleState;

    // Indicate state on LED
    digitalWrite(ledPin, toggleState);
  }

}
void setup() {

  //Set LED pin as output
  pinMode(ledPin, OUTPUT) ;
  // Set switch pin as INPUT with pullup

  pinMode (buttonPin, INPUT_PULLUP) ;
  //Setup Serial Monitor
  Serial. begin (9600);

  // Attach Interrupt to Interrupt Service Routine
  attachInterrupt(digitalPinToInterrupt(buttonPin),checkSwitch, FALLING);
}

void loop() {

  // 5-second time delay
  Serial.println("Delay Started");
  delay (5000);
  Serial.println("Delay Finished");
  Serial.println(".......
}


Pin Change Interrupts

Arduino microcontrollers have a limited number of pins that are hardware interrupt compatible. 

To get around this limitation, we can use a pin change interrupts on almost all pins.


Image Added


Image AddedImage Added

Image AddedImage Added


Enable Port B

Image Added

Each port has a mask to enable particular pins.

Image Added


Activate Pin D12 on Port B

Image Added


Interrupt Service Routines are pre-defined for each port

Image Added


Define the ISR

Image Added


We must rest the interrupt by writing a "1" to the corresponding bit of the PCIFR register. This is not required when using an ISR.

Image Added


Note about Pin Change Interrupts

Image Added


Circuit for Example Pin Change Interrupt 

Image Added

Sample Code

Code Block
languagecpp
// LEDs and switchs
const byte ledPin1 = 11;
const byte ledPin2 = 13;
const byte buttonPin1= 2;
const byte buttonPin2 = 7;

// Booleans for input states
volatile bool D2_state = LOW;
volatile bool D7_state = LOW;

void setup() {

  // Set LEDs as output
  pinMode(ledPin1, OUTPUT) ;
  pinMode(ledPin2, OUTPUT) ;

  // Set Switches as input with pullup
  pinMode(buttonPin1, INPUT_PULLUP) ;
  pinMode(buttonPin2, INPUT_PULLUP) ;

  // Enable PCIE2 Bit3 = 1 (Port D)|
  PCICR |= 800000100;

  //Enable interrupt on Pin D2 & D7 - Select PCINT18 & PCINT23 (Pin D2 & D7)
  PCMSK2 |= B10000100;
}

void loop(){
 // No code in Loop
}

ISR (PCINT2_vect)
{
  // Port D Interrupt occured

  // Check if this was D2
  if (digitalRead(buttonPin1) == LOW) {

    //Pin D2 triggered the ISR on a Falling pulse
    D2_state = !D2_state;

    //Set LED 1 to state of D2 state boolean
    digitalWrite(ledPin1, D2_state);
  }

  // Check if this was D7
  if (digitalRead(buttonPin2) == LOW) {

    //Pin D7 triggered the ISR on a Falling pulse
    D7_state = !D7_state;
    //Set LED 2 to state of D7_state boolean
    digitalWrite(ledPin2, D7_state);
  }

}


Timer Interrupts

Do not use a timer that is used by another process.


Arduino Uno Timers

Image Added

Image Added

Image Added

Image Added

Image AddedImage AddedImage Added


Image AddedImage Added


Image Added

Replace x with 0,1, or 2 representing the timer #.


Code Sample 

Code Block
//define the LED pin
#define ledPin 13

//Define timer compare match register value
int timer1_compare_match;

ISR(TIMER1_COMPA_vect){
//Interrupt Service Routine for Compare Mode

  //Preload timer with compare match value
  TCNT1 = timer_compare_match;

  //Write opposite value to LED
  digitalWrite(ledPin, digitalRead(ledPin) ^ 1);
}

void setup(){

  //Set LED as output
  pinMode(ledPin, OUTPUT);
  
  //Disable all interrupts
  noInterrupts();

  //Initialize Timer1
  TCCR1A = 0;
  TCCR1B = 0;
  
  //Set timerl_compare_match to the correct compare match register value
  // 256 prescaler & 31246 compare match = 2Hz
  timer_compare_match = 31249;  
  
  //Preload timer with compare match value
  TCNT1 = timer1_compare_match;

  // Preload timer with compare match value
  TCNT1 = timer1_compare_match;

  // Set prescaler to 256 - set CS12 bit in TCCR1B
  TCCR1B = (1 < CS12) ;

  // Enable timer interrupt for compare mode
  TIMSK1 |= (1 < OCIE1A);

  // Enable all interrupts
  interrupts ();

}

void loop() {
  //nothing
}
















Analyzing the Following Code

Code Block
static uint8_t saveTCCR1A, saveTCCR1B;

static inline void capture_init(void)
{
	saveTCCR1A = TCCR1A;
	saveTCCR1B = TCCR1B;

    //reset TimerCounter 1
	TCCR1B = 0;         
    TCCR1A = 0;

	TCNT1 = 0;
	TIFR1 = (1<<ICF1) | (1<<TOV1);
	TIMSK1 = (1<<ICIE1) | (1<<TOIE1);
}
static inline void capture_start(void)
{
	TCCR1B = (1<<ICNC1) | (1<<ICES1) | (1<<CS10);
}
static inline uint16_t capture_read(void)
{
	return ICR1;
}
static inline uint8_t capture_overflow(void)
{
	return TIFR1 & (1<<TOV1);
}
static inline void capture_overflow_reset(void)
{
	TIFR1 = (1<<TOV1);
}
static inline void capture_shutdown(void)
{
	TCCR1B = 0;
	TIMSK1 = 0;
	TCCR1A = saveTCCR1A;
	TCCR1B = saveTCCR1B;
}


#define TIMER_OVERFLOW_VECTOR  TIMER1_OVF_vect
#define TIMER_CAPTURE_VECTOR   TIMER1_CAPT_vect 



References

ReferenceURL
Understanding Arduino Interrupts | Hardware, Pin Change & Timer Interrupts

Video: https://www.youtube.com/watch?v=wIcC8-g9Lnw

Article with code: https://dronebotworkshop.com/interrupts

More articles and tutorials: https://dronebotworkshop.com

Join the conversation on the forum: https://forum.dronebotworkshop.com

Electronic Basics #30: Microcontroller (Arduino) Timershttps://www.youtube.com/watch?v=IdL0_ZJ7V2s
Configuring & Handling ESP32 GPIO Interrupts In Arduino IDE