Incremental Encoder counting problem with arduino mega on a car wheel

Hi all!

This is my first topic here, but I have really big hopes about it. First of all I would like to apologize for my english (mostly for my grammar), I will try to be understandable.

I am working for a theatre designer company and our team's project is to make a car which can move decorative elements. Basically it is a big RC car.

We are done with the car, we use RC communication (drone controller and transceiver):
Taranis Q X7 RC controller

The car has 6 wheels, 2 driven and 4 holder. We use 2 brushless DC motors to drive the wheels. We have 2 motor drivers:
Cytron MDS40B motor drivers

We have 4 ultrasonic sensors and 2 incremental encoders:
HC-SR04
Incremental Photoelectric Rotary Encoder

The "brain" of the car is an arduino mega (I don't think that I should link it :slight_smile: ).

The basic features are working good. So the telemetry is okay (we use PinChangeInt library for reading the channels), the car is moving where we want it. The extended feature would be that we want to teach positions to it. That is why we have the encoders on both driven wheels. We use interrupt pins for the encoders (18-21) and they count perfectly when we drive them with our hands (the motors are turned off and we rotate the wheels manually). The problem is when we turn on the motor and the encoders counts always down regardless from the direction of rotation.

I have found topics if the encoder counts only one direction. The difference here is that we count in both directions but always counts down and the bigger problem is that it counts randomly. So for the same distances we got back different numbers on the encoder. Again when we turn it manually it works perfectly.

First we thought there could be interference between the motor and the encoders but when the encoders were off the wheels we could drive the motors and rotate manually the encoders with perfect counting. We use shaded cables everywhere for everything.

The code we use for the encoders:

const byte enc2B = 21;  //A 2-es enkóder B jele
const byte enc2A = 20;  //A 2-es enkóder A jele
const byte enc1A = 19;  //Az 1-es enkóder A jele
const byte enc1B = 18;  //Az 1-es enkóder B jele

volatile long counter1 = 0;  //Számláló az 1. enkóder jeléhez, a volatile adja meg azt, hogy gyorsan, nagy mértékben változik
volatile long counter2 = 0;  //Számláló a 2. enkóder jeléhez, a long adja meg azt, hogy elegendő körülfordulást mérhessünk (+-2 milliárd)

void setup() {
  pinMode(enc1A,INPUT);  //Az enc1A pin bemenet
  pinMode(enc1B,INPUT);  //Az enc1B pin bemenet
  pinMode(enc2A,INPUT);  //Az enc2A pin bemenet
  pinMode(enc2B,INPUT);  //Az enc2B pin bemenet

  digitalWrite(enc1A,HIGH);  //Bekapcsoljuk a felhúzó ellenállásokat
  digitalWrite(enc1B,HIGH);
  digitalWrite(enc2A,HIGH);
  digitalWrite(enc2B,HIGH);

  attachInterrupt(5, ai0, RISING);  //Interruptot állitunk be a megfelelő pinekre, 0-s interrupt pin a 2-es digitális pin, 1-es a 3-as,... 
  attachInterrupt(4, ai1, RISING);  //További részletek: https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/
  attachInterrupt(2, ai2, RISING);  //Interruptra meghívjuk az ai0, ai1,... függvényeket és lefuttatjuk
  attachInterrupt(3, ai3, RISING);  //Interrupt akkor van, ha a pin 0-ról 1-re vált (RISING)

  Serial.begin(115200);  //Soros kommunikáció elindítása, 115200-as Baud rate
}

void loop() {

  Serial.print(counter1);
  Serial.print(" ");
  Serial.println(counter2);
}

  //1A
void ai0(){                     //ai0-t az 5-ös interrupt pinhez csatoltuk, ami a 18-as digitális pin, tehát ha a 18-as pin vált 0-ról 1-re, akkor:
  if(digitalRead(enc1A)==LOW){  //Nézzük meg az enc1A pint, amely a 19-es, hogy alacsony-e, ha igen
    counter1++;                 //Növeljünk egyet az 1. enkóder számlálóján
  }
  else{          //Ha nem alacsony, akkor másik irányba forgunk
    counter1--;  //Csökkentsen egyet az 1. enkóder számlálóján
  }
}

  //1B
void ai1(){                     //ai1-et a 4-es interrupt pinhez csatoltuk, ami a 19-es digitális pin, tehát ha a 19-es pin vált 0-ról 1-re, akkor:
  if(digitalRead(enc1B)==LOW){  //Nézzük meg az enc1B pint, amely a 18as, hogy alacsony-e, ha igen
    counter1--;                 //Csökkentsünk egyet az 1. enkóder számlálóján
  }
  else{          //Ha nem alacsony, akkor másik irányba forgunk
    counter1++;  //Növeljen egyet az 1. enkóder számlálóján
  }
}

  //2A
void ai2(){                     //ai2-t az 1-es interrupt pinhez csatoltuk, ami a 3-as digitális pin, tehát ha a 3-as pin vált 0-ról 1-re, akkor:
  if(digitalRead(enc2A)==LOW){  //Nézzük emg az enc2A pint, amely a 2-es, hogy alacsony-e, ha igen
    counter2++;                 //Növeljen egyet a 2. enkóder számlálóján
  }
  else{          //Ha nem alacsony, akkor másik irányba forgunk
    counter2--;  //Csökkentsen egyet a 2. enkóder számlálóján
  }
}

  //2B
void ai3(){                     //ai3-at a 0-s interrupt pinhez csatoltuk, ami a 2-es digitális pin, tehát ha a 2-es pin vált 0-ról 1-re, akkor:
  if(digitalRead(enc2B)==LOW){  //Nézzük meg az enc2B pint, amely a 2-es, hogy alacsony-e, ha igen
    counter2--;                 //Csökkentsünk egyet a 2. enkóder számlálóján
  }
  else{          //Ha nem alacsony, akkor másik irányba forgunk
    counter2++;  //Növeljen egyet a 2. enkóder számlálóján
  }
}

It is not the full code, I know but I can't post it because of industrial secrecy, I am sorry :frowning: .

Hi again!

Sorry, I have post my problem to the wrong topic and I don't know now how to delete it :(. I will post it to project guidance where I should have post it at the first time.