attachInterrupt get interrupted pin

I'll try to use one function to handle interrupts (same type) on multiple pins.
My question is, how can I get the currently interrupted pin number?

Sample Code:

int pinEcho1 = 30;
int pinEcho2 = 32;

void handleInterrupt()
{
  Serial.print("handle interrupt on pin: ");
  Serial.println(/* how? */);
}

void setup()
{
  Serial.begin(9600);
  
  attachInterrupt(pinEcho1, handleInterrupt, CHANGE);
  attachInterrupt(pinEcho2, handleInterrupt, CHANGE);
}

void loop()
{
}

Use two handler functions.

+1 for a handler for each interrupt.
Take the serial prints out of the interrupt handler(s). Set a flag in handler and print in loop() when the flag is set.

Sure two functions work, but I'd like to use only one.
Is there no way to determine the pin which is currently interrupted?

P. S. the Serial.print is just for the example

Thanks in advance

The external interrupt flag register, EIFR, has a flag for each external interrupt. You should be able to check that register to see which pin caused the interrupt. Check the data sheet under external interrupts.

The Arduino attachInterrupt mechanism already polls this register to
dispatch to the right function, so just use a function per pin. These functions
can call common code with a pin number if you like - a macro can be used
to define them even :

#define PIN_HANDLER(pin) \
void pin_handler_##pin (void) \
{
  common_handler (pin) ;
}
  • it would be nice if that could put the attachInterrupt calls in setup() but
    alas C macros are lowly beasts with few powers.

Perhaps polling the register yourself is best, on reflection!

It wouldn't be hard to adapt WInterrupts.c to use handler functions
with the signature:

void handler (int pin)

But it would mean creating some port/mask -> Arduino pin reverse
mappings.

Mhh, not working... :frowning:

int pinEcho1 = 30;
int pinEcho2 = 32;

#define PIN_HANDLER(pin) \
void pin_handler_##pin (void) \
{
  handleInterrupt(pin);
}

void handleInterrupt(int pin)
{
  Serial.print("handle interrupt on pin: ");
  Serial.println(pin);
}

void setup()
{
  Serial.begin(9600);
  
  attachInterrupt(pinEcho1, PIN_HANDLER(30), CHANGE);
  attachInterrupt(pinEcho2, PIN_HANDLER(32), CHANGE);
}

void loop()
{
}

Message:

sketch_sep18a.ino:7:18: error: expected constructor, destructor, or type conversion before '(' token
sketch_sep18a.ino:8:1: error: expected declaration before '}' token

Thanks :slight_smile:

Sorry,. forgot all the line continuations on that macro. Fix it...

Do you have any idea?

Thanks :slight_smile:

brightdroid:
Do you have any idea?

Thanks :slight_smile:

Erm, fix the missing line continuations? Just
add
them
to
the
end.

Mhhh, not working :frowning:

int pinEcho1 = 30;
int pinEcho2 = 32;

#define PIN_HANDLER(pin) \
void pin_handler_##pin (void) \
{ \
  handleInterrupt(pin); \
}

void handleInterrupt(int pin)
{
  Serial.print("handle interrupt on pin: ");
  Serial.println(pin);
}

void setup()
{
  Serial.begin(9600);
  
  attachInterrupt(pinEcho1, PIN_HANDLER(30), CHANGE);
  attachInterrupt(pinEcho2, PIN_HANDLER(32), CHANGE);
}

void loop()
{
}

Arduino: 1.5.7 (Linux), Board: "Arduino Due (Programming Port)"

sketch_sep22a.ino: In function 'void setup()':
sketch_sep22a.ino:5:1: error: expected primary-expression before 'void'
sketch_sep22a.ino:20:29: note: in expansion of macro 'PIN_HANDLER'
sketch_sep22a.ino:5:1: error: expected primary-expression before 'void'
sketch_sep22a.ino:21:29: note: in expansion of macro 'PIN_HANDLER'

Any idea? Thanks :slight_smile:

Please actually think about the code - it is a macro for defining functions.
So you call it at top-level to define the functions, it doesn't create function
calls, you have to do that:

const int pinEcho1 = 30;
const int pinEcho2 = 32;

#define PIN_HANDLER(pin) \
void pin_handler_##pin (void) \
{ \
  handleInterrupt(pin); \
}

// Now define all the trampoline functions
PIN_HANDLER (pinEcho1)
PIN_HANDLER (pinEcho2)

void handleInterrupt(int pin)
{
   // Do the right thing here.  Do not call delay() or Serial or anything else using interrupts!
}

void setup()
{
  Serial.begin(9600);
  
  attachInterrupt (pinEcho1, pin_handler_pinEcho1, CHANGE);
  attachInterrupt (pinEcho2, pin_handler_pinEcho2, CHANGE);
}

void loop()
{
}

Mhh, ok understand :frowning:
So is there no way to define it dynamically?
Thanks for your help :slight_smile:

C and C++ don't support closures, so there's no way to define functions
at runtime. Its pretty clunky in fact. And the macro system is horrible beyond
reason.