Two Metal Gearmotors 37Dx57L mm 12V with 64 CPR Encoders (No End Cap) running with Arduino Mega or Mega 2560

// Pin Definitions for Motor 1 (Encoder Motor 1)
#define ENA1 9
#define IN1_1 7
#define IN1_2 8
#define ENCODER1_A 2
#define ENCODER1_B 3

// Pin Definitions for Motor 2 (Encoder Motor 2)
#define ENA2 10
#define IN2_1 4
#define IN2_2 5
#define ENCODER2_A 6
#define ENCODER2_B 11

// Pin Definitions for Ultrasonic Sensor
#define TRIG_PIN 12
#define ECHO_PIN 13
#define OBSTACLE_DISTANCE 60
#define STOP_DISTANCE 20

// Encoder tracking
volatile long encoderPosition1 = 0;
volatile long encoderPosition2 = 0;

int motorSpeed1 = 150;
int motorSpeed2 = 150;

// Counter for obstacle detections
int obstacleCount = 0;

void setup() {
// Motor and encoder pin setups
pinMode(ENA1, OUTPUT);
pinMode(IN1_1, OUTPUT);
pinMode(IN1_2, OUTPUT);
pinMode(ENCODER1_A, INPUT_PULLUP);
pinMode(ENCODER1_B, INPUT_PULLUP);

pinMode(ENA2, OUTPUT);
pinMode(IN2_1, OUTPUT);
pinMode(IN2_2, OUTPUT);
pinMode(ENCODER2_A, INPUT_PULLUP);
pinMode(ENCODER2_B, INPUT_PULLUP);

// Ultrasonic sensor setup
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);

// Attach encoder interrupts
attachInterrupt(digitalPinToInterrupt(ENCODER1_A), readEncoder1, CHANGE);
attachInterrupt(digitalPinToInterrupt(ENCODER2_A), readEncoder2, CHANGE);

Serial.begin(9600);
}

void loop() {
long distance = measureDistance();

if (distance > 0 && distance <= STOP_DISTANCE) {
stopMotors();
Serial.println("Obstacle detected within stop distance. Motors stopped.");
delay(500);
return;
}

if (distance > STOP_DISTANCE && distance <= OBSTACLE_DISTANCE) {
obstacleCount++;
if (obstacleCount % 2 != 0) { // Odd obstacle count: turn right
Serial.println("Obstacle detected! Turning right...");
turnRight(170); // Perform right turn
} else { // Even obstacle count: turn left
Serial.println("Obstacle detected! Turning left...");
turnLeft(170); // Perform left turn
}
delay(500);
} else {
runMotorsForward();
}
}

long measureDistance() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);

long duration = pulseIn(ECHO_PIN, HIGH);
return duration * 0.034 / 2; // Convert time to distance in cm
}

void turnRight(int angle) {
long targetTicks = encoderPosition1 + calculateEncoderTicks(angle);
unsigned long startTime = millis();
while (encoderPosition1 < targetTicks && millis() - startTime < 3000) { // 3s timeout
digitalWrite(IN1_1, HIGH);
digitalWrite(IN1_2, LOW);
analogWrite(ENA1, motorSpeed1);

digitalWrite(IN2_1, LOW);
digitalWrite(IN2_2, HIGH);
analogWrite(ENA2, motorSpeed2);

}
stopMotors();
}

void turnLeft(int angle) {
long targetTicks = encoderPosition2 + calculateEncoderTicks(angle);
unsigned long startTime = millis();
while (encoderPosition2 < targetTicks && millis() - startTime < 3000) { // 3s timeout
digitalWrite(IN1_1, LOW);
digitalWrite(IN1_2, HIGH);
analogWrite(ENA1, motorSpeed1);

digitalWrite(IN2_1, HIGH);
digitalWrite(IN2_2, LOW);
analogWrite(ENA2, motorSpeed2);

}
stopMotors();
}

void runMotorsForward() {
digitalWrite(IN1_1, HIGH);
digitalWrite(IN1_2, LOW);
analogWrite(ENA1, motorSpeed1);

digitalWrite(IN2_1, HIGH);
digitalWrite(IN2_2, LOW);
analogWrite(ENA2, motorSpeed2);

Serial.println("No obstacle detected. Motors running forward.");
}

void stopMotors() {
digitalWrite(IN1_1, LOW);
digitalWrite(IN1_2, LOW);
analogWrite(ENA1, 0);

digitalWrite(IN2_1, LOW);
digitalWrite(IN2_2, LOW);
analogWrite(ENA2, 0);
}

long calculateEncoderTicks(int angle) {
int ticksPerRevolution = 20; // Update based on your encoder
int wheelDegreesPerRevolution = 360;
return (ticksPerRevolution * angle) / wheelDegreesPerRevolution;
}

void readEncoder1() {
if (digitalRead(ENCODER1_A) == digitalRead(ENCODER1_B)) {
encoderPosition1++;
} else {
encoderPosition1--;
}
}

void readEncoder2() {
if (digitalRead(ENCODER2_A) == digitalRead(ENCODER2_B)) {
encoderPosition2++;
} else {
encoderPosition2--;
}
}
I ran the above code on an Arduino Mega or Mega 2560 board, but when the obstacle is detected by the ultrasonic sensor for the first time, the motors make a 170-degree left turn. However, when the obstacle is detected for the second time, the motors make a turn of more than 170 degrees.

Hi, @souvik89

Please post your code in code tags.

What has PLC IDE to do with your code?

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:

I moved your topic to an appropriate forum category @souvik89

In the future, please take some time to pick the forum category that best suits the subject of your topic. There is an "About the _____ category" topic at the top of each category that explains its purpose.

This is an important part of responsible forum usage, as explained in the "How to get the best out of this forum" guide. The guide contains a lot of other useful information. Please read it.

Thanks in advance for your cooperation.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.