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.
1 Answer 1
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); }
two clock pins are in HIGH state
... there is a flaw in your thinking (not related to your question though) ... your thinking should betwo clock pins transition from LOW to HIGH state (or vice versa)