Need Help with an Uno and 2 linear actuators

I am trying to get 2 actuators to move and the same time/speed/length. If they are not at the same stroke I want them to equalize(one of the actuator expand/contract to the other). I am close but it is turning the motor off and on too quickly in order to achieve this goal. I want to smooth this out and get it to be more precise. here is the code. And an early thanks for those who help

//Variables
int Act0Up = 2;                          // Sends signal to Coil side of relay to move actuator 0 UP
int Act1Up = 3;                          // Sends signal to Coil side of relay to move actuator 1 UP
int Act0Down = 4;                        // Sends signal to Coil Side of relay to move actuator 0 DOWN
int Act1Down = 5;                        // Sends signal to Coil Side of relay to move actuator 1 DOWN
int KeyUp = 6;                           // Reads signal from keylock switch. If high it will be used to move the actuators UP
int KeyDown = 7;                         // Reads signal from keylock switch. If high it will be used to move the actuators DOWN
int ActPot0 = A0;                        // Reads signal from potentiometer in actuator 0 (left side when looking at back of trailer).
int ActPot1 = A1;                        // Reads signal from potentiometer in actuator 1 (right side when looking at back of trailer).
int ActPot0Val;                          // Variable to save the value of the potentiaometer from ActPot0
int ActPot1Val;                          // Variable to save the value of the potentiaometer from ActPot1
int ActPot0MapVal;                       // Variable to store the new map value of the potentiameter
int ActPot1MapVal;                       // Variable to store the new map value of the potentiameter
int LimitUp;                             // Limit to be set to stop the actuators from extending to far
int LimitDown;                           // Limit to be set to stop the actuators from retracting to far
int i=0;

void setup() {

  pinMode(Act0Up, OUTPUT);
  pinMode(Act1Up, OUTPUT);
  pinMode(Act0Down, OUTPUT);
  pinMode(Act1Down, OUTPUT);
  pinMode(KeyUp, INPUT);
  pinMode(KeyDown, INPUT);
  digitalWrite(Act0Up, LOW);
  digitalWrite(Act1Up, LOW);
  digitalWrite(Act0Down, LOW);
  digitalWrite(Act1Down, LOW);
  digitalWrite(KeyUp, LOW);
  digitalWrite(KeyDown, LOW);
  ReadPots();
  Serial.begin(9600);
  delay(250);
}

void loop() {

  Serial.print("i value : ");
  Serial.println(i);
  ReadPots();
  if(digitalRead(KeyUp) == HIGH){
  Up();
  }
  else {
  digitalWrite(Act1Up, LOW); 
  digitalWrite(Act0Up, LOW);
  }
  if(digitalRead(KeyDown) == HIGH){
  Down();
  }
  else{
  digitalWrite(Act1Down, LOW); 
  digitalWrite(Act0Down, LOW);
  }
}

void ReadPots() {
  for (i = 1; i < 4; ++i){
    ActPot0Val = ActPot0Val + analogRead(ActPot0);
    ActPot1Val = ActPot1Val + analogRead(ActPot1);
  }
  ActPot0Val = ActPot0Val / 4;
  ActPot1Val = ActPot1Val / 4;
  Serial.print("Actuator0 AVG: ");
  Serial.println(ActPot0Val);            // Prints to the Serial Monitor the value of the POT 0
  Serial.print("Actuator1 AVG: ");
  Serial.println(ActPot1Val);            // Prints to the Serial Monitor the value of the POT 1
  delay(25);
  ActPot0MapVal = map(ActPot0Val, 77, 990, 0, 255);
  ActPot1MapVal = map(ActPot1Val, 80, 994, 0, 255);  
  Serial.print("Actuator0 MV: ");
  Serial.println(ActPot0MapVal);            // Prints to the Serial Monitor the mapped value of the POT 0
  Serial.print("Actuator1 MV: ");
  Serial.println(ActPot1MapVal);            // Prints to the Serial Monitor the mapped value of the POT 1
  delay(25);
}

void Up(){      // If the Up keylock switch is activated then it will move the actuators Up
    
    if (ActPot0MapVal != ActPot1MapVal){
    EqualizeUP();
    }
    else if(ActPot0MapVal == ActPot1MapVal){
    digitalWrite(Act1Down, LOW); 
    digitalWrite(Act0Down, LOW);
    digitalWrite(Act1Up, HIGH); 
    digitalWrite(Act0Up, HIGH);   
    delay(5);
   }
}
void Down(){        // If the Down keylock switch is activated then it will move the actuators Down
    if (ActPot0MapVal != ActPot1MapVal){
    EqualizeDOWN();
    }
    else if(ActPot0MapVal == ActPot1MapVal){
    digitalWrite(Act1Up, LOW); 
    digitalWrite(Act0Up, LOW); 
    digitalWrite(Act1Down, HIGH); 
    digitalWrite(Act0Down, HIGH);  
    delay(5);
    }
    }
void EqualizeUP(){
    if(ActPot0MapVal > ActPot1MapVal){
    digitalWrite(Act0Up, HIGH);
    digitalWrite(Act1Up, LOW);
    delay(5);
    }
    if(ActPot0MapVal < ActPot1MapVal){
    digitalWrite(Act0Up, LOW);
    digitalWrite(Act1Up, HIGH);
    delay(5);
    }
}

void EqualizeDOWN(){
    if(ActPot0MapVal > ActPot1MapVal){
    digitalWrite(Act1Down, HIGH);
    digitalWrite(Act0Down, LOW);
    delay(5);
    }
    if(ActPot0MapVal < ActPot1MapVal){
    digitalWrite(Act1Down, LOW);
    digitalWrite(Act0Down, HIGH);
    delay(5);
    }
}

Firstly, don’t you need to reset ActPot0Val and ActPot1Val to zero at the start of ReadPots()?

Secondly, what do you want to happen when the two actuators are in different positions? Is it right that you only want this equalisation to occur when a movement is commanded? Do you want them to both continue to move but at different speeds, so that they eventually get in sync? Or, do you want the one that is furthest ahead (in the current direction of movement) to wait until the other one catches up, before it moves?

I imagine that the reset is needed. Didn't think of that. Thanks for the reminder.

As for the second question, preferably if the two actuators are not at the same position, I want when the actuators are extending, the one that is lower to extend to the position of the one that is higher and the one that is higher to wait until it gets there. When the actuators are contracting, the one that is higher to contract to the position of the one that is lower and the one that is lower to wait until it gets there.

