How to control a two motors and encoders in a single function?

Dear: LMR

Just to let you know I am trying to control all my robots motors and encoders in a single function. It is not going so well obviously since I am starting a forum. This code is supposed to work that function void move has parameters that are leftMotorSpeed, rightMotorSpeed, leftMotorDistance, and rightMotorDistance. Left and Right motor speed control the motor's speed. The other parameters represent the number of ticks the motors are supposed to tick. When they reach a certain amount of ticks the function returns. As should the loop function.

You should know all the motors are moving fine unplugged from the usb. My orginal code to move the motors work fine plugged and unplugged from the USB. The only problem is they control the motors entirely not the encoders as well. The encoders are printing values into computer through the arduino serial monitor but the motors aren't moving on there own. 

Also I am using arduino mega 2560 with cytron 10 amp motor driver. I am also using this encoder library. Thank you.

From: Noah

#include <Encoder.h>
Encoder MtrEnc1(20,21);
const int MtrDir1 = 2;
const int MtrPWM1 = 3;
Encoder MtrEnc2(18,19);
const int MtrDir2 = 4;
const int MtrPWM2 = 5;

void setup() {
 // put your setup code here, to run once:
 Serial.begin(9600);
 pinMode(MtrDir1, OUTPUT);
 pinMode(MtrPWM1, OUTPUT);
 pinMode(MtrDir2, OUTPUT);
 pinMode(MtrPWM2, OUTPUT);
}
void loop() {
 // put your main code here, to run repeatedly:
 Move(255, 0, 1000, 0);
 return;
}
long position1 = -999;
long position2 = -999;
void Move(int LeftMotorSpeed, int RightMotorSpeed, int LeftMotorDistance, int RightMotorDistance)
{
 long EncRead1, EncRead2;
 bool LeftMotorMatched = false;
 bool RightMotorMatched = false;
 EncRead1 = MtrEnc1.read();
 EncRead2 = MtrEnc2.read();
 if (Serial.available())
 {
   Serial.read();
   MtrEnc1.write(0);
   MtrEnc2.write(0);
 }
 if (EncRead1 != position1 || EncRead2 != position2) {
   position1 = EncRead1;
   position2 = EncRead2;
   Serial.print(EncRead1);
   Serial.print(EncRead2);
   Serial.println();
 }
 if (EncRead1 == LeftMotorDistance)
 {
   LeftMotorMatched = true;
 }
 if (EncRead2 == RightMotorDistance)
 {
   RightMotorMatched = true;
 }
 if (LeftMotorDistance > 0 && LeftMotorMatched == false)
 {
   digitalWrite(MtrDir1, LOW);
   analogWrite(MtrPWM1, LeftMotorSpeed);
 }
 if (LeftMotorDistance < 0 && LeftMotorMatched == false)
 {
   digitalWrite(MtrDir1, HIGH);
   analogWrite(MtrPWM1,LeftMotorSpeed);
 }
 if (RightMotorDistance > 0 && RightMotorMatched == false)
 {
   digitalWrite(MtrDir2, LOW);
   analogWrite(MtrPWM2, RightMotorSpeed);
 }
 if (RightMotorDistance < 0 && RightMotorMatched == false)
 {
   digitalWrite(MtrDir2, HIGH);
   analogWrite(MtrPWM2,RightMotorSpeed);
 }
 if (LeftMotorMatched == true && RightMotorMatched == true)
 {
   return;
 }
}

#include

#include <Encoder.h>

Encoder MtrEnc1(20,21);
const int MtrDir1 = 2;
const int MtrPWM1 = 3;
Encoder MtrEnc2(18,19);
const int MtrDir2 = 4;
const int MtrPWM2 = 5;

