Interrupts, Can I use multiple ?

Hi All

I have a question about interrupts. Can I use different types of interrupts (RISING, FALLING etc) for two different functions of code to run different scenarios on a single interrupt pin. According to my understanding the programming will choose which function to run depending upon the type of interrupt registered ? Am I thinking right.

No, one pin can have FALLING, RISING, CHANGE (which is both) or LOW.

I believe you can. I have code that interrupts on a rising edge or a falling edge depending on the state of a button pin.
Just define two ISRs.

So I cannot do like this. ?

void setup()
{

attachInterrupt(0, scenario1, CHANGE);
attachInterrupt(0, scenario 2, RISING);
attachInterrupt(0, scenario 3, FALLING);
attachInterrupt(0, scenario 4, LOW
}

void loop()
{

}

void scenario1()
{}
void scenario2()
{}
void scenario3()
{}
void scenario4()
{}

 attachInterrupt(0, scenario1, CHANGE);
 attachInterrupt(0, scenario 2, RISING);
 attachInterrupt(0, scenario 3, FALLING);
 attachInterrupt(0, scenario 4, LOW

Absolutely not. attachInterrupt saves the address of your interrupt handler (one per interrupt, not one per interrupt type per interrupt) like this:

void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) {
  if(interruptNum < EXTERNAL_NUM_INTERRUPTS) {
    intFunc[interruptNum] = userFunc;   // <---------- save your function
 ...

So each time you call attachInterrupt you replace that saved function address.

All you need to do is set up a CHANGE interrupt, and inside the ISR check if the pin is HIGH or LOW.

Hmm, gonna have to review my code to see how I handled rising or falling. It's on a different computer tho.

Hmm, gonna have to review my code to see how I handled rising or falling. It's on a different computer tho.

If you use CHANGE, in the ISR you can determine the current state of the pin to see what the change was - to HIGH or to LOW.

OP: The use of LOW as the interrupt type has very limited applicability. Typically, it is used only when the need to wake the processor from sleep mode.

Okay, so in the nutshell I cannot use a single hardware pin for different types of interrupts as Nick precisely explained.
in order to accomplish the code I written earlier I have to assign each Interrupt type to different hardware pin to accomplish 4 different types of scenarios.

void setup()
{
 
 attachInterrupt(0, scenario1, CHANGE);
 attachInterrupt(1, scenario 2, RISING);
 attachInterrupt(2, scenario 3, FALLING);
 attachInterrupt(3, scenario 4, LOW);
}

void loop()
{
 
}

void scenario1()
{}
void scenario2()
{}
void scenario3()
{}
void scenario4()
{}

Correct me if I am wrong. I am new to programming and learning my way through via forums and study material. :slight_smile:

Correct me if I am wrong.

The need to connect the same source of information to 4 different pins, and use 4 different interrupt handlers is correct.

The assumption that you need 4 different handlers is questionable.

Is there something about detecting whether the CHANGE interrupt happened because the pin went HIGH (a RISING edge happened) or went LOW (a FALLING edge happened) that is difficult? It simply involves looking at the current state of the pin. If it's HIGH, the RISING part of CHANGE happened. If it's LOW, the FALLING part of CHANGE happened.

The three different scenarios are really one with a simple test.

The LOW situation is rarely used, and using it in conjunction with other types of events does not make sense. RISING, FALLING, and CHANGE events aren't registered when the Arduino is asleep, which is the only situation where use of LOW makes sense.

Here's what I did - so I guess I really only have 1 active at a time:

// in pre-setup area:
byte volatile clockEdgeUp = 0; // volatile for the interrupts
byte volatile clockEdgeDown= 0; // volatile for the interrupts


// ISRs for Hardware interrupts
// External Interrupt Request 0  (pin D2)          (INT0_vect)

// ISRs for Rising & Falling interrupts on INT0

// Hardware interrupt 0

void clockFalling() // 
// ISR (INT0_vect) //
{
  clockEdgeDown = 1;

edgeCount = edgeCount + 1; // rolls over if not used

}

void clockRising() // 
// ISR (INT0_vect) //
{
  clockEdgeUp = 1;

edgeCount = edgeCount + 1; // rolls over if not used

}


// in loop area:
if ( ((PIND & 0b0001000) == 0 ) && (cameraRunning == 1) && (PINB & 0b00000100) == 0b00000100 ){  // ARM tripped, not yet running
  cameraRunning = 0;  // Armed
  attachInterrupt(0, clockRising, RISING);
}
if ( ((PIND & 0b0001000) == 0 ) && (cameraRunning == 1) && (PINB & 0b00000100) == 0b00000000 ){  // ARM tripped, not yet running
  cameraRunning = 0;  // Armed
  attachInterrupt(0, clockFalling, FALLING);
}

msdhillon:
Okay, so in the nutshell I cannot use a single hardware pin for different types of interrupts as Nick precisely explained.
in order to accomplish the code I written earlier I have to assign each Interrupt type to different hardware pin to accomplish 4 different types of scenarios.

...

Correct me if I am wrong. I am new to programming and learning my way through via forums and study material. :slight_smile:

You don't have four hardware pins that support external interrupts on the Uno, so this idea won't fly very well. You have pin change interrupts, but in those you have to work out for yourself which way the pin changed.

As more than one of us has explained, a single CHANGE interrupt should suffice for whatever-it-is you are trying to do.

I feel an X-Y problem here.

What are you really trying to achieve?