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.

VE7JRO
2,51519 gold badges27 silver badges29 bronze badges
asked Jul 5, 2020 at 19:30
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. Commented 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? Commented 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 Commented 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. Commented 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) Commented 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); }
answered Jul 5, 2020 at 19:51
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.