Help on interference between motor and encoder

Newbie here need some help....

Background info
I use 8 pwm pins from mega to control 4 motors, and then read the speed of the motors via 4 pulse encoders which
connect to 4 external interrupts from mega.

the interrupt call function is very easy, just to count the time of signal changes, then wait a second and reset all the counts,
so I get the pulses per second.

Driver IC is L293, drive voltage is 7.4v, the maga connects to my laptop, which is of course 5v, while L293 to 7.4v, so different power supply!

Here is the problem,
separately, the motors can be controlled perfectly, and the encoders also works fine(tested driven manually)
But when I use them at the same time, it cause some kind of interference, like you only switch on motor1, all the other encoders then have readings, which is really weird...

Now I have all the boards set up and cannot make changes like using relay module, optical isolation,
so anyone have any idea this can be easily solved?

the connection goes like this,
pin 11,10,9,8,7,6,5,4 on mega are used for PWM,
pin 2,3,18,19 are used for external interrupts,
pin 20, 21 are used for I2C compass(not installed yet),
digital pin 22,24,26,28 are used for motor enable.
others includes some pins for analog input and some pins for 4 ultrasonic range finder( not installed yet)

everything have already shared the common ground.

Here is the schematic(sorry, my first eagle sch), I used 2 L293 IC,
there is only one in the schematic, because they are connected the same way.

here is my code:

/*assign pin to motors*/
int val = 0;

const int motorA1 = 4,  motorA2 = 5;
const int motorB1 = 6,  motorB2 = 7;
const int motorC1 = 8,  motorC2 = 9;
const int motorD1 = 10,  motorD2 = 11;

const int motorEA = 22;
const int motorEB = 24;
const int motorEC = 26;
const int motorED = 28;

/*interrupts*/

int c = 0;
volatile int count1, PPS1;
volatile int count2, PPS2;
volatile int count3, PPS3;
volatile int count4, PPS4;

void callback1() { count1++; }
void callback2() { count2++; }
void callback3() { count3++; }
void callback4() { count4++; }

void resetP()
{
  PPS1 = count1;   count1 = 0;
  PPS2 = count2;   count2 = 0;
  PPS3 = count3;   count3 = 0;
  PPS4 = count4;   count4 = 0;
}

void setup()
{    
    pinMode(motorA1, OUTPUT);
    pinMode(motorA2, OUTPUT);
    pinMode(motorB1, OUTPUT);
    pinMode(motorB2, OUTPUT);
    pinMode(motorC1, OUTPUT);
    pinMode(motorC2, OUTPUT);
    pinMode(motorD1, OUTPUT);
    pinMode(motorD2, OUTPUT);
    
    pinMode(motorEA, OUTPUT);
    pinMode(motorEB, OUTPUT);
    pinMode(motorEC, OUTPUT);
    pinMode(motorED, OUTPUT);
    
    pinMode(0, INPUT);//pin0 connects to a potential meter, to change motor speed
    
    Serial.begin(9600);
    
    attachInterrupt(0, callback1, CHANGE);
    attachInterrupt(1, callback2, CHANGE);
    attachInterrupt(4, callback3, CHANGE);
    attachInterrupt(5, callback4, CHANGE);
}

void loop()
{ 
      val = analogRead(0)/4;
  
      digitalWrite(motorEA, HIGH);
      digitalWrite(motorEB, HIGH);
      digitalWrite(motorEC, HIGH);
      digitalWrite(motorED, HIGH);
      
      analogWrite(motorA1, 0);
      analogWrite(motorA2, val);
      
      analogWrite(motorB1, 0);
      analogWrite(motorB2, val);
      
      analogWrite(motorC1, 0);
      analogWrite(motorC2, val);
      
      analogWrite(motorD1, 0);
      analogWrite(motorD2, val);
      
      Serial.print("PPS1=");
      Serial.print(PPS1);
      
      Serial.print("  PPS2=");
      Serial.print(PPS2);
      
      Serial.print("  PPS3 = ");
      Serial.print(PPS3);
      
      Serial.print("  PPS4=");
      Serial.print(PPS4);
      
      Serial.print("          Value=");
      Serial.print(val);
      Serial.print("  Count=");
      Serial.println(c);
      
      c++;
      
      delay(1000);
      resetP();
}

Shouldn't your count variables be declared volatile?

dxw00d:
Shouldn't your count variables be declared volatile?

sorry, I used the wrong sample code, have fixed it already.
Let me add something, when only one motor is running, everything appears fine,
when you measure the voltage between the signal and GND of other encoders, there is nothing unstable,
yet the interrupt still counts, so my guess some high frequency stuff is affecting all
the interrupts. is there a easy way to filter it, or just tell the interrupt to just ignore them
if the frequency is too high?

I'll add the schematic later today.

Are you using the same power supply for the motors and encoders? If so then you need to isolate them, possibly powering the encoders from the Arduino.

Are the motor and encoder wires running in parallel? Are the encoder wires shielded? You may need to shield the encoder wires and ground the shield at ONLY 1 END.

PWM can be rather noisy and because of the on-off-on-off... nature of PWM it can induce a lot of noise in nearby circuits.

kf2qd:
Are you using the same power supply for the motors and encoders? If so then you need to isolate them, possibly powering the encoders from the Arduino.

Are the motor and encoder wires running in parallel? Are the encoder wires shielded? You may need to shield the encoder wires and ground the shield at ONLY 1 END.

PWM can be rather noisy and because of the on-off-on-off... nature of PWM it can induce a lot of noise in nearby circuits.

the answers are: No, No, No
well, how to shield the encoder wires anyway?
I have updated the schematic

UPDATE

I tried to read the value flips from the encoders directly and I found out
that they sometimes flip their value at a very high frequency, for example, 10 microseconds per flip.

So is there a way to tell the interrupts to ignore the flip,
if the time between each flip is larger than 500 microseconds?

in that way, all the false readings are filtered automatically.

Thanks