Currently the get out of sync by about 1.5 inches. With the current program the equalize part of the program causes the actuator to stop and start again fairly quickly and I would prefer not cause this kind of stress on the motor and they are going to be used to lift something heavy.

Also I was curious was I on the right track?

I think you’re on broadly the right lines.

In Down(), you have:

if (ActPot0MapVal != ActPot1MapVal){
}
else if(ActPot0MapVal == ActPot1MapVal){
}
}

The two values are equal or not equal. If the first check shows that they are equal, there is no need for a further if to test whether they are still equal.
You should get rid of the else if and just use:

if (ActPot0MapVal != ActPot1MapVal)
{
}
else
{
}

Similarly for the other places where you do this.

I suggest you get rid of the delays in EqualizeDOWN(). They are not needed.

For clarity, I suggest you extract out the digitalWrite calls into separate functions to move each actuator up, down, and stop.

I suggest you move the pin numbers for each actuator into arrays of length 2 (one entry per actuator). Then you can use common functions to move and stop each actuator eg:

void MoveUp(int actuator)
{
  digitalWrite(downPin[actuator], LOW);
  digitalWrite(upPin[actuator], HIGH);
}

You need to have some dead band on your equalisation. This is probably why it is behaving so badly at the moment - the two actuators are never in exactly the same position, and so one is always stopping to wait for the other. You’d do this by code like this:

const int TOLERANCE = 10; // adjust this once you know how close is 'close enough' for your purposes
boolean Equal()
{
  return abs(ActPot1MapVal - ActPot0MapVal) < TOLERANCE);
}

void Down()
{
  if(Equal())
  {
    MoveDown(0);
    MoveDown(1);
  }
  else
  {
    EqualizeDOWN();
  }
}

Here is what I came up with and it is working great.

Is there a way to keep the motor from shutting off completely? I am thinking that slowing it down until the other catches up would be better ?

Again thank you for the help

//Variables
int Act0Up = 2;                          // Sends signal to Coil side of relay to move actuator 0 UP
int Act1Up = 3;                          // Sends signal to Coil side of relay to move actuator 1 UP
int Act0Down = 4;                        // Sends signal to Coil Side of relay to move actuator 0 DOWN
int Act1Down = 5;                        // Sends signal to Coil Side of relay to move actuator 1 DOWN
int KeyUp = 6;                           // Reads signal from keylock switch. If high it will be used to move the actuators UP
int KeyDown = 7;                         // Reads signal from keylock switch. If high it will be used to move the actuators DOWN
int ActPot0 = A0;                        // Reads signal from potentiometer in actuator 0 (left side when looking at back of trailer).
int ActPot1 = A1;                        // Reads signal from potentiometer in actuator 1 (right side when looking at back of trailer).
int ActPot0Val;                          // Variable to save the value of the potentiaometer from ActPot0
int ActPot1Val;                          // Variable to save the value of the potentiaometer from ActPot1
int ActPot0MapVal;                       // Variable to store the new map value of the potentiameter
int ActPot1MapVal;                       // Variable to store the new map value of the potentiameter
int LimitUp;                             // Limit to be set to stop the actuators from extending to far
int LimitDown;                           // Limit to be set to stop the actuators from retracting to far
int i=0;
const int buffer = 9;                    // Buffer for the actuators to equal out 

void setup() {

  pinMode(Act0Up, OUTPUT);
  pinMode(Act1Up, OUTPUT);
  pinMode(Act0Down, OUTPUT);
  pinMode(Act1Down, OUTPUT);
  pinMode(KeyUp, INPUT);
  pinMode(KeyDown, INPUT);
  digitalWrite(Act0Up, LOW);
  digitalWrite(Act1Up, LOW);
  digitalWrite(Act0Down, LOW);
  digitalWrite(Act1Down, LOW);
  digitalWrite(KeyUp, LOW);
  digitalWrite(KeyDown, LOW);
  ReadPots();
  Serial.begin(9600);
  delay(250);
}

void loop() {

  Serial.print("i value : ");
  Serial.println(i);
  ReadPots();
  if(digitalRead(KeyUp) == HIGH){
  Up();
  }
  else {
  digitalWrite(Act1Up, LOW); 
  digitalWrite(Act0Up, LOW);
  }
  if(digitalRead(KeyDown) == HIGH){
  Down();
  }
  else{
  digitalWrite(Act1Down, LOW); 
  digitalWrite(Act0Down, LOW);
  }
}

void ReadPots() {
  ActPot0Val = 0;
  ActPot1Val = 0;
  for (i = 1; i < 4; ++i){
  ActPot0Val = ActPot0Val + analogRead(ActPot0);
  ActPot1Val = ActPot1Val + analogRead(ActPot1);
  }
  ActPot0Val = ActPot0Val / 4;
  ActPot1Val = ActPot1Val / 4;
  Serial.print("Actuator0 AVG: ");
  Serial.println(ActPot0Val);            // Prints to the Serial Monitor the value of the POT 0
  Serial.print("Actuator1 AVG: ");
  Serial.println(ActPot1Val);            // Prints to the Serial Monitor the value of the POT 1
  delay(25);
  ActPot0MapVal = map(ActPot0Val, 58, 743, 0, 608);
  ActPot1MapVal = map(ActPot1Val, 59, 746, 0, 608);  
  Serial.print("Actuator0 MV: ");
  Serial.println(ActPot0MapVal);            // Prints to the Serial Monitor the mapped value of the POT 0
  Serial.print("Actuator1 MV: ");
  Serial.println(ActPot1MapVal);            // Prints to the Serial Monitor the mapped value of the POT 1
  delay(25);
}

void Up(){      // If the Up keylock switch is activated then it will move the actuators Up
    
    if (EqualLR()&&EqualRL()){
    digitalWrite(Act1Down, LOW); 
    digitalWrite(Act0Down, LOW);
    digitalWrite(Act1Up, HIGH); 
    digitalWrite(Act0Up, HIGH); 
    }
    else {
    EqualizeUP();  
    delay(5);
   }
}
void Down(){        // If the Down keylock switch is activated then it will move the actuators Down
    if (EqualLR()&&EqualRL()){
    digitalWrite(Act1Up, LOW); 
    digitalWrite(Act0Up, LOW); 
    digitalWrite(Act1Down, HIGH); 
    digitalWrite(Act0Down, HIGH); 
    
    }
    else {
    EqualizeDOWN();
    delay(5);  
  }
}
void EqualizeUP(){
    if(ActPot0MapVal > ActPot1MapVal){
    digitalWrite(Act0Up, HIGH);
    digitalWrite(Act1Up, LOW);
    }
    if(ActPot0MapVal < ActPot1MapVal){
    digitalWrite(Act0Up, LOW);
    digitalWrite(Act1Up, HIGH);
    }
}

