Hey all, I'm trying to incorporate a rotary encoder to my standalone ATMega328 proyect and I'm struggling with said interrupt on the MCU.
I've tried many libraries already, like Encoder, MD_REncoder, Rotary, and a couple more which I've deleted and can't remember their names. These ones I have seem to have pretty clear code and aim to be easy-to-use, but maybe the libraries might not be the problem here.
They all recommend using both interrupt pins for outputs A & B of the encoder (INT1 & INT0, respectively), which I am doing, and I've also tried with A connected to INT1 and B connected to the non-interrupt-pin PD4 (Pin 6). In that configuration I was using INT0 to trigger the switch of the encoder to enter a setup screen on my LCD. In my actual configuration, the switch of the encoder is connected to PD4 and triggers with PCINT20. I'll attach pictures of the schematic and the PCB.
In the end, I couldn't get it to work properly in any of said configurations. The encoder is mechanically OK and functional, though. I've tried many examples that came with the libraries and none worked, only INT0 seems to be responsive to input, but its output isn't coherent since it should work in conjunction with INT1, which is not working. I am doing a simple test now in which the serial monitor simply outputs text when the corresponding INT is triggered. Here's a snippet of my code:
volatile bool intFlag = false;
volatile bool int0 = false;
volatile bool int1 = false;
void setup() {
Wire.begin();
Serial.begin(57600);
PORTD |= (1 << PORTD2) | (1 << PORTD3) | (1 << PORTD4);
// Disable Global Interrupts to set them
cli();
// Enable interrupt for button
PCMSK2 |= (1 << PCINT20);
PCICR |= (1 << PCIE2);
// Enable interrupts INT0 & INT1 on CHANGE
EIMSK |= (1 << INT0) | (1 << INT1);
EICRA |= (1 << ISC00) | (1 << ISC10);
// Reset timer1
TCCR1A = 0;
// Restart timer on compare
TCCR1B &= ~(1 << WGM13);
TCCR1B |= (1 << WGM12);
// Prescaler to 1024
TCCR1B |= (1 << CS12);
TCCR1B &= ~(1 << CS11);
TCCR1B |= (1 << CS10);
// Set compare value
OCR1A = 62500;
// Set interrupt for Timer1 overflow
TIMSK1 = (1 << OCIE1A);
// Enable global interrupts
sei();
}
ISR(TIMER1_COMPA_vect) {
count++;
}
ISR(PCINT2_vect) {
intFlag = true;
}
ISR(INT0_vect) {
int0 = true;
}
ISR(INT1_vect) {
int1 = true;
}
void loop() {
if(int0) {
int0 = false;
Serial.println("INT0");
} else if (int1) {
int1 = false;
Serial.println("INT1");
}
}
(the timer1 part I just left in 'cause it handles interrupts too, just in case)
When I test this, the monitor outputs INT0 whenever I spin the encoder, but never INT1 in any case. Also, the switch works great.
There was only one or two instances in which INT1 would show up on the monitor at the very top, as the first output I guess, but that's it.
At the moment of writing, all encoder-MCU connections have been checked for continuity and nothing seems to be in short.
Thanks to everyone in advance!