Optical Sensor (LM393) as a wheel encoder not reading correct ticks

Problem Statement:

I am trying to build a robo car with 4 wheels that has moves forward a predefined amount setup in the function using two encoder disks and two opto-interrupter.

To debug I setup a serial print statement for each counter to read the ISR counter values of each wheel. The distance travelled by the car is always half of that specified in the move forward function and the counter is about half too.

When I send a command to move forward 40 cm, I get a counter reading of of 80 steps/ticks. Also the ticks and right ticks dont match despite putting while loop for it. How do I fix this problem and ensure my car alignment issues get resolved due to difference in power send to each motor or battery drainage.

Setup

  1. Arduino Mega 2560 Board.

  2. Robot Car:
    DIY 4WD Smart Electronic Robot Car Chassis w/ Speed Encoder Arduino Starter Kit | eBay

  3. H-Bridge Hookup:

    I am using one L298N H Bridge to drive all four wheels with each Motor side driving two wheels per side. Motor A output on the H-Bridge is connected to the right wheels while Motor B to the left ones. I am running the H-Bridge on a standard 9V energizer battery with the jumper pin taken out as I am feeding the logic circuit with one of the arduino's 5 V output. GND is connected to the arduino's GND.

Arduino Mega 2560 Hookup:

H-Bridge Connection:

MOTOR 1 (Right Motor)

enA=Pin 9
in1=Pin 8
in2=Pin 7

Motor 2 (Left Motor)

enB= Pin 4
in3=Pin 6
in4=5

LM398 Photointerrupters as Wheel Encoders:

LM398 Photointerrupters are used with the provided 20 slot encoder disks on the two front wheels only. I didnt see the need to record rotations on the rear wheels.

LM398 Connection:

Pin 21 and Pin 20 on the Mega which are capable of handling interrupts as per the official website.

5V power is coming from the arduino with a small breadboard for both photointerrupters using some type of bridge (not sure what its called (the LM393 chip is on it) but it has two potentiometers on top of them connected to each opto interrupter)

Wheel Diameter:

Around 66.10mm

Code Used:

///VARIABLE SETUP FOR ARDUINO I/O AND SENSORS

////////MOTION CONTROL VARIABLES///////

//Motor 1 which is the Right MOTOR

int enA=9;
int in1=8;
int in2=7;

//Motor 2 which is the Left MOTOR

int enB=4;
int in3=6;
int in4=5;

////////ENCODER VARIABLES////////
//Constants for Interrupt Pins (Used for the Wheel Encoders)

const byte MOTOR1=21; //Motor 1 Interrupt Pin
const byte MOTOR2=20; //Motor 2 Interrupt Pin

//Float for number of state changes in a revolution for the encoder disk

float enc_calib=40; //20 slots per disk hence 40 state changes

//Constant for Wheel Diameter

const float wheeldiameter=66.10; // In mm

//Integers to pulse counter (Used for the Wheel Encoders)

volatile int counter1=0;
volatile int counter2=0;

//////INTERRUPT SERVICE ROUTINE FOR ENCODERS//////

//Motor 1 pulse count
void ISR_count1(){

counter1++;
Serial.println("ISR_COUNTER1=");
Serial.println(counter1);

}

//Motor 2 pulse count

void ISR_count2(){
counter2++;
Serial.println("ISR_COUNTER2=");
Serial.println(counter2);

}

// Function to convert cm to Steps

int CMtoSteps(float cm) {

int stepcount;
float circumference= (wheeldiameter*3.14)/10; //Calculate Circumference in Cm
float cm_step=circumference/enc_calib; // Cm per step

float f_stepcount= (cm/cm_step); //Convert cm/step to cm as a floating point
stepcount= (int) f_stepcount; //Convert float to integer....not rounded off.
return stepcount;

}

//FUNCTION TO MOVE FORWARD

void MoveForward(int steps,int mspeed){

counter1=0; //Reset Counter 1
counter2=0; //Reset Counter 2

//Set Motor 1 to move forward
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);

//Set Motor 2 to move forward
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);

while (steps> counter1 && steps> counter2){

if (steps>counter1) {
  analogWrite(enA,mspeed);
}else{
  analogWrite(enA,0);
}

if (steps>counter2) {

  analogWrite(enB,mspeed);

}else{
  analogWrite(enB,0);
}

}
//Stop Motors when distance reached

analogWrite(enA,0);
analogWrite(enB,0);

counter1=0;
counter2=0;
}

void setup()

{
Serial.begin(115200);

//Set Motor control pins to output

pinMode(enA,OUTPUT);
pinMode(in1,OUTPUT);
pinMode(in2,OUTPUT);
pinMode(in3,OUTPUT);
pinMode(in4,OUTPUT);
pinMode(enB,OUTPUT);

//Encoder Timer

attachInterrupt(digitalPinToInterrupt (MOTOR1), ISR_count1,CHANGE); //Increase counter 1 when speed sensor pin changes state
attachInterrupt(digitalPinToInterrupt (MOTOR2), ISR_count2,CHANGE); //Increase counter 2 when speed sensor pin changes state

// ///MOTION COMMAND//////
//
MoveForward(CMtoSteps(20.77),200);

}

void loop()

{

}

Thanks!

Words describing a circuit just doesn’t work.


Show us a good schematic of your circuit.
Show us a good image of your ‘actual’ wiring.
Give links to components.

Sure. I m sorry this is my first time posting. Thanks for the feedback.

So here are the pictures and circuit diagrams. I am mechanical engineer trying to learn some electronics and programming so I am not so great at circuit diagrams. I hope you entertain my enthusiasm though. I cannot find the model for the opto-interrupter coupler which has the two potentiometers. Rest of the parts are as per the links below:

  1. Arduino Mega

  2. L298n H Bridge: L298N Motor Driver Module Pinout, Datasheet, Features & Specs

  3. Opto-Interrupter : I honestly cannot find the specs or any model number or make. but it could be this one as it has four leads. I know it has a LM393 comparator on the OPTO coupler which is what both interrupters are connected to.
    CNY36 datasheet - Phototransistor Optical Interrupter Switch

  4. Wheels, and motors: Same as mentioned in my post.

Images