void setup() {
 // put your setup code here, to run once:
 Serial.begin(9600);
 pinMode(MtrDir1, OUTPUT);
 pinMode(MtrPWM1, OUTPUT);
 pinMode(MtrDir2, OUTPUT);
 pinMode(MtrPWM2, OUTPUT);
}
void loop() {
 // put your main code here, to run repeatedly:
 Move(255, 0, 1000, 0);
 return;
}
long position1 = -999;
long position2 = -999;
void Move(int LeftMotorSpeed, int RightMotorSpeed, int LeftMotorDistance, int RightMotorDistance)
{
 long EncRead1, EncRead2;
 bool LeftMotorMatched = false;
 bool RightMotorMatched = false;
 EncRead1 = MtrEnc1.read();
 EncRead2 = MtrEnc2.read();
 if (Serial.available())
 {
   Serial.read();
   MtrEnc1.write(0);
   MtrEnc2.write(0);
 }
 if (EncRead1 != position1 || EncRead2 != position2) {
   position1 = EncRead1;
   position2 = EncRead2;
   Serial.print(EncRead1);
   Serial.print(EncRead2);
   Serial.println();
 }
 if (EncRead1 == LeftMotorDistance)
 {
   LeftMotorMatched = true;
 }
 if (EncRead2 == RightMotorDistance)
 {
   RightMotorMatched = true;
 }
 if (LeftMotorDistance > 0 && LeftMotorMatched == false)
 {
   digitalWrite(MtrDir1, LOW);
   analogWrite(MtrPWM1, LeftMotorSpeed);
 }
 if (LeftMotorDistance < 0 && LeftMotorMatched == false)
 {
   digitalWrite(MtrDir1, HIGH);
   analogWrite(MtrPWM1,LeftMotorSpeed);
 }
 if (RightMotorDistance > 0 && RightMotorMatched == false)
 {
   digitalWrite(MtrDir2, LOW);
   analogWrite(MtrPWM2, RightMotorSpeed);
 }
 if (RightMotorDistance < 0 && RightMotorMatched == false)
 {
   digitalWrite(MtrDir2, HIGH);
   analogWrite(MtrPWM2,RightMotorSpeed);
 }
 if (LeftMotorMatched == true && RightMotorMatched == true)
 {
   return;
 }
}

Code problems

You are making exact “==” comparisons for final values. What if the value skips over end point? Might want to change to “<=” or “>=” as required. I also like to add extra “(” and “)” inside compound IF statements. Doesn’t change anything except make it clearer to the reader what your intent is.

 

Dear: GGThank you for your

Dear: GG

Thank you for your help but now something weird is happening. I know this is not an electrical issue I checked but now the motors aren’t moving at all. Can I please have some help? Thank you.

From: Noah

void Move(int LeftMotorSpeed, int RightMotorSpeed, int LeftMotorDistance, int RightMotorDistance)
{
 long EncRead1, EncRead2;
 bool LeftMotorMatched = false;
 bool RightMotorMatched = false;
 EncRead1 = MtrEnc1.read();
 EncRead2 = MtrEnc2.read();
 if (Serial.available())
 {
   Serial.read();
   MtrEnc1.write(0);
   MtrEnc2.write(0);
 }
 if ((EncRead1 != position1) || (EncRead2 != position2)) {
   position1 = EncRead1;
   position2 = EncRead2;
 }
 if ((LeftMotorDistance >= 0) && (EncRead1 >= LeftMotorDistance))
 {
   LeftMotorMatched = true;
 }
 else
 {
   LeftMotorMatched = true;
 }
 if ((RightMotorDistance >= 0) && (EncRead2 >= RightMotorDistance))
 {
   RightMotorMatched = true;
 }
 else
 {
   RightMotorMatched = true;
 }
 if ((LeftMotorDistance > 0) && (LeftMotorMatched == false))
 {
   digitalWrite(MtrDir1, LOW);
   analogWrite(MtrPWM1, LeftMotorSpeed);
 }
 if ((LeftMotorDistance < 0) && (LeftMotorMatched == false))
 {
   digitalWrite(MtrDir1, HIGH);
   analogWrite(MtrPWM1,LeftMotorSpeed);
 }
 if ((RightMotorDistance > 0) && (RightMotorMatched == false))
 {
   digitalWrite(MtrDir2, LOW);
   analogWrite(MtrPWM2, RightMotorSpeed);
 }
 if ((RightMotorDistance < 0) && (RightMotorMatched == false))
 {
   digitalWrite(MtrDir2, HIGH);
   analogWrite(MtrPWM2,RightMotorSpeed);
 }
 if ((LeftMotorMatched == true) && (RightMotorMatched == true))
 {
   return;
 }
}

I’m no expert, but…

I think the problem might be the if/else statements are always setting Right/LeftMotorMatched to true no matter what, so the subsequent if statements depending on R/LMotorMatched to be false are being ignored. My guess is the else statements should either be setting these boolean variables to false, or omitted entirely as in the original code.