void EqualizeDOWN(){
    if(ActPot0MapVal > ActPot1MapVal){
    digitalWrite(Act1Down, HIGH);
    digitalWrite(Act0Down, LOW);
    }
    if(ActPot0MapVal < ActPot1MapVal){
    digitalWrite(Act1Down, LOW);
    digitalWrite(Act0Down, HIGH);
    }
}

boolean EqualLR(){
  return abs((ActPot1MapVal - ActPot0MapVal) < buffer);
}
boolean EqualRL(){
  return abs((ActPot0MapVal - ActPot1MapVal) < buffer);
}

Depends on the capabilities of your motor controller. It looks as if you have got one output pin for each terminal on the motor and just send them high and low to turn the motor on in the right direction. In that case you could use PWM to control the speed. For simplicity, you would apply PWM to the ‘high’ pin (i.e. according to the current direction) so that a higher analog write value corresponds to a greater speed. This would be much nicer in operation than switching the motors off completely. If you’re just trying to control drift between the motors, it would probably be sufficient to run the slower motor at (say) 90% of full speed and the faster motor at 100% speed. It doesn’t seem that you need to be able to make big corrections, only ensure that they always drift back into sync. That would just require changing the code in EqualizeUP() and EqualizeDOWN() which currently uses digitalWrite(LOW) to turn one of the motors off, to an analogWrite(200) or similar to run the motor at slightly less than full speed.

If you were trying to cope with bigger differences I’d suggest making the speed difference proportional to the amount of error you’re trying to correct, but I think that’s overkill for this application. If you wanted to do that as an academic exercise then you’d calculate the difference between ActPot0MapVal and ActPot1MapVal and then calculate the speed of the slower motor from that.

Peter you have been such a big help, I thought I would bother you once more. I purchased this motor driver http://www.pololu.com/catalog/product/2502 in order to do what we spoke of in previous posts. So while this motor driver comes with it own library and I was able to synchronize the actuators without issue, I need to have the Arduino figure out what speed the actuators need to be at instead of them being defined. The code below is as far as I got in order to make that work but it is a little buggy and I was wondering if you had any advice. I feel like I am on the right track again but I am missing something.

#include <DualVNH5019MotorShield.h>

DualVNH5019MotorShield md;

//Variables
float Act1 = 0;                            // Motor 1 speed value
float Act2 = 0;                            // Motor 2 speed value
int KeyUp = 3;                           // Reads signal from keylock switch. If high it will be used to move the actuators UP
int KeyDown = 5;                         // Reads signal from keylock switch. If high it will be used to move the actuators DOWN
int ActPot1 = A4;                        // Reads signal from potentiometer in actuator 0 (left side when looking at back of trailer).
int ActPot2 = A5;                        // Reads signal from potentiometer in actuator 1 (right side when looking at back of trailer).
int ActPot1Val;                          // Variable to save the value of the potentiaometer from ActPot1
int ActPot2Val;                          // Variable to save the value of the potentiaometer from ActPot2
int ActPot1MapVal;                       // Variable to store the new map value of the potentiameter
int ActPot2MapVal;                       // Variable to store the new map value of the potentiameter
int Limit1Up;                            // Limit to be set to stop the actuators from extending to far
int Limit1Down;                          // Limit to be set to stop the actuators from retracting to far
int Limit2Up;                            // Limit to be set to stop the actuators from extending to far
int Limit2Down;                          // Limit to be set to stop the actuators from retracting to far
int i=0;
const int buffer = 7;                    // Buffer for the actuators to equal out. This the most the actuators can be off from each other.

void setup() {

  pinMode(KeyUp, INPUT);
  pinMode(KeyDown, INPUT);
  digitalWrite(KeyUp, LOW);
  digitalWrite(KeyDown, LOW);
  ReadPots();
  Serial.begin(115200);
  delay(50);
  md.init();
}

void loop() {

  Serial.print("i value : ");
  Serial.println(i);
  Serial.print("Act1 value : ");
  Serial.println(Act1);
  Serial.print("Act2 value : ");
  Serial.println(Act2);
  ReadPots();

  if(digitalRead(KeyUp) == LOW && digitalRead(KeyDown) == LOW){
    md.setSpeeds(0, 0);
    md.setBrakes(400, 400); 
  }

  if(digitalRead(KeyUp) == HIGH){
    Up();
  }

  if(digitalRead(KeyDown) == HIGH){
    Down();
  }

}

void ReadPots() {
  ActPot1Val = 0;
  ActPot2Val = 0;
  for (i = 1; i < 4; ++i){
    ActPot1Val = ActPot1Val + analogRead(ActPot1);
    ActPot2Val = ActPot2Val + analogRead(ActPot2);
  }
  ActPot1Val = ActPot1Val / 4;
  ActPot2Val = ActPot2Val / 4;
  Serial.print("Actuator0 AVG: ");
  Serial.println(ActPot1Val);               // Prints to the Serial Monitor the value of the POT 1
  Serial.print("Actuator1 AVG: ");
  Serial.println(ActPot2Val);               // Prints to the Serial Monitor the value of the POT 2
  delay(50);
  ActPot1MapVal = map(ActPot1Val, 58, 743, 0, 608);
  ActPot2MapVal = map(ActPot2Val, 59, 746, 0, 608);  
  Serial.print("Actuator0 MV: ");
  Serial.println(ActPot1MapVal);            // Prints to the Serial Monitor the mapped value of the POT 1
  Serial.print("Actuator1 MV: ");
  Serial.println(ActPot2MapVal);            // Prints to the Serial Monitor the mapped value of the POT 2
  delay(50);
}

