Use 2 incremental rotary encoders

Hello to all.
I want to create a program to manage 2 incremental rotary encoders and a stepper motor, but now I have left the stepper motor aside because I want to solve this problem first.

I am using an arduino Mega, even if I used the Uno before, but since I thought the program was not working due to the few Interrupt pins, I switched to the Mega (photos of the Arduino Uno pins: https: //i.stack .imgur.com / dVkQU.jpg and the Arduino Mega pin photos: https://arduino-projekte.info/wp-content/uploads/2017/03/mega_pinout.png)
I bought the two encoders I'm using on Amazon: https://www.amazon.it/Wisamic-incrementale-tensione-alificazione-millimetri/dp/B015GYY7XU/ref=sr_1_6?__mk_it_IT=ÅMÅ % C5% BD% C3% 95% C3% 91 & dchild = 1 & keywords = encoder & qid = 1605898632 & sr = 8-6

volatile long temp, counter = 0; //This variable will increase or decrease depending on the rotation of encoder
    
void setup() {
  Serial.begin (9600);

  pinMode(2, INPUT_PULLUP); // internal pullup input pin 2 
  
  pinMode(3, INPUT_PULLUP); // internalเป็น pullup input pin 3
   //Setting up interrupt
  //A rising pulse from encodenren activated ai0(). AttachInterrupt 0 is DigitalPin nr 2 on moust Arduino.
  attachInterrupt(0, ai0, RISING);
   
  //B rising pulse from encodenren activated ai1(). AttachInterrupt 1 is DigitalPin nr 3 on moust Arduino.
  attachInterrupt(1, ai1, RISING);
  }
   
  void loop() {
  // Send the value of counter
  if( counter != temp ){
  Serial.println (counter);
  temp = counter;
  }
  }
   
  void ai0() {
  // ai0 is activated if DigitalPin nr 2 is going from LOW to HIGH
  // Check pin 3 to determine the direction
  if(digitalRead(3)==LOW) {
  counter++;
  }else{
  counter--;
  }
  }
   
  void ai1() {
  // ai0 is activated if DigitalPin nr 3 is going from LOW to HIGH
  // Check with pin 2 to determine the direction
  if(digitalRead(2)==LOW) {
  counter--;
  }else{
  counter++;
  }
  }

This is the code I had copied and pasted from a guy who used an Arduino Uno and the same encoder to see the counter increase and decrease as I turned the encoder shaft.
And so far everything is fine.
Then I realized that on the Arduino Uno I couldn't put another encoder, if I'm wrong PLEASE tell me, and so I switched to the Mega.

#define PinBiancoEncoder1 20
#define PinVerdeEncoder1 21
#define PinBiancoEncoder2 18
#define PinVerdeEncoder2 19
volatile long temp, counter = 0; //This variable will increase or decrease depending on the rotation of encoder
volatile long temp1, counter1 = 0; //This variable will increase or decrease depending on the rotation of encoder
    
void setup() {
  Serial.begin (9600);

  pinMode(PinVerdeEncoder1, INPUT_PULLUP); 
  
  pinMode(PinBiancoEncoder1, INPUT_PULLUP); 

  pinMode(PinVerdeEncoder2, INPUT_PULLUP); 
  
  pinMode(PinBiancoEncoder2, INPUT_PULLUP); 
   //Setting up interrupt
  //A rising pulse from encodenren activated ai0(). AttachInterrupt 0 is DigitalPin nr 2 on moust Arduino.
  attachInterrupt(0, ai0, RISING);
   
  //B rising pulse from encodenren activated ai1(). AttachInterrupt 1 is DigitalPin nr 3 on moust Arduino.
  attachInterrupt(1, ai1, RISING);

   //Setting up interrupt
  //A rising pulse from encodenren activated ai0(). AttachInterrupt 0 is DigitalPin nr 2 on moust Arduino.
  attachInterrupt(4, ai2, RISING);
   
  //B rising pulse from encodenren activated ai1(). AttachInterrupt 1 is DigitalPin nr 3 on moust Arduino.
  attachInterrupt(5, ai3, RISING);
  }
   
  void loop() {
  // Send the value of counter
  if( counter != temp ){
  Serial.println (counter);
  temp = counter;
  }
  if( counter1 != temp1 ){
  Serial.println (counter1);
  temp1 = counter1;
  }
  }
   
  void ai0() {
  // ai0 is activated if DigitalPin nr 2 is going from LOW to HIGH
  // Check pin 3 to determine the direction
  if(digitalRead(PinBiancoEncoder1)==LOW) {
  counter++;
  }else{
  counter--;
  }
  }
   
  void ai1() {
  // ai0 is activated if DigitalPin nr 3 is going from LOW to HIGH
  // Check with pin 2 to determine the direction
  if(digitalRead(PinVerdeEncoder1)==LOW) {
  counter--;
  }else{
  counter++;
  }
  }

  void ai2() {
  // ai0 is activated if DigitalPin nr 2 is going from LOW to HIGH
  // Check pin 3 to determine the direction
  if(digitalRead(PinBiancoEncoder2)==LOW) {
  counter1++;
  }else{
  counter1--;
  }
  }
   
  void ai3() {
  // ai0 is activated if DigitalPin nr 3 is going from LOW to HIGH
  // Check with pin 2 to determine the direction
  if(digitalRead(PinVerdeEncoder2)==LOW) {
  counter1--;
  }else{
  counter1++;
  }
  }

In this code I tried to put the second encoder as well, but nothing.
The code you see now is the final result of dozens and dozens of changes I made to the code, from the point of view of the pins, both the encoder pins and the attachInterrupt pins.
I looked on the internet about dozens of sites about attachInterrupt and how to program more than one encoder on the same program, BUT NOTHING.

I can't get mad guys and I don't even want to think about how many hours I spent trying and making mistakes, without finding a solution.

I repeat, I have 2 incremental rotary encoders and an Arduino Mega / Uno, you decide which one to use, and my goal is to have and read on the Serial Monitor the values, COUNTER, of each of the two encoders.
OR, instead of reading the values of each of the two encoders, it would be fine for me if the counter is the same, so that if one encoder increases and the other decreases there is the difference between the values of the two encoders.

I ask you to give me a hand if possible, I can not get out of this situation.

THANK YOU SO MUCH GUYS for your attention

Just curious if you get a different outcome by initializing the interrupts with:

    //Setting up interrupts
    attachInterrupt(digitalPinToInterrupt(PinVerdeEncoder1), ai0, RISING);    
    attachInterrupt(digitalPinToInterrupt(PinBiancoEncoder1), ai1, RISING);

    attachInterrupt(digitalPinToInterrupt(PinVerdeEncoder2), ai2, RISING);  
    attachInterrupt(digitalPinToInterrupt(PinBiancoEncoder2), ai3, RISING);

I think you can use two encoders on the Uno. You really only need one interrupt for each encoder. Connect one encoder to pins 2 and 4, and the other encoder to pins 3 and 5. Your interrupts are on pins 2 and 3, which are now connected to different encoders. When pin 2 interrupts, you read pin 4 to get the direction. When pin 3 interrupts, you read pin 5. So your ISRs would look like this:

 void ai0() {
  // ai0 is activated if DigitalPin nr 2 is going from LOW to HIGH
  // Check pin 4 to determine the direction
  if(digitalRead(4)==LOW) {
  counter++;
  }else{
  counter--;
  }
  }
   
  void ai1() {
  // ai0 is activated if DigitalPin nr 3 is going from LOW to HIGH
  // Check with pin 5 to determine the direction
  if(digitalRead(5)==LOW) {
  counter--;
  }else{
  counter++;
  }
  }

You will get half as many ticks per revolution because only one pin of each encoder is generating an interrupt.

Blackfin:
Sono solo curioso se ottieni un risultato diverso inizializzando gli interrupt con:

    //Setting up interrupts

attachInterrupt(digitalPinToInterrupt(PinVerdeEncoder1), ai0, RISING);    
   attachInterrupt(digitalPinToInterrupt(PinBiancoEncoder1), ai1, RISING);

attachInterrupt(digitalPinToInterrupt(PinVerdeEncoder2), ai2, RISING);  
   attachInterrupt(digitalPinToInterrupt(PinBiancoEncoder2), ai3, RISING);

No it doesn't work. Thanks anyway

ShermanP:
I think you can use two encoders on the Uno. You really only need one interrupt for each encoder. Connect one encoder to pins 2 and 4, and the other encoder to pins 3 and 5. Your interrupts are on pins 2 and 3, which are now connected to different encoders. When pin 2 interrupts, you read pin 4 to get the direction. When pin 3 interrupts, you read pin 5. So your ISRs would look like this:

 void ai0() {

// ai0 is activated if DigitalPin nr 2 is going from LOW to HIGH
 // Check pin 4 to determine the direction
 if(digitalRead(4)==LOW) {
 counter++;
 }else{
 counter–;
 }
 }
 
 void ai1() {
 // ai0 is activated if DigitalPin nr 3 is going from LOW to HIGH
 // Check with pin 5 to determine the direction
 if(digitalRead(5)==LOW) {
 counter–;
 }else{
 counter++;
 }
 }




You will get half as many ticks per revolution because only one pin of each encoder is generating an interrupt.

I LOVE YOU!
Thank you very much, you solved this huge problem of mine
Good day everyone

crevatinfrancesco:
I LOVE YOU!
Thank you very much, you solved this huge problem of mine
Good day everyone

LOL. Well, for future reference, you can also use the pin change interrupts for rotary encoders. So you could have as many as five encoders on a Uno - one for each of the two"external" interrupts, and one for each of the three ports. Anyway, I'm glad you've worked it out without having to resort to a Mega.

Hi,
What is the project that needs two encoders?

Thanks... Tom.. :slight_smile:

ShermanP:
LOL. Well, for future reference, you can also use the pin change interrupts for rotary encoders. So you could have as many as five encoders on a Uno - one for each of the two"external" interrupts, and one for each of the three ports. Anyway, I'm glad you've worked it out without having to resort to a Mega.

Wich ports are you talking about?

Inside the 328P, the GPIO pins are organized as three 8-bit ports. Port B includes D8 through D13 (PB0 - PB5) plus XTAL1 and XTAL2 (PB6 & PB7), which aren't brought out on the Arduino boards.

Port C has A0 through A5 (PC0 - PC5). PC6 & PC7 are A6 and A7, but I think they are analog inputs only, with no digital function.

Port D has the Rx and Tx pins,which are PD0 & PD1, plus D2 through D7 (PD2 - PD7).

You can access these ports directly instead of using digitalRead and digitalWrite. And they can be used for external interrupts (despite what you see about Unos only having the two external interrupt pins). But only pin-change is avilable, not rising or falling. You can enable interrupts on specific pins, but there's only one interrupt flag bit for each port, so if you've enabled more than one pin, you don't know which one interrupted. Also, I don't believe the Arduino IDE lets you "attach" interrupts to these pins, so you have to modify the registers directly. So using these interrupts is not very user-friendly.

Anyway, the datasheet has complete information on all of this.

Thank for your reply! :slight_smile:

You seems to be one who knows a lot, can you help me on my recent post? I'm stucked there and no one helps me. :frowning:

I have a problem with TRS female jack where I want to plug in a TRS or TS jack on the needs of the moment
Here's the link:

Sorry, but I don't think I can contribute anything on that.