I everybody
I have used interrupts with arduino mini and nano on small projects where I have modified some old soldering stations. I put a rotary encoder and OLED or LED display as appropriate. I must say that the result was excellent. I am very satisfied. I specify that I used a Matthias Hertel library, RoraryEncoder.h
Now I want to change an old code for a submersible pump control unit. It uses MEGA2560 Display st7735 and three buttons as data entry (without interrupts). I would like to replace the buttons with a rotary encoder (with interrupt).
First of all I tried with the above library. Which, however, was preset. With the MEGA you have to change the interrupt parameters. I took the MEGA manual and tried unsuccessfully to rewrite these commands (in stars)
// ROTARY ENCODER
#include <RotaryEncoder.h>
RotaryEncoder encoder(A10, A12);
ISR(**PCINT2_vect**) {
encoder.tick(); // just call tick() to check the state.
}
#define MIN 1
#define MAX 254
// ASSIGN DIGITAL PIN
byte pin_mode = A8; // int5 Rotary encoder MODE
void setup() {
pinMode (pin_mode, INPUT_PULLUP);
....
// ROTARY - modify the next 2 lines if using other pins than A2 and A3
PCICR |= (1 << **PCIE2**); // This enables Pin Change Interrupt 0 will trigger
//if any enabled PCINT25:16 pin toggles.
PCMSK2 |= (1 << **PCINT18**) | (1 << **PCINT20**); // This enables the interrupt for pin A10, A12.
encoder.setPosition(Tset); // starts with value.
It does’t work. This could be a first question: where am I failing?
Then I tried the classic “attachInterrupt” method
I got as the simplest code as possible, and it works. At least it increments and decrements a simple variable, but the encoder is anything but responsive, as it is in the other projects with the Hertel library, where the response to rotation is immediate and quite precise.
I can’t explain it to myself: when I turn the encoder, it does nothing for several clicks, then suddenly it starts to work, then it locks again, if I turn slightly faster it seems to go better, but often for half a turn it does nothing, as if it were not reading .
I thought it was the 1.8 "ST7735 TFT slowing down, so I tried the Serial.print, but it doesn’t change anything. It’s not the display.
the code is this, trivial
const int PinA = 21; //Rot.Enc A
const int PinB = 19; // Rot. Enc B
const int PinSW = 3; // button
// Keep track of last rotary value
int preX = 25;
// Updated by the ISR (Interrupt Service Routine)
volatile int X = 60;
void setup() {
Serial.begin(9600);
// Rotary pulses are INPUTs
pinMode(PinA, INPUT_PULLUP);
pinMode(PinB, INPUT_PULLUP);
pinMode(PinSW, INPUT_PULLUP);
// Attach the routine to service the interrupts
attachInterrupt(digitalPinToInterrupt(PinA), isrUP, FALLING);
attachInterrupt(digitalPinToInterrupt(PinB), isrDN, FALLING);
attachInterrupt(digitalPinToInterrupt(PinSW), isrSW, LOW);
}
void loop() {
// If the current rotary switch position has changed then update everything
if (X != preX) {
Serial.println(X);
// Keep track of this new value
preX = X;
}
}
// ------------------------------------------------------------------
// INTERRUPT INTERRUPT INTERRUPT INTERRUPT INTERRUPT
// ------------------------------------------------------------------
void isrUP() {
X++;
X = min(100, max(0, X));
}
void isrDN() {
X-- ;
X = min(100, max(0, X));
}
void isrSW() {
X = 50 ;
}
How is it possible that with the NANO and the MINI the encoder works without problems, while with the Mega I can’t get decent operation?