void Up(){         // If the Up keylock switch is activated then it will move the actuators Up
  ReadPots();
  EqualizeUP();
  md.setM1Speed(Act1);
  md.setM2Speed(Act2);

}
void Down(){         // If the Down keylock switch is activated then it will move the actuators Down
  ReadPots();
  EqualizeDOWN();
  md.setM1Speed(Act1);
  md.setM2Speed(Act2);
}

void EqualizeUP(){
  if(ActPot1MapVal > ActPot2MapVal){
    Act1 = float(ActPot1MapVal / ActPot2MapVal) * 400;
    Act2 = 400;
  }
  else{
    Act2 = float(ActPot2MapVal / ActPot1MapVal) * 400;
    Act1 = 400;
  }
  int(Act1);
  int(Act2);
}

void EqualizeDOWN(){
    if(ActPot1MapVal > ActPot2MapVal){
    Act1 = float(ActPot1MapVal / ActPot2MapVal) * -400;
    Act2 = -400;
  }
  else{
    Act2 = float(ActPot2MapVal / ActPot1MapVal) * -400;
    Act1 = -400;
  } 
  int(Act1);
  int(Act2);
}

These statements don't achieve anything:

  int(Act1);
  int(Act2);

It looks as if the code will slow down the 'higher' actuator by an amount that is proportional to the ratio of the two actuator positions. In other words, as the actuators get lower, the 'equalizing' algorithm gets more aggressive. Is that what you wanted? I don't see anything that would stop it working - what are the symptoms of these bugs you're chasing?

The issue I am getting is that the ratio is not coming out as a decimal but as a whole number. When divide ActPot1MapVal by ActPot2MapVal it needs to be between 0 - 1. In example, 0.92. But I am not getting that. Also I took out the

int(Act1);
int(Act2);

yesterday

void EqualizeUP(){
 Act1=0;
 Act2=0;
  if(ActPot1MapVal > ActPot2MapVal){
    Act1 = float(ActPot1MapVal / ActPot2MapVal) * 400;
    Act2 = 400;
  }
  else{
    Act2 = float(ActPot2MapVal / ActPot1MapVal) * 400;
    Act1 = 400;
  }
 }

Since you're calculating the ratio using float arithmetic, you need to cast the individual terms to floats first - otherwise, it'll do the calculation using integers and cast the result to a float, which defeats the point of using floats.

Act1 = (float(ActPot1MapVal) / float(ActPot2MapVal)) * 400.0;

Thank you for the help.
Here is where I am at now. I took a metal rod and put it between the 2 actuators and taped a level to it, so I can see if it is staying level. But the problem is that the it does not stay level but it is close. It seems that the actuators can not keep up with program.
Any suggestions?

Maybe the position sensors attached to the two rams are not producing identical results when the rams are level? You could find out by disconnecting the electrical drives to the actuators and printing out the measured positions when they are set to the same level.

Make sense but that's why I used the code below I thought it would fix that issue.

 ActPot1MapVal = map(ActPot1Val, 58, 743, 0, 608);
  ActPot2MapVal = map(ActPot2Val, 59, 746, 0, 608);

When the rams are level, are ActPot1MapVal and ActPot2MapVal equal?

They are because I mapped the lowest value for each to be 0. Actually I changed it to 1 because of the math that has to be done 0 causes some oddities. I did the same mapping for the high values.

Here is the current code. It is the closest thing I can get it to.

#include <DualVNH5019MotorShield.h>

DualVNH5019MotorShield md;

//Variables
float Act1 = 0;                            // Motor 1 speed value
float Act2 = 0;                            // Motor 2 speed value
int KeyUp = 3;                           // Reads signal from keylock switch. If high it will be used to move the actuators UP
int KeyDown = 5;                         // Reads signal from keylock switch. If high it will be used to move the actuators DOWN
int ActPot1 = A4;                        // Reads signal from potentiometer in actuator 0 (left side when looking at back of trailer).
int ActPot2 = A5;                        // Reads signal from potentiometer in actuator 1 (right side when looking at back of trailer).
int ActPot1Val;                          // Variable to save the value of the potentiaometer from ActPot1
int ActPot2Val;                          // Variable to save the value of the potentiaometer from ActPot2
int ActPot1MapVal;                       // Variable to store the new map value of the potentiameter
int ActPot2MapVal;                       // Variable to store the new map value of the potentiameter
int Limit1Up;                            // Limit to be set to stop the actuators from extending to far
int Limit1Down;                          // Limit to be set to stop the actuators from retracting to far
int Limit2Up;                            // Limit to be set to stop the actuators from extending to far
int Limit2Down;                          // Limit to be set to stop the actuators from retracting to far
int i=0;
const int buffer = 7;                    // Buffer for the actuators to equal out. This the most the actuators can be off from each other.

void setup() {

  pinMode(KeyUp, INPUT);
  pinMode(KeyDown, INPUT);
  digitalWrite(KeyUp, LOW);
  digitalWrite(KeyDown, LOW);
  ReadPots();
  Serial.begin(115200);
  delay(50);
  md.init();
}

void loop() {

  Serial.print("i value : ");
  Serial.println(i);
  Serial.print("Act1 value : ");
  Serial.println(Act1);
  Serial.print("Act2 value : ");
  Serial.println(Act2);
  ReadPots();

  if(digitalRead(KeyUp) == LOW && digitalRead(KeyDown) == LOW){
    md.setSpeeds(0, 0);
    md.setBrakes(400, 400); 
  }

  if(digitalRead(KeyUp) == HIGH){
    Up();
  }

  if(digitalRead(KeyDown) == HIGH){
    Down();
  }

}

void ReadPots() {
  ActPot1Val = 0;
  ActPot2Val = 0;
  for (i = 1; i < 4; ++i){
    ActPot1Val = ActPot1Val + analogRead(ActPot1);
    ActPot2Val = ActPot2Val + analogRead(ActPot2);
  }
  ActPot1Val = ActPot1Val / 4;
  ActPot2Val = ActPot2Val / 4;
  Serial.print("Actuator1 AVG: ");
  Serial.println(ActPot1Val);               // Prints to the Serial Monitor the value of the POT 1
  Serial.print("Actuator2 AVG: ");
  Serial.println(ActPot2Val);               // Prints to the Serial Monitor the value of the POT 2
  delay(50);
  ActPot1MapVal = map(ActPot1Val, 22, 709, 1, 608);
  ActPot2MapVal = map(ActPot2Val, 20, 707, 1, 608);  
  Serial.print("Actuator1 MV: ");
  Serial.println(ActPot1MapVal);            // Prints to the Serial Monitor the mapped value of the POT 1
  Serial.print("Actuator2 MV: ");
  Serial.println(ActPot2MapVal);            // Prints to the Serial Monitor the mapped value of the POT 2
  delay(50);
}

