Hi, I'm doing a project with a rotary encoder and I'm experimenting a little with interrupts in order to make it run better. I trying to make an interrupt-timer reenable the "encoder turn"-interrupt after a certain time has passed.
- I'm using an Arduino Mega for my project.
I have tested the disabling of the encoder-interrupt (works).
I have tested the timer interrupt (works).
The issue is that my encoder-interrupt runs after being enabled again, if I turn the rotary encoder while its interrupt is disabled. I figured the interrupt flag for the encoder-interrupt can still be 'set' even though I disabled the interrupt. The encoder-interrupt is an external interrupt on the Mega's 18th pin (RISING Edge). I disable the interrupt by clearing the bit in the EIMSK-byte.
bitClear(EIMSK, INT3); //Disable Encoder
Just before the timer-interrupt enables the encoder again, I clear what I think is the right flag -so it won't trigger the encoder-interrupt again when it gets reenabled.
ISR (TIMER4_COMPA_vect)
{
bitClear(EIFR, 4); //Resets INTF4 (External Interrupt Flag 4)
bitSet(EIMSK, INT3); //Enable Encoder
}
But the interrupt still triggers. Have I misunderstood something here, or am I simply just clearing a wrong flag?
Here's the whole code - sorry if the syntax Isn't 100% right
//Encoder
#define ENCODER_A 18 //Encoder's A output
#define ENCODER_B 46 //Encoder's B output
volatile int encoderValue;
volatile bool encoderTurned; //True if encoder position was changed
void setup()
{
// PinModes
pinMode(ENCODER_A, INPUT);
pinMode(ENCODER_B, INPUT);
//EncoderTimerINTSetup (4seconds)
cli();
TCCR4A = 0; //clear Timer/Counter Control Register 4A
TCCR4B = 0; //clear Timer/Counter Control Register 4B
TCCR4B |= B00001101; //CTC mode with 1024 prescaler
TCNT4 = 0; //clear counter
OCR4A = 62499;//(4s with 1024 prescaler)
TIMSK4 |= B00000010; //Enable timer compare interrupt
sei();
//ExternalINTSetup
attachInterrupt(digitalPinToInterrupt(ENCODER_A), EncoderTurnISR, RISING);
Serial.begin(9600);
function();
}
void loop()
{
// put your main code here, to run repeatedly:
}
void function()
{
while (1)
{
if (encoderTurned)
{
encoderTurned = false;
Serial.println("Now");
}
}
}
void EncoderTurnISR()
{
encoderTurned = true;
if (digitalRead(ENCODER_A) != digitalRead(ENCODER_B)) //Clockwise turn
{
encoderValue++;
}
else //Clockwise
{
encoderValue--;
}
//Disable Encoder... until timer activates it again
bitClear(EIMSK, INT3);
}
ISR (TIMER4_COMPA_vect)
{
bitClear(EIFR, 4); //Resets INTF4 (External Interrupt Flag 4) ... Issue? Clears before enable, but EncoderTurnISR() still runs for some reason
bitSet(EIMSK, INT3); //Enable Encoder
}
- The Serial monitor writes "Now" twice if the encoder is: turned, disabled, turned, enabled.
Hope someone can help