2

I wrote some code that handles rotary encoder using an interrupt, but I would like to get which pin generated the interrupt, so I'll be able to handle many interrupts in a single method.

Something like:

void ISREncoders()
{
  int pin = GetCurentInterruptPin(); // <============= this
  int dataPin = dataPins[pin];
  int data = DigitalRead(dataPin);
  if(data == HIGH)
  {
    encoders[pin] += 1;
  }
  else
  {
    encoders[pin] -= 1;
  }
}

Is it anyhow possible?


As mentioned in the answer this is not possible. Still, after peeking some encoder libraries that use interrupt found out that they do the following:

The Encoder class contains several static ISR methods hard coded.

As you create new objects it increments an internal counter and sets proper ISR method on the interrupt.

This is for sure the best solution available, but this is not at all scalable, for instance if you have an imaginary board with thousand pins that handle thousands encoders you will have to hard code each ISR method.

8
  • A common data, clock endoder. (when you rotate it generates a clock, and data contains rotation direction information). The objective is to use a single method to handle multiple encoders, I would like to know wich pin generated the interrupt.
    – user67439
    Jul 5, 2020 at 19:34
  • What if user rotates two encoders at the same time, and inspite of possibility, two clock pins are in HIGH state?
    – user67439
    Jul 5, 2020 at 19:35
  • keep a list of the states of the interrupt pins ... compare list at an interrupt .... anyway, your question is a general programming question ... there is no Arduino component in your question
    – jsotola
    Jul 5, 2020 at 19:43
  • Polling clock pin is OK, this is not the problem. The question is how to acquire which pin generated the interrupt, so, using interrupts I don't need to constantly poll clock pins. Posted here because it is an arduino (like) issue, and haven't found any information on this on Google. If anyone closes it I would understand. Thanks for your time and effort.
    – user67439
    Jul 5, 2020 at 19:46
  • two clock pins are in HIGH state ... there is a flaw in your thinking (not related to your question though) ... your thinking should be two clock pins transition from LOW to HIGH state (or vice versa)
    – jsotola
    Jul 5, 2020 at 19:46

1 Answer 1

2

It is not possible to know which interrupt caused the ISR to be called. The INTFx flag gets cleared when the interrupt routine is called, so you lose that information (which is a shame).

The closest you could do is to have a separate ISR for each pin which just calls the common routine with a parameter to say which ISR it was executed via. That will add some extra latency though as it has to make an extra function call, but that can be somewhat mitigated by having the common function marked as always_inline, which means the compiler will duplicate it and place it within the code where it's being called from. This reduces latency but increases code size.

static ISREncoder(uint8_t pin) __attribute__ ((always_inline)) {
    // Do stuff with the `pin` variable
}

void ISR0() { ISREncoder(2); }
void ISR1() { ISREncoder(3); }
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.