void Up(){         // If the Up keylock switch is activated then it will move the actuators Up
  ReadPots();
  EqualizeUP();
  delay(5);
  md.setM1Speed(Act1);
  md.setM2Speed(Act2);

}
void Down(){         // If the Down keylock switch is activated then it will move the actuators Down
  ReadPots();
  EqualizeDOWN();
  delay(5);
  md.setM1Speed(Act1);
  md.setM2Speed(Act2);
}

void EqualizeUP(){
 Act1=0;
 Act2=0;
  if(ActPot1MapVal > ActPot2MapVal){
    Act1 = (float(ActPot2MapVal) / float(ActPot1MapVal)) * 400.00;
    Act2 = 400;
  }
  else{
    Act2 = (float(ActPot1MapVal) / float(ActPot2MapVal)) * 400.00;
    Act1 = 400;
  }
 }

void EqualizeDOWN(){
 Act1=0;
 Act2=0;
  if(ActPot1MapVal > ActPot2MapVal){
    Act2 = (float(ActPot2MapVal) / float(ActPot1MapVal)) * -400.00;
    Act1 = -400;
  }
  else{
    Act1 = (float(ActPot1MapVal) / float(ActPot2MapVal)) * -400.00;
    Act2 = -400;
  } 
 }

mhump711:
They are because I mapped the lowest value for each to be 0.

I meant print out the values actually being read when you know the actuators are level and around the position where you saw the problem, and see if you are really getting equal values.

So I think I have figured out the issue. I needed to change Act1 = (float(ActPot2MapVal) / float(ActPot1MapVal)) * 400.00; to Act1 = (float(ActPot2MapVal) / float(ActPot1MapVal)) * 375.00;.
This acts as like a buffer for the actuators so that they have time to react to the new speed value.

void EqualizeUP(){
 Act1=0;
 Act2=0;
  if(ActPot1MapVal > ActPot2MapVal){
    Act1 = (float(ActPot2MapVal) / float(ActPot1MapVal)) * 375.00;
    Act2 = 400;
  }
  else{
    Act2 = (float(ActPot1MapVal) / float(ActPot2MapVal)) * 375.00;
    Act1 = 400;
  }
 }

void EqualizeDOWN(){
 Act1=0;
 Act2=0;
  if(ActPot1MapVal > ActPot2MapVal){
    Act2 = (float(ActPot2MapVal) / float(ActPot1MapVal)) * -375.00;
    Act1 = -400;
  }
  else{
    Act1 = (float(ActPot1MapVal) / float(ActPot2MapVal)) * -375.00;
    Act2 = -400;
  } 
 }

So this is the code so far. But I realized that the feedback(potentiometer) from the actuators are being affected by the keylock switch. Currently the min and max values for the feedback are between ~60 to ~740. But when I try code to read the potentiometer with other code that does not involve the keylock I get ~20 to ~995. I am more in belief that the wiring is more the issue than the code but I am not sure. I also was reading that sometimes using the same GRD can cause issues with using analogRead. Is this possibly the issue? I will eventually try it I just haven’t had the chance yet.

A thanks to anyone that can help. I also hope that the code will help someone in the future.

#include <DualVNH5019MotorShield.h>

DualVNH5019MotorShield md;

//Variables
float Act1 = 0;                          // Motor 1 speed value
float Act2 = 0;                          // Motor 2 speed value
int KeyUp = 3;                           // Reads signal from keylock switch. If high it will be used to move the actuators UP
int KeyDown = 5;                         // Reads signal from keylock switch. If high it will be used to move the actuators DOWN
int ActPot1 = A4;                        // Reads signal from potentiometer in actuator 0 (left side when looking at back of trailer).
int ActPot2 = A5;                        // Reads signal from potentiometer in actuator 1 (right side when looking at back of trailer).
int ActPot1Val;                          // Variable to save the value of the potentiaometer from ActPot1
int ActPot2Val;                          // Variable to save the value of the potentiaometer from ActPot2
int ActPot1MapVal;                       // Variable to store the new map value of the potentiameter
int ActPot2MapVal;                       // Variable to store the new map value of the potentiameter
int Limit1Up = 22;                       // Limit to be set to stop the actuators from extending to far
int Limit1Down = 1215;                   // Limit to be set to stop the actuators from retracting to far
int Limit2Up = 22;                       // Limit to be set to stop the actuators from extending to far
int Limit2Down = 1215;                   // Limit to be set to stop the actuators from retracting to far
int i=0;

void setup() {
  ReadPots();
  md.init();
}

void loop() {
  ReadPots();
  if(digitalRead(KeyUp) == LOW && digitalRead(KeyDown) == LOW){
    md.setSpeeds(0, 0);
    md.setBrakes(400, 400); 
  }
  else{
    if (digitalRead(KeyUp) == HIGH){
      if (ActPot2MapVal < Limit2Up){
        md.setSpeeds(0, 0);
        md.setBrakes(400, 400);
      }
      else{
        Up();
      }
    }
  }
  if (digitalRead(KeyDown) == HIGH){
    if (ActPot2MapVal >= Limit2Down){
      md.setSpeeds(0, 0);
      md.setBrakes(400, 400);
    }
    else{
      Down();
    }
  }
}

void ReadPots() {
  i = 1;
  ActPot1Val = 0;
  ActPot2Val = 0;
  for (i = 1; i < 4; ++i){
    ActPot1Val = ActPot1Val + analogRead(ActPot1);
    ActPot2Val = ActPot2Val + analogRead(ActPot2);
  }
  delay(10);
  ActPot1Val = ActPot1Val / 4;
  ActPot2Val = ActPot2Val / 4;
  ActPot1Val = constrain(ActPot1Val, 57, 742);
  ActPot2Val = constrain(ActPot2Val, 60, 746);
  delay(10);
  ActPot1MapVal = map(ActPot1Val, 57, 742, 1, 1216);
  ActPot2MapVal = map(ActPot2Val, 60, 746, 1, 1216);  
}