Ignore this

was meant to be reply to your updated code

Well that might not be the case.

Dear: Smashley

Just to let you know I don’t think that is the case becasue I recently changed the else statements to something else and it is still not working but it is working better than before because the motors are moving and nothing is happening with this method. Now what should be hapenning is that if the encoder left and right are greater than or less than zero and depending if they are greater than or less than encoders are reading the method will put right and left motor match as true as explained below. I replaced the methods with one method displayed below.

From: Noah

 

  if (((LeftMotorDistance >= 0) && (EncRead1 >= LeftMotorDistance)) || ((LeftMotorDistance <= 0) && (EncRead1 <= LeftMotorDistance)))
 {
   LeftMotorMatched = true;
 }
 if (((RightMotorDistance >= 0) && (EncRead2 >= RightMotorDistance) || (RightMotorDistance <= 0) && (EncRead2 <= LeftMotorDistance)))
 {
   RightMotorMatched = true;
 }

Can I have some help?

Dear: LMR

Just to let you know I’ve been doing some more code and this is what I got. Just to let you know I got the code to return for a while but when I began messing with the function loop I think I messed something up. Guys I can’t see what I could possibly be doing wrong can I have some help?

From: Noah

 

#include <Encoder.h>

Encoder LeftEncoder(18,19);
const int MtrDirLeft = 2;
const int MtrPWMLeft = 3;
Encoder RightEncoder(20,21);
const int MtrDirRight = 4;
const int MtrPWMRight = 5;
void setup() {
 // put your setup code here, to run once:
 Serial.begin(9600);
 pinMode(MtrDirLeft, OUTPUT);
 pinMode(MtrPWMLeft, OUTPUT);
 pinMode(MtrDirRight, OUTPUT);
 pinMode(MtrPWMRight, OUTPUT);
 
}

void loop() {
 // put your main code here, to run repeatedly:
 Move(255,0,6000, 0);
 delay(1000);
 Move(255, 0, -6000, 0);
 delay(1000);
 Move(0,255,0, 6000);
 delay(1000);
 Move(0,255, 0, -6000);
 delay(1000);
}

void Move(int LeftMotorSpeed, int RightMotorSpeed, int LeftMotorWantedTicks, int RightMotorWantedTicks)
{
 bool LeftMotorSet = false;
 bool RightMotorSet = false;

 long LeftEncRead, RightEncRead;
 LeftEncRead = LeftEncoder.read();
 RightEncRead = RightEncoder.read();
 if ((RightMotorSet == true) && (LeftMotorSet == true))
 {
   RightEncoder.write(0);
   LeftEncoder.write(0);
   return;
 }
 else
 {
   if (LeftMotorSet == true)
   {
     LeftMotorSpeed = 0;
     LeftMotorWantedTicks = 0;
   }
   else
   {
     if (((LeftMotorWantedTicks < 0) && ((LeftMotorWantedTicks >= LeftEncRead))) || ((LeftMotorWantedTicks > 0) && (LeftMotorWantedTicks <= LeftEncRead)) || (LeftMotorWantedTicks == 0) || (LeftMotorSpeed == 0))
     {
       LeftMotorSet = true;
     }
     if (LeftMotorWantedTicks > 0)
     {
       digitalWrite(MtrDirLeft, HIGH);
       analogWrite(MtrPWMLeft, LeftMotorSpeed);
     }
     else
     {
       digitalWrite(MtrDirLeft, LOW);
       analogWrite(MtrPWMLeft, LeftMotorSpeed);
     }
   }
   if (RightMotorSet == true)
   {
     RightMotorSpeed = 0;
     RightMotorWantedTicks = 0;
   }
   else
   {
     if (((RightMotorWantedTicks < 0) && (RightMotorWantedTicks >= RightEncRead)) || ((RightMotorWantedTicks > 0) && (RightMotorWantedTicks <= RightEncRead)) || (RightMotorWantedTicks == 0) || (RightMotorSpeed == 0))
     {
       RightMotorSet == true;
     }
     if (RightMotorWantedTicks > 0)
     {
       digitalWrite(MtrDirRight, HIGH);
       analogWrite(MtrPWMRight, RightMotorSpeed);
     }
     else
     {
       digitalWrite(MtrDirRight, LOW);
       analogWrite(MtrPWMRight, RightMotorSpeed);
     }
   }
 }
}