void Up(){                                     // If the Up keylock switch is activated then it will move the actuators Up
  ReadPots();
  EqualizeUP();
  md.setBrakes(0, 0);
  md.setM1Speed(Act1);
  md.setM2Speed(Act2);
}
void Down(){                                   // If the Down keylock switch is activated then it will move the actuators Down
  ReadPots();
  EqualizeDOWN();
  md.setBrakes(0, 0);
  md.setM1Speed(Act1);
  md.setM2Speed(Act2);
}

void EqualizeUP(){                              // While going UP/DOWN this function checks to see if the Actuators are in the same position. 
  Act1=0;                                       // Depending by how much the faster actuator is moving is slowed down porportional to that amount.
  Act2=0;
  if (ActPot2MapVal < 85){
   Act1 = 200;
   Act2 = 200;
   return;
  }
  else if (ActPot1MapVal == ActPot2MapVal){
    Act1 = 350;
    Act2 = 350;
  }
  else if (ActPot2MapVal > ActPot1MapVal){
    Act1 = (float(ActPot2MapVal) / float(ActPot1MapVal)) * 350.00;
    Act2 = 400;
  }
  else if (ActPot1MapVal > ActPot2MapVal){
    Act2 = (float(ActPot1MapVal) / float(ActPot2MapVal)) * 350.00;
    Act1 = 400;
  }
}

void EqualizeDOWN(){
  Act1=0;
  Act2=0;
  
  if (ActPot2MapVal < 80){
   if (ActPot2MapVal < 50){
   Act1 = -200;
   Act2 = -200;
   return;
   }
   Act1 = -250;
   Act2 = -250;
   return;
  }
  else if (ActPot1MapVal == ActPot2MapVal){
    Act1 = -350;
    Act2 = -350;
  }
  else if(ActPot2MapVal > ActPot1MapVal){
    Act2 = (float(ActPot1MapVal) / float(ActPot2MapVal)) * -350.00;
    Act1 = -400;
  }
  else if(ActPot1MapVal > ActPot2MapVal){
    Act1 = (float(ActPot2MapVal) / float(ActPot1MapVal)) * -350.00;
    Act2 = -400;
  } 
}

So I am at a loss with this project as of now. I have the issue of the feedback from the 10K pots on the actuators giving me some odd readings. See the folllowing: (This is a portion of the readings as the list would be very long.)

Actuator REAL Pot 1 = 791
Actuator REAL Pot 2 = 755
Actuator Pot 1 = 796
Actuator1 MV: 1216
Actuator Pot 2 = 760
Actuator2 MV: 1216
Actuator Pot 1 = 783
Actuator1 MV: 1203
Actuator Pot 2 = 760
Actuator2 MV: 1216
Actuator REAL Pot 1 = 787
Actuator REAL Pot 2 = 754
Actuator Pot 1 = 789
Actuator1 MV: 1216
Actuator Pot 2 = 736
Actuator2 MV: 1176
Actuator Pot 1 = 778
Actuator1 MV: 1191
Actuator Pot 2 = 753
Actuator2 MV: 1216
Actuator REAL Pot 1 = 791
Actuator REAL Pot 2 = 754
Actuator Pot 1 = 789
Actuator1 MV: 1216
Actuator Pot 2 = 752
Actuator2 MV: 1216
Actuator Pot 1 = 778
Actuator1 MV: 1191
Actuator Pot 2 = 755
Actuator2 MV: 1216
Actuator REAL Pot 1 = 790
Actuator REAL Pot 2 = 754
Actuator Pot 1 = 769
Actuator1 MV: 1169
Actuator Pot 2 = 722
Actuator2 MV: 1142
Actuator Pot 1 = 790
Actuator1 MV: 1216
Actuator Pot 2 = 754
Actuator2 MV: 1216
Actuator REAL Pot 1 = 791
Actuator REAL Pot 2 = 754
Actuator Pot 1 = 791
Actuator1 MV: 1216
Actuator Pot 2 = 755
Actuator2 MV: 1216
Actuator Pot 1 = 802
Actuator1 MV: 1216
Actuator Pot 2 = 754
Actuator2 MV: 1216
Actuator REAL Pot 1 = 790
Actuator REAL Pot 2 = 754
Actuator Pot 1 = 815
Actuator1 MV: 1216
Actuator Pot 2 = 790
Actuator2 MV: 1216
Actuator Pot 1 = 790
Actuator1 MV: 1216
Actuator Pot 2 = 755
Actuator2 MV: 1216
Actuator REAL Pot 1 = 790
Actuator REAL Pot 2 = 754
Actuator Pot 1 = 790
Actuator1 MV: 1216
Actuator Pot 2 = 753
Actuator2 MV: 1216
Actuator Pot 1 = 791
Actuator1 MV: 1216
Actuator Pot 2 = 741
Actuator2 MV: 1189
Actuator REAL Pot 1 = 791
Actuator REAL Pot 2 = 767
Actuator Pot 1 = 789
Actuator1 MV: 1216
Actuator Pot 2 = 742
Actuator2 MV: 1191
Actuator Pot 1 = 790
Actuator1 MV: 1216
Actuator Pot 2 = 755
Actuator2 MV: 1216
Actuator REAL Pot 1 = 791
Actuator REAL Pot 2 = 754
Actuator Pot 1 = 779
Actuator1 MV: 1193
Actuator Pot 2 = 734
Actuator2 MV: 1172
Actuator Pot 1 = 790
Actuator1 MV: 1216
Actuator Pot 2 = 761
Actuator2 MV: 1216
Actuator REAL Pot 1 = 792
Actuator REAL Pot 2 = 826
Actuator Pot 1 = 792
Actuator1 MV: 1216
Actuator Pot 2 = 755
Actuator2 MV: 1216
Actuator Pot 1 = 790
Actuator1 MV: 1216
Actuator Pot 2 = 760
Actuator2 MV: 1216
Actuator REAL Pot 1 = 790
Actuator REAL Pot 2 = 754
Actuator Pot 1 = 796
Actuator1 MV: 1216
Actuator Pot 2 = 763
Actuator2 MV: 1216
Actuator Pot 1 = 789
Actuator1 MV: 1216
Actuator Pot 2 = 748
Actuator2 MV: 1206
Actuator REAL Pot 1 = 791
Actuator REAL Pot 2 = 754
Actuator Pot 1 = 790
Actuator1 MV: 1216
Actuator Pot 2 = 753
Actuator2 MV: 1216
Actuator Pot 1 = 787
Actuator1 MV: 1213
Actuator Pot 2 = 754
Actuator2 MV: 1216
Actuator REAL Pot 1 = 788
Actuator REAL Pot 2 = 754
Actuator Pot 1 = 790
Actuator1 MV: 1216
Actuator Pot 2 = 756
Actuator2 MV: 1216
Actuator Pot 1 = 793
Actuator1 MV: 1216
Actuator Pot 2 = 754
Actuator2 MV: 1216
Actuator REAL Pot 1 = 791
Actuator REAL Pot 2 = 754
Actuator Pot 1 = 789
Actuator1 MV: 1216
Actuator Pot 2 = 746
Actuator2 MV: 1201
Actuator Pot 1 = 793
Actuator1 MV: 1216
Actuator Pot 2 = 758
Actuator2 MV: 1216
Actuator REAL Pot 1 = 817
Actuator REAL Pot 2 = 752
Actuator Pot 1 = 795
Actuator1 MV: 1216
Actuator Pot 2 = 763
Actuator2 MV: 1216
Actuator Pot 1 = 786
Actuator1 MV: 1211
Actuator Pot 2 = 746
Actuator2 MV: 1201
Actuator REAL Pot 1 = 791
Actuator REAL Pot 2 = 754
Actuator Pot 1 = 790
Actuator1 MV: 1216
Actuator Pot 2 = 754
Actuator2 MV: 1216
Actuator Pot 1 = 790
Actuator1 MV: 1216
Actuator Pot 2 = 751
Actuator2 MV: 1213
Actuator REAL Pot 1 = 791
Actuator REAL Pot 2 = 759
Actuator Pot 1 = 789
Actuator1 MV: 1216
Actuator Pot 2 = 754
Actuator2 MV: 1216
Actuator Pot 1 = 790
Actuator1 MV: 1216
Actuator Pot 2 = 749
Actuator2 MV: 1208
Actuator REAL Pot 1 = 845
Actuator REAL Pot 2 = 752
Actuator Pot 1 = 796
Actuator1 MV: 1216
Actuator Pot 2 = 753
Actuator2 MV: 1216
Actuator Pot 1 = 778
Actuator1 MV: 1191
Actuator Pot 2 = 765
Actuator2 MV: 1216
Actuator REAL Pot 1 = 792
Actuator REAL Pot 2 = 864
Actuator Pot 1 = 789
Actuator1 MV: 1216
Actuator Pot 2 = 751
Actuator2 MV: 1213
Actuator Pot 1 = 778
Actuator1 MV: 1191
Actuator Pot 2 = 768
Actuator2 MV: 1216
Actuator REAL Pot 1 = 791
Actuator REAL Pot 2 = 754
Actuator Pot 1 = 785
Actuator1 MV: 1208
Actuator Pot 2 = 749
Actuator2 MV: 1208
Actuator Pot 1 = 791
Actuator1 MV: 1216
Actuator Pot 2 = 752
Actuator2 MV: 1216
Actuator REAL Pot 1 = 791
Actuator REAL Pot 2 = 754
Actuator Pot 1 = 790
Actuator1 MV: 1216
Actuator Pot 2 = 754
Actuator2 MV: 1216
Actuator Pot 1 = 789
Actuator1 MV: 1216
Actuator Pot 2 = 740
Actuator2 MV: 1186
Actuator REAL Pot 1 = 789
Actuator REAL Pot 2 = 743
Actuator Pot 1 = 790
Actuator1 MV: 1216
Actuator Pot 2 = 753
Actuator2 MV: 1216
Actuator Pot 1 = 805
Actuator1 MV: 1216
Actuator Pot 2 = 753
Actuator2 MV: 1216
Actuator REAL Pot 1 = 791
Actuator REAL Pot 2 = 754
Actuator Pot 1 = 805
Actuator1 MV: 1216
Actuator Pot 2 = 753
Actuator2 MV: 1216
Actuator Pot 1 = 803
Actuator1 MV: 1216
Actuator Pot 2 = 741
Actuator2 MV: 1189
Actuator REAL Pot 1 = 789
Actuator REAL Pot 2 = 639
Actuator Pot 1 = 791
Actuator1 MV: 1216
Actuator Pot 2 = 771
Actuator2 MV: 1216
Actuator Pot 1 = 791
Actuator1 MV: 1216
Actuator Pot 2 = 742
Actuator2 MV: 1191
Actuator REAL Pot 1 = 791
Actuator REAL Pot 2 = 754
Actuator Pot 1 = 786
Actuator1 MV: 1211
Actuator Pot 2 = 753
Actuator2 MV: 1216
Actuator Pot 1 = 791
Actuator1 MV: 1216
Actuator Pot 2 = 752
Actuator2 MV: 1216
Actuator REAL Pot 1 = 834
Actuator REAL Pot 2 = 752
Actuator Pot 1 = 790
Actuator1 MV: 1216
Actuator Pot 2 = 754
Actuator2 MV: 1216
Actuator Pot 1 = 791
Actuator1 MV: 1216
Actuator Pot 2 = 759
Actuator2 MV: 1216
Actuator REAL Pot 1 = 791
Actuator REAL Pot 2 = 754
Actuator Pot 1 = 790
Actuator1 MV: 1216
Actuator Pot 2 = 753
Actuator2 MV: 1216
Actuator Pot 1 = 787
Actuator1 MV: 1213
Actuator Pot 2 = 759
Actuator2 MV: 1216
Actuator REAL Pot 1 = 792
Actuator REAL Pot 2 = 783
Actuator Pot 1 = 793
Actuator1 MV: 1216
Actuator Pot 2 = 753
Actuator2 MV: 1216
Actuator Pot 1 = 787
Actuator1 MV: 1213
Actuator Pot 2 = 759
Actuator2 MV: 1216
Actuator REAL Pot 1 = 791
Actuator REAL Pot 2 = 753

As you can see the Reading “Actuator Pot 1”&“Actuator Pot 2” should be getting smaller but they tend to jump around. Code will be in the next post.
I have an Arduino Uno, a protoshield, and the Pololu Dual VNH5019 Motor Driver Shield for Arduino (http://www.pololu.com/catalog/product/2502). When I run the motors without using the math the program works fine.

Any help would be greatly appreciated.

Thanks
Mike

#include <DualVNH5019MotorShield.h>
DualVNH5019MotorShield md;

// Variables

const int keyUp = 5;  // Reads signal from keylock switch. If high it will be used to move the actuators UP
const int keyDown = 3;  // Reads signal from keylock switch. If high it will be used to move the actuators Down
int act1 = 0;  // Motor 1 speed value
int act2 = 0;  // Motor 2 speed value
const int actPot1 = A4; // Reads signal from potentiometer in actuator 1 (left side when looking at back of trailer).
const int actPot2 = A5;  // Reads signal from potentiometer in actuator 2 (right side when looking at back of trailer).
int actPot1Val = 0;  // Variable to save the value of the potentiaometer from ActPot1
int actPot2Val = 0;  // Variable to save the value of the potentiaometer from ActPot2
int actPot1MapVal;  // Variable to store the new map value of the potentiameter
int actPot2MapVal;  // Variable to store the new map value of the potentiameter
int actPot1MathVal;
int actPot2MathVal;
const int limit1Up = 1216;  // Limit to be set to stop the actuators from extending to far
const int limit1Down = 1;  // Limit to be set to stop the actuators from retracting to far
const int limit2Up = 1216;  // Limit to be set to stop the actuators from extending to far
const int limit2Down = 1;  // Limit to be set to stop the actuators from retracting to far
int downCheck = 0;

void setup() {
  pinMode(keyUp, INPUT);
  digitalWrite(keyUp, HIGH);
  pinMode(keyDown, INPUT);
  digitalWrite(keyDown, HIGH);
  md.init();
  Serial.begin(115200);
  READPOTS();
}

void loop() {
  READPOTS();
  Serial.print("Actuator REAL Pot 1 = ");  // Prints to the Serial Monitor the value of the POT 1
  Serial.println(analogRead(actPot1));
  Serial.print("Actuator REAL Pot 2 = ");  // Prints to the Serial Monitor the value of the POT 2
  Serial.println(analogRead(actPot2));
  if(digitalRead(keyUp) == HIGH && digitalRead(keyDown) == HIGH){
    act1 = 0;
    act2 = 0;
    md.setM1Speed(act1);
    md.setM2Speed(act2);
    md.setM1Brake(400);
    md.setM2Brake(400);    
  }
  else if (digitalRead(keyUp) == LOW){
     if (actPot1MapVal >= limit1Up){
     act1 = 0;
     act2 = 0;
     md.setM1Speed(act1);
     md.setM2Speed(act2);
     md.setM1Brake(400);
     md.setM2Brake(400);    
     }
     else{
    UP();
    }
  }
  else if(digitalRead(keyDown) == LOW){
    if (actPot1MapVal <= limit2Down){
     act1 = 0;
     act2 = 0;
     md.setM1Speed(act1);
     md.setM2Speed(act2);
     md.setM1Brake(400);
     md.setM2Brake(400);    
     }
     else{
         DOWN(); 
     }
  }
}

void UP(){  // If the Up keylock switch is activated then it will move the actuators Up
   if (actPot1MapVal > 1000){
   act1 = act1 - 2;
   act2 = act1;
   delay(20);
   if (act1 < 250){
   act1 = 250;
   act2 = 250;
   }
   }
   else{
   if(actPot1MapVal == actPot2MapVal){
   act1 = 360.00;
   act2 = 360.00;
   }
   else  if(actPot1MapVal > actPot2MapVal){
    act1 = (((actPot2MathVal * 100) / actPot1MathVal) * 320.00) / 100;
    act2 = 360.00;
  }
  else if(actPot1MapVal < actPot2MapVal){
    act2 = (((actPot1MathVal * 100) / actPot2MathVal) * 320.00) / 100;
    act1 = 360.00;
  }
  }
  md.setBrakes(0, 0);
  md.setSpeeds(act1, act2);

}

void DOWN(){  // If the Down keylock switch is activated then it will move the actuators Down
   if (actPot1MapVal < 1000){
   downCheck = 0;  
   }
   if (actPot1MapVal > 1000){
   if (downCheck = 0){
   act1 = -200;
   act2 = -200;
   downCheck = 1;
   }
   act1 = act1 + -2;
   act2 = act1;
   if(act1 < -320){
   act1 = -360;
   act2 = -360;
   }
   }
   else{
   if(actPot1MapVal == actPot2MapVal){
   act1 = -360.00;
   act2 = -360.00;
   }
   else  if(actPot1MapVal < actPot2MapVal){
    act1 = (((actPot1MathVal * 100) / actPot2MathVal) * -320.00) / 100;
    act2 = -360.00;
  }
  else if(actPot1MapVal > actPot2MapVal){
    act2 = (((actPot2MathVal * 100) / actPot1MathVal) * -320.00) / 100;
    act1 = -360.00;
    }
  }
  md.setBrakes(0, 0);
  md.setSpeeds(act1, act2);
}

void READPOTS(){
  actPot1Val = 0;
  actPot2Val = 0;
  for (int i = 0; i < 8; i = i + 1){
    actPot1Val = actPot1Val + analogRead(actPot1);
    delay(10);
    actPot2Val = actPot2Val + analogRead(actPot2);
    delay(10);
  }
  actPot1Val = actPot1Val / 8;
  actPot2Val = actPot2Val / 8;
  actPot1Val = constrain(actPot1Val, 292, 790);
  actPot2Val = constrain(actPot2Val, 254, 753);
  actPot1MapVal = map(actPot1Val, 292, 790, 1, 1216);
  actPot2MapVal = map(actPot2Val, 254, 753, 1, 1216);
  actPot1MathVal = actPot1MapVal;
  actPot2MathVal = actPot2MapVal;
  Serial.print("Actuator Pot 1 = ");  // Prints to the Serial Monitor the value of the POT 1
  Serial.println(actPot1Val);
  Serial.print("Actuator1 MV: ");
  Serial.println(actPot1MapVal);  // Prints to the Serial Monitor the mapped value of the POT 1
  Serial.print("Actuator Pot 2 = ");  // Prints to the Serial Monitor the value of the POT 2
  Serial.println(actPot2Val);
  Serial.print("Actuator2 MV: ");
  Serial.println(actPot2MapVal);  // Prints to the Serial Monitor the mapped value of the POT 2
}