Digital Pins Output Pins not Being Written to

Ok. Update.

The Vertical motor is working.

I've added code and re-populated the array for the X-Y Joystick.

I've added code for the X-Y Joystick changed and modified the original joystick changed routine so that it looks only for the Z axis. It is to simplify things a bit, so that the motor driver pins are updated only for the fwd/reverse motors and the vertical motor.

What is happening now is that the motors only spin when the joystick is pushed forwards.

I've checked the voltages being returned from the joystick and changed the values in the array accordingly, but this doesn't seem to make much difference.

The full amended code is below:-

I've checked the actual voltages with a voltmeter and they all give me the values that I would expect, but they are slightly different from the ones coming into the pins.

Any suggestions?

//Port Motor Pins
constexpr int prtPWMPin = 9; //Port Motor PWM
constexpr int prtIn1Pin = 8; //Port Motor In1
constexpr int prtIn2Pin = 7; //Port Motor In2

//Starboard Motor Pins
constexpr int stbdPWMPin = 6; //Starboard Motor PWM
constexpr int stbdIn3Pin = 5; //Starboard Motor In3
constexpr int stbdIn4Pin = 4; //Starboard Motor In4

//Vertical Motor Pins
constexpr int vertPWMPin = 10; //Vertical Motor PWM Pin
constexpr int vertIn3Pin = 12; //Vertical Motor In3 Pin
constexpr int vertIn4Pin = 11; //Vertical Motor In4 Pin

struct motorType {
  byte pwmPin;
  byte inPin1;
  byte inPin2;
  void init(byte pwm, byte in1, byte in2) {
    pwmPin = pwm;
    inPin1 = in1;
    inPin2 = in2;
    pinMode(inPin1, OUTPUT);
    pinMode(inPin2, OUTPUT);
    stop();
  }
  void setDirection(byte in1, byte in2) {
    digitalWrite(inPin1, in1);
    digitalWrite(inPin2, in2);
  }
  void stop() {
    digitalWrite(inPin1, LOW);
    digitalWrite(inPin1, LOW);
    speed(0);
  }
  void speed(int aSpeed) {
    if (aSpeed >= 0) {
      analogWrite(pwmPin, aSpeed);
    }
  }
  // The following functions are not used here
  // but could be useful in future
  void forward() {
    digitalWrite(inPin1, HIGH);
    digitalWrite(inPin1, LOW);
  }
  void back() {
    digitalWrite(inPin1, LOW);
    digitalWrite(inPin1, HIGH);
  }
};

motorType prtMotor;
motorType stbdMotor;
motorType vertMotor;



//Joystick input values
int X_Voltage  = 0; //Port/Starboard Joystick input value
int Y_Voltage = 0;  //Forward/Reverse Joystick input value
int Z_Voltage = 0;  //Vertical Joystick input value

//Min Joystick Values
//int Min_X_Voltage = 0;
//int Min_Y_Voltage = 0;
//int Min_Z_Voltage = 0;

//int Z_CountR = 0;// Used to access Rows data in Z_Joystick_Array
//int Z_CountC = 0;// Used to access Columns data in Z_Joystick_Array
int Z_Rows = 5; //Max Number of Rows in Z Joystick Array
int Z_Columns = 4; //Max Number of Columns in Z Joystick Array

int X_Count = 0; // Used to access X_Voltage data in XY_Joystick_Array
int Y_Count = 0; // Used to access Y_Voltage date in XY_Joystick_Array
int XY_Columns = 7; //Used to access Columns in XY_Joystick_Array
int XY_Rows = 9; // Number of Rows in XY Joystick Array

// Array for decoding Z Axis Joystick values - Z_Voltage, In3, In4, PWM
int Z_Joystick_Array[5][4] = {
  {0, 0, 1, 127}, //Joystick full down - motor down at PWM 50%
  {1, 0, 1, 64}, //Joystick half down - motor down at PWM 25%
  {2, 0, 0, 0},  //Joystick in middle, motor stopped, PWM 0
  {3, 1, 0, 64}, //Joystick half up - motor up at PWM 25%
  {4, 1, 0, 127} //Joystick full up - motor up at 50%
};

//Array for decoded XY joystick - X_Voltage, Y_Voltage, In1, In2, PWM1, In3, In4, PWM2
int XY_Joystick_Array[9][8] = {
  {2, 2, 0, 0, 0, 0, 0, 0}, // Both Motors stopped
  {2, 4, 1, 0, 127, 1, 0, 127}, // Both Motors forward
  {0, 2, 1, 0, 127, 0, 0, 0}, // Right/starboard - Port Motor forward PWM 50%, Starboard Motor stopped
  {4, 2, 0, 0, 0, 1, 0, 127}, // Left/Port - Starboard Motor forward PWM 50%, Port Motor stopped
  {2, 0, 0, 1, 127, 0, 1, 127}, //Both Motors Reverse
  {4, 4, 1, 0, 64, 1, 0, 127}, //Left/Port Forwards - Starboard Motor Forward PWM 50%,Port Motor Forward PWM 25%
  {0, 0, 0, 1, 127, 0, 1, 64}, //Right/Starboard Reverse - Port Motor Reverse PWM 50%, Starboard Motor Forward PWM 25%
  {3, 1, 1, 0, 127, 1, 0, 64}, //Right/Starboard Forward - Port Motor Forward PWM 50%, Starboard Motor Reverse PWM 25%
  {4, 0, 0, 1, 64, 0, 1, 127} //Left/Port Reverse - Port Motor Reverse PWM 25%, Starboard Motor Reverse PWM 50%
};

#define X_Pin A0 //Joystick input Port/Starboard pin
#define Y_Pin A1 //Joystick input Forward/Reverse pin
#define Z_Pin A2 //Joystick input up/down

// function to return a scaled value of 0-5V from the analogue pins
int scaled_value(int adc, int scale_factor = 5) {
  constexpr int max_adc = 1023;
  int scaled = scale_factor * adc / max_adc;
  return scaled;
}

void setup() {

  //Enable Joystick inputs
  pinMode(X_Pin, INPUT); //Joystick X Input Pin
  pinMode(Y_Pin, INPUT); //Joystick Y Input Pin
  pinMode(Z_Pin, INPUT); //Input Z Joystick Pin

  //Set Motors to stop -> now done in init()
  //Enable Port motor outputs
  prtMotor.init(prtPWMPin, prtIn1Pin, prtIn2Pin);

  //Enable Starboard Motor Outputs
  stbdMotor.init(stbdPWMPin, stbdIn3Pin, stbdIn4Pin);

  //Enable Vertical Motor Outputs
  vertMotor.init(vertPWMPin, vertIn3Pin, vertIn4Pin);

  //Enable Serial Output for Displaying values
  Serial.begin(9600);

}

int oldX, oldY, oldZ;

void loop() {
    if (Vert_joystickDataHaveChanged()) {
      ControlVertMotor();
    }
    if (XY_joystickDataHaveChanged()){
      ControlPortStarbdMotor();
    }
}

boolean Vert_joystickDataHaveChanged() {
  
  Z_Voltage = scaled_value(analogRead(Z_Pin), 5);
  if (oldZ != Z_Voltage)
  {
    Serial.print("Z Voltage\t");
    Serial.print(Z_Voltage);
    oldZ = Z_Voltage;
    return true;
  }
  return false;
}
boolean XY_joystickDataHaveChanged() {
  X_Voltage = scaled_value(analogRead(X_Pin), 5);
  Y_Voltage = scaled_value(analogRead(Y_Pin), 5);
  
  if (oldX != X_Voltage ||
      oldY != Y_Voltage )
  {
    Serial.print("X Voltage\t");
    Serial.print(X_Voltage);
    Serial.print("\tY Voltage\t");
    Serial.print(Y_Voltage);
    oldX = X_Voltage;
    oldY = Y_Voltage;
    return true;
  }
  return false;
}
void ControlVertMotor() {
  for (int Z_CountR = 0; Z_CountR < Z_Rows; Z_CountR++)
  {
    int Array_Voltage = 0;
    Array_Voltage = Z_Joystick_Array[Z_CountR][0];
    if (Z_Voltage == Array_Voltage)
    {
      int in1 = Z_Joystick_Array[Z_CountR][1];
      int in2 = Z_Joystick_Array[Z_CountR][2];
      int pwmValue = Z_Joystick_Array[Z_CountR][3];
      vertMotor.setDirection(in1, in2);
      vertMotor.speed(pwmValue);

      return;
    }
  }
}
  void ControlPortStarbdMotor() {
  for (int X_CountR = 0; X_CountR < XY_Rows; X_CountR++)
  {
    int X_Array_Voltage = 0;
    int Y_Array_Voltage = 0;
    X_Array_Voltage = XY_Joystick_Array[X_CountR][0];
    if (X_Voltage == X_Array_Voltage)
    {
      if (Y_Voltage == XY_Joystick_Array[X_CountR][1])
      {
        int in1 = XY_Joystick_Array[X_CountR][2];
        int in2 = XY_Joystick_Array[X_CountR][3];
        int pwmValue1 = XY_Joystick_Array[X_CountR][4];
        int in3 = XY_Joystick_Array[X_CountR][5];
        int in4 = XY_Joystick_Array[X_CountR][6];
        int pwmValue2 = XY_Joystick_Array[X_CountR][7]; 
        stbdMotor.setDirection(in1, in2);
        stbdMotor.speed(pwmValue1);
        prtMotor.setDirection(in3, in4);
        prtMotor.speed(pwmValue2);

        Serial.print("XY Array Row: ");
        Serial.print(X_CountR);
        Serial.print("\tX_Array Voltage: ");
        Serial.print(X_Array_Voltage);
        Serial.print("\tY_Array Voltage");
        Serial.print(Y_Array_Voltage);
        Serial.print("\tPort In1: ");
        Serial.print(in1);
        Serial.print("\tPort In2: ");
        Serial.print(in2);
        Serial.print("\tPort PWM: ");
        Serial.println(pwmValue1);
        Serial.print("\tStarboard In3: ");
        Serial.print(in3);
        Serial.print("\tStarboard In4: ");
        Serial.print(in4);
        Serial.print("\tStarboard PWM: ");
        Serial.println(pwmValue2);
      return;
      }
    }
    else{
      return;
    } 

  }
}


This is a copy of the Serial Monitor, below. It seems that the XY_JoystickChanged runs a couple of times and the array is read, but it doesn't seem to run for the last change of the X& Y voltages. I'm not 100% sure how best to get round this? Would a delay in the program of a few ms get round this? Or is there another way to tackle it?

X Voltage 1 Y Voltage 2X Voltage 2 Y Voltage 2XY Array Row: 0 X_Array Voltage: 2 Y_Array Voltage0 Port In1: 0 Port In2: 0 Port PWM: 0

Starboard In3: 0 Starboard In4: 0 Starboard PWM: 0

X Voltage 1 Y Voltage 2X Voltage 0 Y Voltage 2X Voltage 1 Y Voltage 2X Voltage 2 Y Voltage 2XY Array Row: 0 X_Array Voltage: 2 Y_Array Voltage0 Port In1: 0 Port In2: 0 Port PWM: 0

Starboard In3: 0 Starboard In4: 0 Starboard PWM: 0

You might check the XY array: The line with {3, 1, ...} does not fit into the scheme.

I suggest to sort the array rows for an easier overview e.g. for the positions

  • x left, y top down
  • x centered, y top down
  • x right, y top down

It's not really necessary but would make it easier to compare with the wanted results.

Hi,

Thanks for your reply.

I was playing about with values and input the first values that were being returned for a specific condition, e.g. forward on the joystick, reverse, etc.

I did sort the rows of the array, but now if I push the joystick forward, the motors come on and stay on even when the joystick has returned to the middle. Not 100% sure what it causing this.

I think that the joystickchanged procedure isn't running all the time - it seems to run for a couple of samples, then stop.

Any ideas?

Full code is below:-

//Port Motor Pins
constexpr int prtPWMPin = 9; //Port Motor PWM
constexpr int prtIn1Pin = 8; //Port Motor In1
constexpr int prtIn2Pin = 7; //Port Motor In2

//Starboard Motor Pins
constexpr int stbdPWMPin = 6; //Starboard Motor PWM
constexpr int stbdIn3Pin = 5; //Starboard Motor In3
constexpr int stbdIn4Pin = 4; //Starboard Motor In4

//Vertical Motor Pins
constexpr int vertPWMPin = 10; //Vertical Motor PWM Pin
constexpr int vertIn3Pin = 12; //Vertical Motor In3 Pin
constexpr int vertIn4Pin = 11; //Vertical Motor In4 Pin

struct motorType {
  byte pwmPin;
  byte inPin1;
  byte inPin2;
  void init(byte pwm, byte in1, byte in2) {
    pwmPin = pwm;
    inPin1 = in1;
    inPin2 = in2;
    pinMode(inPin1, OUTPUT);
    pinMode(inPin2, OUTPUT);
    stop();
  }
  void setDirection(byte in1, byte in2) {
    digitalWrite(inPin1, in1);
    digitalWrite(inPin2, in2);
  }
  void stop() {
    digitalWrite(inPin1, LOW);
    digitalWrite(inPin1, LOW);
    speed(0);
  }
  void speed(int aSpeed) {
    if (aSpeed >= 0) {
      analogWrite(pwmPin, aSpeed);
    }
  }
  // The following functions are not used here
  // but could be useful in future
  void forward() {
    digitalWrite(inPin1, HIGH);
    digitalWrite(inPin1, LOW);
  }
  void back() {
    digitalWrite(inPin1, LOW);
    digitalWrite(inPin1, HIGH);
  }
};

motorType prtMotor;
motorType stbdMotor;
motorType vertMotor;



//Joystick input values
int X_Voltage  = 0; //Port/Starboard Joystick input value
int Y_Voltage = 0;  //Forward/Reverse Joystick input value
int Z_Voltage = 0;  //Vertical Joystick input value

//Min Joystick Values
//int Min_X_Voltage = 0;
//int Min_Y_Voltage = 0;
//int Min_Z_Voltage = 0;

//int Z_CountR = 0;// Used to access Rows data in Z_Joystick_Array
//int Z_CountC = 0;// Used to access Columns data in Z_Joystick_Array
int Z_Rows = 5; //Max Number of Rows in Z Joystick Array
int Z_Columns = 4; //Max Number of Columns in Z Joystick Array

int X_Count = 0; // Used to access X_Voltage data in XY_Joystick_Array
int Y_Count = 0; // Used to access Y_Voltage date in XY_Joystick_Array
int XY_Columns = 7; //Used to access Columns in XY_Joystick_Array
int XY_Rows = 9; // Number of Rows in XY Joystick Array

// Array for decoding Z Axis Joystick values - Z_Voltage, In3, In4, PWM
int Z_Joystick_Array[5][4] = {
  {0, 0, 1, 127}, //Joystick full down - motor down at PWM 50%
  {1, 0, 1, 64}, //Joystick half down - motor down at PWM 25%
  {2, 0, 0, 0},  //Joystick in middle, motor stopped, PWM 0
  {3, 1, 0, 64}, //Joystick half up - motor up at PWM 25%
  {4, 1, 0, 127} //Joystick full up - motor up at 50%
};

//Array for decoded XY joystick - X_Voltage, Y_Voltage, In1, In2, PWM1, In3, In4, PWM2
int XY_Joystick_Array[9][8] = {
  {2, 4, 1, 0, 127, 1, 0, 127}, // Both Motors forward
  {2, 0, 0, 1, 127, 0, 1, 127}, //Both Motors Reverse
  {2, 2, 0, 0, 0, 0, 0, 0}, // Both Motors stopped
  {4, 2, 1, 0, 127, 0, 0, 0}, // Right/starboard - Port Motor forward PWM 50%, Starboard Motor stopped
  {0, 2, 0, 0, 0, 1, 0, 127}, // Left/Port - Starboard Motor forward PWM 50%, Port Motor stopped
  {4, 4, 1, 0, 127, 1, 0, 64}, //Right/Starboard Forward - Port Motor Forward PWM 50%, Starboard Motor Reverse PWM 25%
  {4, 0, 0, 1, 127, 0, 1, 64}, //Right/Starboard Reverse - Port Motor Reverse PWM 50%, Starboard Motor Forward PWM 25%
  {0, 0, 0, 1, 64, 0, 1, 127}, //Left/Port Reverse - Port Motor Reverse PWM 25%, Starboard Motor Reverse PWM 50%
  {0, 4, 1, 0, 64, 1, 0, 127}, //Left/Port Forwards - Starboard Motor Forward PWM 50%,Port Motor Forward PWM 25% 
};

#define X_Pin A0 //Joystick input Port/Starboard pin
#define Y_Pin A1 //Joystick input Forward/Reverse pin
#define Z_Pin A2 //Joystick input up/down

// function to return a scaled value of 0-5V from the analogue pins
int scaled_value(int adc, int scale_factor = 5) {
  constexpr int max_adc = 1023;
  int scaled = scale_factor * adc / max_adc;
  return scaled;
}

void setup() {

  //Enable Joystick inputs
  pinMode(X_Pin, INPUT); //Joystick X Input Pin
  pinMode(Y_Pin, INPUT); //Joystick Y Input Pin
  pinMode(Z_Pin, INPUT); //Input Z Joystick Pin

  //Set Motors to stop -> now done in init()
  //Enable Port motor outputs
  prtMotor.init(prtPWMPin, prtIn1Pin, prtIn2Pin);

  //Enable Starboard Motor Outputs
  stbdMotor.init(stbdPWMPin, stbdIn3Pin, stbdIn4Pin);

  //Enable Vertical Motor Outputs
  vertMotor.init(vertPWMPin, vertIn3Pin, vertIn4Pin);

  //Enable Serial Output for Displaying values
  Serial.begin(9600);

}

int oldX, oldY, oldZ;

void loop() {
    if (Vert_joystickDataHaveChanged()) {
      ControlVertMotor();
    }
    if (XY_joystickDataHaveChanged()){
      ControlPortStarbdMotor();
    }
}

boolean Vert_joystickDataHaveChanged() {
  
  Z_Voltage = scaled_value(analogRead(Z_Pin), 5);
  if (oldZ != Z_Voltage)
  {
    oldZ = Z_Voltage;
    return true;
  }
  return false;
}
boolean XY_joystickDataHaveChanged() {
  X_Voltage = scaled_value(analogRead(X_Pin), 5);
  Y_Voltage = scaled_value(analogRead(Y_Pin), 5);
  
  if (oldX != X_Voltage ||
      oldY != Y_Voltage )
  {
    Serial.print("X Voltage\t");
    Serial.print(X_Voltage);
    Serial.print("\tY Voltage\t");
    Serial.print(Y_Voltage);
    oldX = X_Voltage;
    oldY = Y_Voltage;
    return true;
  }
  return false;
}
void ControlVertMotor() {
  for (int Z_CountR = 0; Z_CountR < Z_Rows; Z_CountR++)
  {
    int Array_Voltage = 0;
    Array_Voltage = Z_Joystick_Array[Z_CountR][0];
    if (Z_Voltage == Array_Voltage)
    {
      int in1 = Z_Joystick_Array[Z_CountR][1];
      int in2 = Z_Joystick_Array[Z_CountR][2];
      int pwmValue = Z_Joystick_Array[Z_CountR][3];
      vertMotor.setDirection(in1, in2);
      vertMotor.speed(pwmValue);
      return;
    }
  }
}
  void ControlPortStarbdMotor() {
  for (int X_CountR = 0; X_CountR < XY_Rows; X_CountR++)
  {
    int X_Array_Voltage = 0;
    int Y_Array_Voltage = 0;
    X_Array_Voltage = XY_Joystick_Array[X_CountR][0];
    Y_Array_Voltage = XY_Joystick_Array[X_CountR][1];
    if (X_Voltage == X_Array_Voltage && Y_Voltage == Y_Array_Voltage)
    {
      int in1 = XY_Joystick_Array[X_CountR][2];
      int in2 = XY_Joystick_Array[X_CountR][3];
      int pwmValue1 = XY_Joystick_Array[X_CountR][4];
      int in3 = XY_Joystick_Array[X_CountR][5];
      int in4 = XY_Joystick_Array[X_CountR][6];
      int pwmValue2 = XY_Joystick_Array[X_CountR][7]; 
      stbdMotor.setDirection(in1, in2);
      stbdMotor.speed(pwmValue1);
      prtMotor.setDirection(in3, in4);
      prtMotor.speed(pwmValue2);
      Serial.print("XY Array Row: ");
      Serial.print(X_CountR);
      Serial.print("\tX_Array Voltage: ");
      Serial.print(X_Array_Voltage);
      Serial.print("\tY_Array Voltage");
      Serial.print(Y_Array_Voltage);
      Serial.print("\tPort In1: ");
      Serial.print(in1);
      Serial.print("\tPort In2: ");
      Serial.print(in2);
      Serial.print("\tPort PWM: ");
      Serial.println(pwmValue1);
      Serial.print("\tStarboard In3: ");
      Serial.print(in3);
      Serial.print("\tStarboard In4: ");
      Serial.print(in4);
      Serial.print("\tStarboard PWM: ");
      Serial.println(pwmValue2);
      return;
      }
    else{
      return;
    } 
  }
}


I guess you only have to delete the

else{
      return;

in the function that's controlling the XY motors.

Thanks for your reply again.

That was it. It worked straight away.

I wouldn't have thought that the else return bit would have made any difference. Is this an peculiarity of Arduino/C++?

No it isn't. The return in the else branch left the function immediately when the if condition was not met.

So I have taken this a bit further. I've added the slew function of the X-Y Joystick.

Now what is happening is that the motors run very slowly and nothing that I do with the joystick stops them.

There is nothing coming through on the Serial Monitor.

I've tried resetting the Arduino, then uploading the code again, but it makes no difference.

Any ideas??

Full code below:-

//Port Motor Pins
constexpr int prtPWMPin = 9; //Port Motor PWM
constexpr int prtIn1Pin = 8; //Port Motor In1
constexpr int prtIn2Pin = 7; //Port Motor In2

//Starboard Motor Pins
constexpr int stbdPWMPin = 6; //Starboard Motor PWM
constexpr int stbdIn3Pin = 5; //Starboard Motor In3
constexpr int stbdIn4Pin = 4; //Starboard Motor In4

//Vertical Motor Pins
constexpr int vertPWMPin = 10; //Vertical Motor PWM Pin
constexpr int vertIn3Pin = 12; //Vertical Motor In3 Pin
constexpr int vertIn4Pin = 11; //Vertical Motor In4 Pin

struct motorType {
  byte pwmPin;
  byte inPin1;
  byte inPin2;
  void init(byte pwm, byte in1, byte in2) {
    pwmPin = pwm;
    inPin1 = in1;
    inPin2 = in2;
    pinMode(inPin1, OUTPUT);
    pinMode(inPin2, OUTPUT);
    stop();
  }
  void setDirection(byte in1, byte in2) {
    digitalWrite(inPin1, in1);
    digitalWrite(inPin2, in2);
  }
  void stop() {
    digitalWrite(inPin1, LOW);
    digitalWrite(inPin1, LOW);
    speed(0);
  }
  void speed(int aSpeed) {
    if (aSpeed >= 0) {
      analogWrite(pwmPin, aSpeed);
    }
  }
  // The following functions are not used here
  // but could be useful in future
  void forward() {
    digitalWrite(inPin1, HIGH);
    digitalWrite(inPin1, LOW);
  }
  void back() {
    digitalWrite(inPin1, LOW);
    digitalWrite(inPin1, HIGH);
  }
};

motorType prtMotor;
motorType stbdMotor;
motorType vertMotor;



//Joystick input values
int X_Voltage  = 0; //Port/Starboard Joystick input value
int Y_Voltage = 0;  //Forward/Reverse Joystick input value
int Z_Voltage = 0;  //Vertical Joystick input value
int SL_Voltage = 0; // XY Joystick Slew value

int Z_Rows = 5; //Max Number of Rows in Z Joystick Array
int Z_Columns = 4; //Max Number of Columns in Z Joystick Array

int X_Count = 0; // Used to access X_Voltage data in XY_Joystick_Array
int Y_Count = 0; // Used to access Y_Voltage date in XY_Joystick_Array
int XY_Columns = 7; //Used to access Columns in XY_Joystick_Array
int XY_Rows = 9; // Number of Rows in XY Joystick Array

int SL_Count = 0; //Used to access Slew Voltage in SL_Array
int SL_Rows = 5; //Number of rows in the SL_Array

int oldX = 2, oldY = 2, oldZ = 2, oldSL = 2; //Variable for storing the old voltages returned from the joysticks. Initialized at centre voltage = 2V

// Array for decoding Z Axis Joystick values - Z_Voltage, In3, In4, PWM
int Z_Joystick_Array[5][4] = {
  {0, 0, 1, 255}, //Joystick full down - motor down at PWM 100%
  {1, 0, 1, 127}, //Joystick half down - motor down at PWM 50%
  {2, 0, 0, 0},  //Joystick in middle, motor stopped, PWM 0
  {3, 1, 0, 127}, //Joystick half up - motor up at PWM 50%
  {4, 1, 0, 255} //Joystick full up - motor up at 100%
};

//Array for decoded XY joystick - X_Voltage, Y_Voltage, In1, In2, PWM1, In3, In4, PWM2
int XY_Joystick_Array[9][8] = {
  {2, 4, 1, 0, 255, 1, 0, 255}, // Both Motors forward at PWM 100%
  {2, 0, 0, 1, 255, 0, 1, 255}, //Both Motors Reverse at PWM 100%
  {2, 2, 0, 0, 0, 0, 0, 0}, // Both Motors stopped
  {4, 2, 1, 0, 255, 0, 0, 0}, // Right/starboard - Port Motor forward PWM 100%, Starboard Motor stopped
  {0, 2, 0, 0, 0, 1, 0, 255}, // Left/Port - Starboard Motor forward PWM 100%, Port Motor stopped
  {4, 4, 1, 0, 255, 1, 0, 255}, //Right/Starboard Forward - Port Motor Forward PWM 100%, Starboard Motor Reverse PWM 50%
  {4, 0, 0, 1, 255, 0, 1, 255}, //Right/Starboard Reverse - Port Motor Reverse PWM 100%, Starboard Motor Forward PWM 50%
  {0, 0, 0, 1, 127, 0, 1, 255}, //Left/Port Reverse - Port Motor Reverse PWM 50%, Starboard Motor Reverse PWM 100%
  {0, 4, 1, 0, 127, 1, 0, 255}, //Left/Port Forwards - Starboard Motor Forward PWM 100%,Port Motor Forward PWM 50% 
};

//Array for slew voltage on XY Joystick - Slew Voltage, In1, In2, PWM1, In3, In4,PWM2
int SL_Array[4][7] = {
  {0, 1, 0, 255, 0, 1, 255}, //Slew to left/port - starboard motor forward 50%, port motor reverse 50%
  {1, 1, 0, 127, 0, 1, 127}, //Slew to left/port 50%- starboard motor forward 25%, port motor reverse 25%
  {3, 0, 1, 127, 1, 0, 127},//Slew to right/starboard 50% - port motor forward 25%, starboard motor reverse 25%
  {4, 0, 1, 255, 1, 0, 255}, //Slew to right/starboard - port motor forward 50%, starboard motor reverse 50%
};

#define X_Pin A0 //Joystick input Port/Starboard pin
#define Y_Pin A1 //Joystick input Forward/Reverse pin
#define Z_Pin A2 //Joystick input Vertical up/down pin
#define SL_Pin A3 //XY Joystick slew pin

// function to return a scaled value of 0-5V from the analogue pins
int scaled_value(int adc, int scale_factor = 5) {
  constexpr int max_adc = 1023;
  int scaled = scale_factor * adc / max_adc;
  return scaled;
}
boolean Vert_joystickDataHaveChanged(int Z_Volts) {
  
  if (oldZ != Z_Volts)
  {
    oldZ = Z_Volts;
    return true;
  }
  return false;
}
boolean XY_joystickDataHaveChanged(int X_Volts, int Y_Volts) {
  
  if (oldX != X_Volts ||
      oldY != Y_Volts )
  {
    oldX = X_Volts;
    oldY = Y_Volts;
    return true;
  }
  return false;
}
boolean SL_joystickDataHaveChanged(int SL_Volts){
    if (oldSL != SL_Volts)
    {
      oldSL = SL_Volts;
      Serial.println("SL_Voltage ");
      Serial.print(SL_Volts);
      Serial.println("Old Voltage ");
      Serial.print(oldSL);
      return true;
    }
    return false;
    Serial.println("SL_Voltage ");
    Serial.print(SL_Volts);
    Serial.println("Old Voltage ");
    Serial.print(oldSL);
  }

void ControlVertMotor() {
  for (int Z_CountR = 0; Z_CountR < Z_Rows; Z_CountR++)
  {
    int Array_Voltage = 0;
    Array_Voltage = Z_Joystick_Array[Z_CountR][0];
    if (Z_Voltage == Array_Voltage)
    {
      int in1 = Z_Joystick_Array[Z_CountR][1];
      int in2 = Z_Joystick_Array[Z_CountR][2];
      int pwmValue = Z_Joystick_Array[Z_CountR][3];
      vertMotor.setDirection(in1, in2);
      vertMotor.speed(pwmValue);
      return;
    }
  }
}

void ControlPortStarbdMotors() {
  int X_Array_Voltage = 0;
    int Y_Array_Voltage = 0;
  for (int X_CountR = 0; X_CountR < XY_Rows; X_CountR++)
  {
    X_Array_Voltage = XY_Joystick_Array[X_CountR][0];
    Y_Array_Voltage = XY_Joystick_Array[X_CountR][1];
    if (X_Voltage == X_Array_Voltage && Y_Voltage == Y_Array_Voltage)
    {
      int in1 = XY_Joystick_Array[X_CountR][2];
      int in2 = XY_Joystick_Array[X_CountR][3];
      int pwmValue1 = XY_Joystick_Array[X_CountR][4];
      int in3 = XY_Joystick_Array[X_CountR][5];
      int in4 = XY_Joystick_Array[X_CountR][6];
      int pwmValue2 = XY_Joystick_Array[X_CountR][7]; 
      stbdMotor.setDirection(in1, in2);
      stbdMotor.speed(pwmValue1);
      prtMotor.setDirection(in3, in4);
      prtMotor.speed(pwmValue2);      
      return;
    } 
  }
}

void ControlPortStarbdMotors_Slew() {
  int SL_Array_Voltage = 0;
  for (SL_Count = 0; SL_Count < SL_Rows; SL_Count++)
  {
    SL_Array_Voltage = SL_Array[SL_Count][0];
    if (SL_Array_Voltage == SL_Voltage){
      int in1 = SL_Array[SL_Count][1];
      int in2 = SL_Array[SL_Count][2];
      int pwmValue1 = SL_Array[SL_Count][3];
      int in3 = SL_Array[SL_Count][4];
      int in4 = SL_Array[SL_Count][5];
      int pwmValue2 = SL_Array[SL_Count][6];
      stbdMotor.setDirection(in1, in2);
      stbdMotor.speed(pwmValue1);
      prtMotor.setDirection(in3, in4);
      prtMotor.speed(pwmValue2);
      Serial.print("SL Array Row: ");
        Serial.print(SL_Count);
        Serial.print("\tSL_Array Voltage: ");
        Serial.print(SL_Array_Voltage);
        Serial.print("\tPort In1: ");
        Serial.print(in1);
        Serial.print("\tPort In2: ");
        Serial.print(in2);
        Serial.print("\tPort PWM: ");
        Serial.println(pwmValue1);
        Serial.print("\tStarboard In3: ");
        Serial.print(in3);
        Serial.print("\tStarboard In4: ");
        Serial.print(in4);
        Serial.print("\tStarboard PWM: ");
        Serial.println(pwmValue2);
      return;
    }
  }
}

void setup() {

  //Enable Joystick inputs
  pinMode(X_Pin, INPUT); //Joystick X Input Pin
  pinMode(Y_Pin, INPUT); //Joystick Y Input Pin
  pinMode(Z_Pin, INPUT); //Input Z Joystick Pin
  pinMode(SL_Pin, INPUT); // XY Joystick Slew input Pin

  //Set Motors to stop -> now done in init()
  //Enable Port motor outputs
  prtMotor.init(prtPWMPin, prtIn1Pin, prtIn2Pin);

  //Enable Starboard Motor Outputs
  stbdMotor.init(stbdPWMPin, stbdIn3Pin, stbdIn4Pin);

  //Enable Vertical Motor Outputs
  vertMotor.init(vertPWMPin, vertIn3Pin, vertIn4Pin);

  //Enable Serial Output for Displaying values
  Serial.begin(9600);

}

void loop() {
  X_Voltage = scaled_value(X_Pin, 5);
  Y_Voltage = scaled_value(Y_Pin, 5);
  Z_Voltage = scaled_value(Z_Pin, 5);
  SL_Voltage = scaled_value(SL_Pin,5);
    if (Vert_joystickDataHaveChanged(Z_Voltage)) {
      ControlVertMotor();
    }
    if (XY_joystickDataHaveChanged(X_Voltage, Y_Voltage)) {
      ControlPortStarbdMotors();
    }
    if (SL_joystickDataHaveChanged(SL_Voltage)) {
      Serial.println("Slew Joystick Changed = ");
      Serial.print(SL_joystickDataHaveChanged(SL_Voltage));
      ControlPortStarbdMotors_Slew();
    }
}


I've just been alerted by she who must not be kept waiting, off to the beach soon.

But I do have time to say that your code is very probably doing exactly what you wrote, even if it doesn't yet do what you want.

Add serial printing at strategic points to check the values of key variables and verify the flow through your code.

Move

  //Enable Serial Output for Displaying values
  Serial.begin(9600);

to be the very first line in the setup() function, and start there. Between printing and putting you finger on the code playing dumb computer, you can figure this out.

void setup() {
  //Enable Serial Output for Displaying values
  Serial.begin(9600);
  Serial.println("I'm alive!");
  delay(777);

// rest of setup
}

a7

1 Like

The main issue of your code from post # 28 is that you call scaled_value() with an adc pin but you are not reading the pin:

int scaled_value(int adc, int scale_factor = 5) {
  constexpr int max_adc = 1023;
  int scaled = scale_factor * adc / max_adc;
  return scaled;
}

void loop(){
  X_Voltage = scaled_value(X_Pin, 5);
  Y_Voltage = scaled_value(Y_Pin, 5);
  Z_Voltage = scaled_value(Z_Pin, 5);
  SL_Voltage = scaled_value(SL_Pin,5);
  // ......
}

You did not get any analog values scaled and returned ... :wink:

A second issue which pops up while using the different slide potentiometers is that for the XY array not all combinations are defined:

int XY_Joystick_Array[noOfRowsXY][noOfColsXY] = {
  {0, 0, 0, 1, 127, 0, 1, 64}, //Right/Starboard Reverse - Port Motor Reverse PWM 50%, Starboard Motor Forward PWM 25%
  {0, 2, 1, 0, 127, 0, 0, 0}, // Right/starboard - Port Motor forward PWM 50%, Starboard Motor stopped
  {2, 0, 0, 1, 127, 0, 1, 127}, //Both Motors Reverse
  {2, 2, 0, 0, 0, 0, 0, 0}, // Both Motors stopped
  {2, 4, 1, 0, 127, 1, 0, 127}, // Both Motors forward
  {3, 1, 1, 0, 127, 1, 0, 64}, //Right/Starboard Forward - Port Motor Forward PWM 50%, Starboard Motor Reverse PWM 25%
  {4, 0, 0, 1, 64, 0, 1, 127}, //Left/Port Reverse - Port Motor Reverse PWM 25%, Starboard Motor Reverse PWM 50%
  {4, 2, 0, 0, 0, 1, 0, 127}, // Left/Port - Starboard Motor forward PWM 50%, Port Motor stopped
  {4, 4, 1, 0, 64, 1, 0, 127} //Left/Port Forwards - Starboard Motor Forward PWM 50%,Port Motor Forward PWM 25%
};

I sorted the array depending on the column 0 (X_Voltage) and then column 1(Y_Voltage).

  • If X_Voltage has a value of 1 or 5 any change of Y_Voltage has no effect.
  • If Y_Voltage has a value of 3 or 5 any change of X_Voltage has no effect.

Is that intended? I assume it could be confusing ...

Here is a sketch that still has this situation:

Sketch plus explanations ... hidden lines ...
/*
  Forum: https://forum.arduino.cc/t/digital-pins-output-pins-not-being-written-to/1188669/13
  Wokwi: https://wokwi.com/projects/382376927710728193
*/

#define DEBUGPRINTS

//Port Motor Pins
constexpr int prtPWMPin = 9; //Port Motor PWM
constexpr int prtIn1Pin = 8; //Port Motor In1
constexpr int prtIn2Pin = 7; //Port Motor In2

//Starboard Motor Pins
constexpr int stbdPWMPin = 6; //Starboard Motor PWM
constexpr int stbdIn3Pin = 5; //Starboard Motor In3
constexpr int stbdIn4Pin = 4; //Starboard Motor In4

//Vertical Motor Pins
constexpr int vertPWMPin = 10; //Vertical Motor PWM Pin
constexpr int vertIn3Pin = 12; //Vertical Motor In3 Pin
constexpr int vertIn4Pin = 11; //Vertical Motor In4 Pin



struct motorType {
  byte pwmPin;
  byte inPin1;
  byte inPin2;
  void init(byte pwm, byte in1, byte in2) {
    pwmPin = pwm;
    inPin1 = in1;
    inPin2 = in2;
    pinMode(inPin1, OUTPUT);
    pinMode(inPin2, OUTPUT);
    stop();
  }
  void setDirection(byte in1, byte in2) {
    digitalWrite(inPin1, in1);
    digitalWrite(inPin2, in2);
  }
  void stop() {
    digitalWrite(inPin1, LOW);
    digitalWrite(inPin1, LOW);
    speed(0);
  }
  void speed(int aSpeed) {
    if (aSpeed >= 0) {
      analogWrite(pwmPin, aSpeed);
    }
  }
  // The following functions are not used here
  // but could be useful in future
  void forward() {
    digitalWrite(inPin1, HIGH);
    digitalWrite(inPin1, LOW);
  }
  void back() {
    digitalWrite(inPin1, LOW);
    digitalWrite(inPin1, HIGH);
  }
};

motorType prtMotor;
motorType stbdMotor;
motorType vertMotor;


// Array for decoding Z Axis Joystick values - Z_Voltage, In3, In4, PWM
constexpr int noOfRowsZ {5};
constexpr int noOfRColsZ {4};
int Z_Joystick_Array[noOfRowsZ][noOfRColsZ] = {
  {0, 0, 1, 127}, //Joystick full down - motor down at PWM 50%
  {1, 0, 1, 64}, //Joystick half down - motor down at PWM 25%
  {2, 0, 0, 0},  //Joystick in middle, motor stopped, PWM 0
  {3, 1, 0, 64}, //Joystick half up - motor up at PWM 25%
  {4, 1, 0, 127} //Joystick full up - motor up at 50%
};

//Array for decoded XY joystick - X_Voltage, Y_Voltage, In1, In2, PWM1, In3, In4, PWM2
constexpr int noOfRowsXY {9};
constexpr int noOfColsXY {8};
int XY_Joystick_Array[noOfRowsXY][noOfColsXY] = {
  {0, 0, 0, 1, 127, 0, 1, 64}, //Right/Starboard Reverse - Port Motor Reverse PWM 50%, Starboard Motor Forward PWM 25%
  {0, 2, 1, 0, 127, 0, 0, 0}, // Right/starboard - Port Motor forward PWM 50%, Starboard Motor stopped
  {2, 0, 0, 1, 127, 0, 1, 127}, //Both Motors Reverse
  {2, 2, 0, 0, 0, 0, 0, 0}, // Both Motors stopped
  {2, 4, 1, 0, 127, 1, 0, 127}, // Both Motors forward
  {3, 1, 1, 0, 127, 1, 0, 64}, //Right/Starboard Forward - Port Motor Forward PWM 50%, Starboard Motor Reverse PWM 25%
  {4, 0, 0, 1, 64, 0, 1, 127}, //Left/Port Reverse - Port Motor Reverse PWM 25%, Starboard Motor Reverse PWM 50%
  {4, 2, 0, 0, 0, 1, 0, 127}, // Left/Port - Starboard Motor forward PWM 50%, Port Motor stopped
  {4, 4, 1, 0, 64, 1, 0, 127} //Left/Port Forwards - Starboard Motor Forward PWM 50%,Port Motor Forward PWM 25%
};

//Array for slew voltage on XY Joystick - Slew Voltage, In1, In2, PWM1, In3, In4,PWM2
constexpr int noOfRowsSL {4};
constexpr int noOfColsSL {7};

int SL_Array[noOfRowsSL][noOfColsSL] = {
  {0, 1, 0, 255, 0, 1, 255}, //Slew to left/port - starboard motor forward 50%, port motor reverse 50%
  {1, 1, 0, 127, 0, 1, 127}, //Slew to left/port 50%- starboard motor forward 25%, port motor reverse 25%
  {3, 0, 1, 127, 1, 0, 127},//Slew to right/starboard 50% - port motor forward 25%, starboard motor reverse 25%
  {4, 0, 1, 255, 1, 0, 255}, //Slew to right/starboard - port motor forward 50%, starboard motor reverse 50%
};

constexpr byte X_Pin  {A0}; //Joystick input Port/Starboard pin
constexpr byte Y_Pin  {A1}; //Joystick input Forward/Reverse pin
constexpr byte Z_Pin  {A2}; //Joystick input Vertical up/down pin
constexpr byte SL_Pin {A3}; //XY Joystick slew pin

//Joystick input values
int X_Voltage = 0;  //Port/Starboard Joystick input value
int Y_Voltage = 0;  //Forward/Reverse Joystick input value
int Z_Voltage = 0;  //Vertical Joystick input value
int SL_Voltage = 0; // XY Joystick Slew value

int oldX  = 2;
int oldY  = 2;
int oldZ  = 2;
int oldSL = 2;

// function to return a scaled value of 0-5V from the analogue pins
int scaled_value(int adc, int scale_factor = 5) {
  constexpr int max_adc = 1024;   // Changed from 1023 to 1024 so that the range
                                  // is from 0..4 instead of 0..5 !
  int scaled = scale_factor * adc / max_adc;
  return scaled;
}

void setup() {
  //Enable Serial Output for Displaying values
  Serial.begin(115200);
#ifdef DEBUGPRINTS  
  Serial.println("Debug prints ON!");
#endif

  //Enable Joystick inputs
  pinMode(X_Pin, INPUT); //Joystick X Input Pin
  pinMode(Y_Pin, INPUT); //Joystick Y Input Pin
  pinMode(Z_Pin, INPUT); //Input Z Joystick Pin
  pinMode(SL_Pin, INPUT); // XY Joystick Slew input Pin

  //Set Motors to stop -> now done in init()
  //Enable Port motor outputs
  prtMotor.init(prtPWMPin, prtIn1Pin, prtIn2Pin);

  //Enable Starboard Motor Outputs
  stbdMotor.init(stbdPWMPin, stbdIn3Pin, stbdIn4Pin);

  //Enable Vertical Motor Outputs
  vertMotor.init(vertPWMPin, vertIn3Pin, vertIn4Pin);
}


void loop() {
  if (Vert_joystickDataHaveChanged()) {
    ControlVertMotor();
  }
  if (XY_joystickDataHaveChanged()) {
    ControlPortStarbdMotor();
  }
  if (SL_joystickDataHaveChanged()) {
    ControlPortStarbdMotors_Slew();
  }
}

boolean Vert_joystickDataHaveChanged() {
  Z_Voltage = scaled_value(analogRead(Z_Pin), 5);
  if (oldZ != Z_Voltage)
  {
    oldZ = Z_Voltage;
    return true;
  }
  return false;
}

boolean XY_joystickDataHaveChanged() {
  X_Voltage = scaled_value(analogRead(X_Pin), 5);
  Y_Voltage = scaled_value(analogRead(Y_Pin), 5);

  if (oldX != X_Voltage ||
      oldY != Y_Voltage )
  {
    oldX = X_Voltage;
    oldY = Y_Voltage;
    return true;
  }
  return false;
}

boolean SL_joystickDataHaveChanged() {
  SL_Voltage = scaled_value(analogRead(SL_Pin), 5);
  if (oldSL != SL_Voltage)
  {
    oldSL = SL_Voltage;
    return true;
  }
  return false;
}

void ControlVertMotor() {
  for (int Z_CountR = 0; Z_CountR < noOfRowsZ; Z_CountR++)
  {
    if (Z_Voltage == Z_Joystick_Array[Z_CountR][0])
    {
      int in1 = Z_Joystick_Array[Z_CountR][1];
      int in2 = Z_Joystick_Array[Z_CountR][2];
      int pwmValue = Z_Joystick_Array[Z_CountR][3];
      vertMotor.setDirection(in1, in2);
      vertMotor.speed(pwmValue);
#ifdef DEBUGPRINTS  
      Serial.print("VertMotor found for voltage ");
      Serial.print(Z_Voltage);
      Serial.print("\t in row ");
      Serial.println(Z_CountR);
#endif       
      return;
    }
  }
#ifdef DEBUGPRINTS  
      Serial.print("VertMotor NOT found for voltage ");
      Serial.println(Z_Voltage);
#endif       
}

void ControlPortStarbdMotor() {
  boolean complete = false;
  boolean found    = false;
  int X = 0;
  int row = -1;
  while (!complete && !found) {
    if (XY_Joystick_Array[X][0] == X_Voltage &&
        XY_Joystick_Array[X][1] == Y_Voltage) {
      found = true;
      row = X;
    }
    X++;
    complete = (X >= noOfRowsXY);
  }
  if (found) {
#ifdef DEBUGPRINTS  
    Serial.print("Starbd Ctrl found for voltage X,Y = ");
    Serial.print(X_Voltage);
    Serial.print(",");
    Serial.print(Y_Voltage);
    Serial.print("\tin row ");
    Serial.println(row);
#endif    
    setPortStarbdMotor(row);
  } else {
#ifdef DEBUGPRINTS  
    Serial.print("Starbd Ctrl NOT found for voltage X,Y = ");
    Serial.print(X_Voltage);
    Serial.print(",");
    Serial.println(Y_Voltage);
#endif     
  }

}

void setPortStarbdMotor(int row) {
  int in1       = XY_Joystick_Array[row][2];
  int in2       = XY_Joystick_Array[row][3];
  int pwmValue1 = XY_Joystick_Array[row][4];
  int in3       = XY_Joystick_Array[row][5];
  int in4       = XY_Joystick_Array[row][6];
  int pwmValue2 = XY_Joystick_Array[row][7];
  stbdMotor.setDirection(in1, in2);
  stbdMotor.speed(pwmValue1);
  prtMotor.setDirection(in3, in4);
  prtMotor.speed(pwmValue2);
}

void ControlPortStarbdMotors_Slew() {
  for (int SL_Count = 0; SL_Count < noOfRowsSL; SL_Count++)
  {
    if (SL_Array[SL_Count][0] == SL_Voltage) {
#ifdef DEBUGPRINTS  
      Serial.print("Starbd Slew found for voltage ");
      Serial.print(SL_Voltage);
      Serial.print("\t in row ");
      Serial.println(SL_Count);
#endif    
      setPortStarbdMotors_Slew(SL_Count);
      return;
    }
  }
#ifdef DEBUGPRINTS    
      Serial.print("Starbd Slew NOT found for voltage ");
      Serial.println(SL_Voltage);
#endif      
}

void setPortStarbdMotors_Slew(int row) {
  int in1       = SL_Array[row][1];
  int in2       = SL_Array[row][2];
  int pwmValue1 = SL_Array[row][3];
  int in3       = SL_Array[row][4];
  int in4       = SL_Array[row][5];
  int pwmValue2 = SL_Array[row][6];
  stbdMotor.setDirection(in1, in2);
  stbdMotor.speed(pwmValue1);
  prtMotor.setDirection(in3, in4);
  prtMotor.speed(pwmValue2);
}

You may check it out on Wokwi again: Joystick Motor Control II

If I have some time I'll have a look at the last issue mentioned ...

Just to show what I mean, here for scaled values 0..5.

For the green marked fields values are defined, the gray fields are undefined = no effect:

image

If 5x5 is enough it looks like this

image

It might be helpful to refine your user interface here ... What do you think?

After trying to understand the logic of your joystick use I finally ended up with a sketch that uses only 3x3 data for the XY control.

Explanations and sketch

If I did not make too many mistakes this should be the use of XY voltage to speed/dir of the motors
image

I mapped that to a 3x3 matrix:

image

and created an array where we can address the correct data just by calculating

X_Voltage + Y_Voltage * 3

I also removed some errors in (unused) functions of the struct.

/*
  Forum: https://forum.arduino.cc/t/digital-pins-output-pins-not-being-written-to/1188669/13
  Wokwi: https://wokwi.com/projects/382382229268352001
*/

#define DEBUGPRINTS

//Port Motor Pins
constexpr int prtPWMPin = 9; //Port Motor PWM
constexpr int prtIn1Pin = 8; //Port Motor In1
constexpr int prtIn2Pin = 7; //Port Motor In2

//Starboard Motor Pins
constexpr int stbdPWMPin = 6; //Starboard Motor PWM
constexpr int stbdIn3Pin = 5; //Starboard Motor In3
constexpr int stbdIn4Pin = 4; //Starboard Motor In4

//Vertical Motor Pins
constexpr int vertPWMPin = 10; //Vertical Motor PWM Pin
constexpr int vertIn3Pin = 12; //Vertical Motor In3 Pin
constexpr int vertIn4Pin = 11; //Vertical Motor In4 Pin


constexpr byte FWD {0};
constexpr byte RVS {1};
constexpr byte STOP {2};

struct motorType {
  byte pwmPin;
  byte inPin1;
  byte inPin2;
  void init(byte pwm, byte in1, byte in2) {
    pwmPin = pwm;
    inPin1 = in1;
    inPin2 = in2;
    pinMode(inPin1, OUTPUT);
    pinMode(inPin2, OUTPUT);
    stop();
  }
  void setDirection(byte in1, byte in2) {
    digitalWrite(inPin1, in1);
    digitalWrite(inPin2, in2);
  }
  void stop() {
    digitalWrite(inPin1, LOW);
    digitalWrite(inPin2, LOW);
    speed(0);
  }
  void speed(int aSpeed) {
    if (aSpeed >= 0) {
      analogWrite(pwmPin, aSpeed);
    }
  }
  void forward() {
    digitalWrite(inPin1, HIGH);
    digitalWrite(inPin2, LOW);
  }
  void back() {
    digitalWrite(inPin1, LOW);
    digitalWrite(inPin2, HIGH);
  }
  void setDirSpeed(byte direction, int aSpeed) {
    switch (direction) {
      case FWD :
        forward();
        break;
      case RVS :
        back();
        break;
      case STOP :
        stop();
        aSpeed = 0;
        break;
    }
    speed(aSpeed);
  }
};

motorType prtMotor;
motorType stbdMotor;
motorType vertMotor;


// Array for decoding Z Axis Joystick values - Z_Voltage, In3, In4, PWM
constexpr int noOfRowsZ {5};
constexpr int noOfRColsZ {4};
int Z_Joystick_Array[noOfRowsZ][noOfRColsZ] = {
  {0, 0, 1, 127}, //Joystick full down - motor down at PWM 50%
  {1, 0, 1, 64}, //Joystick half down - motor down at PWM 25%
  {2, 0, 0, 0},  //Joystick in middle, motor stopped, PWM 0
  {3, 1, 0, 64}, //Joystick half up - motor up at PWM 25%
  {4, 1, 0, 127} //Joystick full up - motor up at 50%
};

//Array for decoded XY joystick - X_Voltage, Y_Voltage, In1, In2, PWM1, In3, In4, PWM2
constexpr int scaleXYMax = {3};
constexpr int noOfEntries {scaleXYMax * scaleXYMax};

int XY_MotorCtrl[noOfEntries][4] = {

  {RVS, 127, RVS, 64},
  {RVS, 127, RVS, 127},
  {RVS,  64, RVS, 127},

  {FWD,  127, STOP, 0},
  {STOP,   0, STOP, 0},
  {STOP,   0, RVS, 127},

  {FWD,  127, FWD, 64},
  {FWD,  127, FWD, 127},
  {FWD,   64, FWD, 127}

};

//Array for slew voltage on XY Joystick - Slew Voltage, In1, In2, PWM1, In3, In4,PWM2
constexpr int noOfRowsSL {5};
constexpr int noOfColsSL {7};

int SL_Array[noOfRowsSL][noOfColsSL] = {
  {0, 1, 0, 255, 0, 1, 255}, //Slew to left/port - starboard motor forward 50%, port motor reverse 50%
  {1, 1, 0, 127, 0, 1, 127}, //Slew to left/port 50%- starboard motor forward 25%, port motor reverse 25%
  {2, 0, 0, 0, 0, 0, 0},     //Stop both motors
  {3, 0, 1, 127, 1, 0, 127},//Slew to right/starboard 50% - port motor forward 25%, starboard motor reverse 25%
  {4, 0, 1, 255, 1, 0, 255}, //Slew to right/starboard - port motor forward 50%, starboard motor reverse 50%
};

constexpr byte X_Pin  {A0}; //Joystick input Port/Starboard pin
constexpr byte Y_Pin  {A1}; //Joystick input Forward/Reverse pin
constexpr byte Z_Pin  {A2}; //Joystick input Vertical up/down pin
constexpr byte SL_Pin {A3}; //XY Joystick slew pin

//Joystick input values
int X_Voltage = 0;  //Port/Starboard Joystick input value
int Y_Voltage = 0;  //Forward/Reverse Joystick input value
int Z_Voltage = 0;  //Vertical Joystick input value
int SL_Voltage = 0; // XY Joystick Slew value

int oldX  = 1;
int oldY  = 1;
int oldZ  = 2;
int oldSL = 2;

// function to return a scaled value of 0-5V from the analogue pins
int scaled_value(int adc, int scale_factor = 5) {
  constexpr int max_adc = 1024;   // Changed from 1023 to 1024 so that the range
  // is from 0..4 instead of 0..5 !
  int scaled = scale_factor * adc / max_adc;
  return scaled;
}

void setup() {
  //Enable Serial Output for Displaying values
  Serial.begin(115200);
#ifdef DEBUGPRINTS
  Serial.println("Debug prints ON!");
#endif

  //Enable Joystick inputs
  pinMode(X_Pin, INPUT); //Joystick X Input Pin
  pinMode(Y_Pin, INPUT); //Joystick Y Input Pin
  pinMode(Z_Pin, INPUT); //Input Z Joystick Pin
  pinMode(SL_Pin, INPUT); // XY Joystick Slew input Pin

  //Set Motors to stop -> now done in init()
  //Enable Port motor outputs
  prtMotor.init(prtPWMPin, prtIn1Pin, prtIn2Pin);

  //Enable Starboard Motor Outputs
  stbdMotor.init(stbdPWMPin, stbdIn3Pin, stbdIn4Pin);

  //Enable Vertical Motor Outputs
  vertMotor.init(vertPWMPin, vertIn3Pin, vertIn4Pin);
}


void loop() {
  if (Vert_joystickDataHaveChanged()) {
    ControlVertMotor();
  }
  if (XY_joystickDataHaveChanged()) {
    ControlPortStarbdMotor();
  }
  if (SL_joystickDataHaveChanged()) {
    ControlPortStarbdMotors_Slew();
  }
}

boolean Vert_joystickDataHaveChanged() {
  Z_Voltage = scaled_value(analogRead(Z_Pin), 5);
  if (oldZ != Z_Voltage)
  {
    oldZ = Z_Voltage;
    return true;
  }
  return false;
}

boolean XY_joystickDataHaveChanged() {
  X_Voltage = scaled_value(analogRead(X_Pin), scaleXYMax);
  Y_Voltage = scaled_value(analogRead(Y_Pin), scaleXYMax);

  if (oldX != X_Voltage ||
      oldY != Y_Voltage )
  {
    oldX = X_Voltage;
    oldY = Y_Voltage;
    return true;
  }
  return false;
}

boolean SL_joystickDataHaveChanged() {
  SL_Voltage = scaled_value(analogRead(SL_Pin), 5);
  if (oldSL != SL_Voltage)
  {
    oldSL = SL_Voltage;
    return true;
  }
  return false;
}

void ControlVertMotor() {
  for (int Z_CountR = 0; Z_CountR < noOfRowsZ; Z_CountR++)
  {
    if (Z_Voltage == Z_Joystick_Array[Z_CountR][0])
    {
      int in1 = Z_Joystick_Array[Z_CountR][1];
      int in2 = Z_Joystick_Array[Z_CountR][2];
      int pwmValue = Z_Joystick_Array[Z_CountR][3];
      vertMotor.setDirection(in1, in2);
      vertMotor.speed(pwmValue);
#ifdef DEBUGPRINTS
      Serial.print("VertMotor found for voltage ");
      Serial.print(Z_Voltage);
      Serial.print("\t in row ");
      Serial.println(Z_CountR);
#endif
      return;
    }
  }
#ifdef DEBUGPRINTS
  Serial.print("VertMotor NOT found for voltage ");
  Serial.println(Z_Voltage);
#endif
}

void ControlPortStarbdMotor() {
  int row = X_Voltage + Y_Voltage * scaleXYMax;

#ifdef DEBUGPRINTS
  Serial.print("Starbd Ctrl found for voltage X,Y = ");
  Serial.print(X_Voltage);
  Serial.print(",");
  Serial.print(Y_Voltage);
  Serial.print("\tin row ");
  Serial.println(row);
#endif

  setPortStarbdMotor(row);
}


void setPortStarbdMotor(int row) {
  //XY_MotorCtrl[row];
  int dir1       = XY_MotorCtrl[row][0];
  int pwmValue1  = XY_MotorCtrl[row][1];
  int dir2       = XY_MotorCtrl[row][2];
  int pwmValue2  = XY_MotorCtrl[row][3];
  stbdMotor.setDirSpeed(dir1, pwmValue1);
  prtMotor.setDirSpeed(dir2, pwmValue2);
}

void ControlPortStarbdMotors_Slew() {
  for (int SL_Count = 0; SL_Count < noOfRowsSL; SL_Count++)
  {
    if (SL_Array[SL_Count][0] == SL_Voltage) {
#ifdef DEBUGPRINTS
      Serial.print("Starbd Slew found for voltage ");
      Serial.print(SL_Voltage);
      Serial.print("\t in row ");
      Serial.println(SL_Count);
#endif
      setPortStarbdMotors_Slew(SL_Count);
      return;
    }
  }
#ifdef DEBUGPRINTS
  Serial.print("Starbd Slew NOT found for voltage ");
  Serial.println(SL_Voltage);
#endif
}

void setPortStarbdMotors_Slew(int row) {
  int in1       = SL_Array[row][1];
  int in2       = SL_Array[row][2];
  int pwmValue1 = SL_Array[row][3];
  int in3       = SL_Array[row][4];
  int in4       = SL_Array[row][5];
  int pwmValue2 = SL_Array[row][6];
  stbdMotor.setDirection(in1, in2);
  stbdMotor.speed(pwmValue1);
  prtMotor.setDirection(in3, in4);
  prtMotor.speed(pwmValue2);
}

Wiring:

To be tested here Joystick Motor Control III - Wokwi ESP32, STM32, Arduino Simulator

Might be it does not directly match your needs but it should be a good start ...

Hi Everyone,

I managed to get it working.

I have changed it so that there are only 2 arrays - one for the XY joystick and the other for the Z joystick. When I thought about it, it seemed a bit of overkill to have the third array for the Slew Voltage. So I added another column to the XY Array for the Slew Voltage, plus a few more lines in the array to include the Slow Voltage conditions.

So now it is working. Now to try it on the vehicle and get it wet.

Progress........

//Port Motor Pins
constexpr int prtPWMPin = 9; //Port Motor PWM
constexpr int prtIn1Pin = 8; //Port Motor In1
constexpr int prtIn2Pin = 7; //Port Motor In2

//Starboard Motor Pins
constexpr int stbdPWMPin = 6; //Starboard Motor PWM
constexpr int stbdIn3Pin = 5; //Starboard Motor In3
constexpr int stbdIn4Pin = 4; //Starboard Motor In4

//Vertical Motor Pins
constexpr int vertPWMPin = 10; //Vertical Motor PWM Pin
constexpr int vertIn3Pin = 12; //Vertical Motor In3 Pin
constexpr int vertIn4Pin = 11; //Vertical Motor In4 Pin

struct motorType {
  byte pwmPin;
  byte inPin1;
  byte inPin2;
  void init(byte pwm, byte in1, byte in2) {
    pwmPin = pwm;
    inPin1 = in1;
    inPin2 = in2;
    pinMode(inPin1, OUTPUT);
    pinMode(inPin2, OUTPUT);
    stop();
  }
  void setDirection(byte in1, byte in2) {
    digitalWrite(inPin1, in1);
    digitalWrite(inPin2, in2);
  }
  void stop() {
    digitalWrite(inPin1, LOW);
    digitalWrite(inPin1, LOW);
    speed(0);
  }
  void speed(int aSpeed) {
    if (aSpeed >= 0) {
      analogWrite(pwmPin, aSpeed);
    }
  }
  // The following functions are not used here
  // but could be useful in future
  void forward() {
    digitalWrite(inPin1, HIGH);
    digitalWrite(inPin1, LOW);
  }
  void back() {
    digitalWrite(inPin1, LOW);
    digitalWrite(inPin1, HIGH);
  }
};

motorType prtMotor;
motorType stbdMotor;
motorType vertMotor;



//Joystick input values
int X_Voltage  = 0; //Port/Starboard Joystick input value
int Y_Voltage = 0;  //Forward/Reverse Joystick input value
int Z_Voltage = 0;  //Vertical Joystick input value
int SL_Voltage = 0; // XY Joystick Slew value

constexpr int Z_Rows = 5; //Max Number of Rows in Z Joystick Array
constexpr int Z_Columns = 4; //Max Number of Columns in Z Joystick Array

int X_Count = 0; // Used to access X_Voltage data in XY_Joystick_Array
int Y_Count = 0; // Used to access Y_Voltage date in XY_Joystick_Array
constexpr int XY_Columns = 9; //Used to access Columns in XY_Joystick_Array
constexpr int XY_Rows = 13; // Number of Rows in XY Joystick Array

int SL_Count = 0; //Used to access Slew Voltage in SL_Array
constexpr int SL_Rows = 4; //Number of rows in the SL_Array
constexpr int SL_Columns = 7; //Number of colums in the SL Array

int oldX = 2, oldY = 2, oldZ = 2, oldSL = 2; //Variable for storing the old voltages returned from the joysticks. Initialized at centre voltage = 2V

// Array for decoding Z Axis Joystick values - Z_Voltage, In3, In4, PWM

int Z_Joystick_Array[Z_Rows][Z_Columns] = {
  {0, 0, 1, 255}, //Joystick full down - motor down at PWM 100%
  {1, 0, 1, 127}, //Joystick half down - motor down at PWM 50%
  {2, 0, 0, 0},  //Joystick in middle, motor stopped, PWM 0
  {3, 1, 0, 127}, //Joystick half up - motor up at PWM 50%
  {4, 1, 0, 255} //Joystick full up - motor up at 100%
};

//Array for decoded XY joystick - X_Voltage, Y_Voltage, SL_Voltage In1, In2, PWM1, In3, In4, PWM2
int XY_Joystick_Array[XY_Rows][XY_Columns] = {
  {2, 4, 2, 1, 0, 255, 1, 0, 255}, // Both Motors forward at PWM 100%
  {2, 0, 2, 0, 1, 255, 0, 1, 255}, //Both Motors Reverse at PWM 100%
  {2, 2, 2, 0, 0, 0, 0, 0, 0}, // Both Motors stopped
  {4, 2, 2, 1, 0, 255, 0, 0, 0}, // Right/starboard - Port Motor forward PWM 100%, Starboard Motor stopped
  {0, 2, 2, 0, 0, 0, 1, 0, 255}, // Left/Port - Starboard Motor forward PWM 100%, Port Motor stopped
  {4, 4, 2, 1, 0, 255, 1, 0, 255}, //Right/Starboard Forward - Port Motor Forward PWM 100%, Starboard Motor Reverse PWM 50%
  {4, 0, 2, 0, 1, 255, 0, 1, 255}, //Right/Starboard Reverse - Port Motor Reverse PWM 100%, Starboard Motor Forward PWM 50%
  {0, 0, 2, 0, 1, 127, 0, 1, 255}, //Left/Port Reverse - Port Motor Reverse PWM 50%, Starboard Motor Reverse PWM 100%
  {0, 4, 2, 1, 0, 127, 1, 0, 255}, //Left/Port Forwards - Starboard Motor Forward PWM 100%,Port Motor Forward PWM 50% 
  {2, 2, 0, 0, 1, 255, 0, 1, 255}, // Slew to left/port - starboard motor forward 100%, port motor reverse 100% 
  {2, 2, 1, 1, 0, 127, 0, 1, 127}, //Slew to left/port 50%- starboard motor forward 50%, port motor reverse 50%
  {2, 2, 3, 0, 1, 127, 1, 0, 127}, //Slew to right/starboard 50% - port motor forward 50%, starboard motor reverse 50%
  {2, 2, 4, 0, 1, 255, 1, 0, 255}, //Slew to right/starboard - port motor forward 50%, starboard motor reverse 50%
};

#define X_Pin A0 //Joystick input Port/Starboard pin
#define Y_Pin A1 //Joystick input Forward/Reverse pin
#define Z_Pin A2 //Joystick input Vertical up/down pin
#define SL_Pin A3 //XY Joystick slew pin

// function to return a scaled value of 0-5V from the analogue pins
int scaled_value(int pin, int scale_factor = 5) {
  constexpr int max_adc = 1023;
  int scaled = scale_factor * analogRead(pin) / max_adc;
  return scaled;
}
boolean Vert_joystickDataHaveChanged(int Z_Volts) {
  
  if (oldZ != Z_Volts)
  {
    oldZ = Z_Volts;
    return true;
  }
  return false;
}
boolean XY_joystickDataHaveChanged(int X_Volts, int Y_Volts, int SL_Volts) {
  
  if (oldX != X_Volts ||
      oldY != Y_Volts || oldSL != SL_Volts)
  {
    oldX = X_Volts;
    oldY = Y_Volts;
    oldSL = SL_Volts;
    return true;
  }
  return false;
}


void ControlVertMotor() {
  for (int Z_CountR = 0; Z_CountR < Z_Rows; Z_CountR++)
  {
    int Array_Voltage = 0;
    Array_Voltage = Z_Joystick_Array[Z_CountR][0];
    if (Z_Voltage == Array_Voltage)
    {
      int in1 = Z_Joystick_Array[Z_CountR][1];
      int in2 = Z_Joystick_Array[Z_CountR][2];
      int pwmValue = Z_Joystick_Array[Z_CountR][3];
      vertMotor.setDirection(in1, in2);
      vertMotor.speed(pwmValue);
      return;
    }
  }
}

void ControlPortStarbdMotors() {
  int X_Array_Voltage = 0;
    int Y_Array_Voltage = 0;
    int SL_Array_Voltage = 0;
  for (int X_CountR = 0; X_CountR < XY_Rows; X_CountR++)
  {
    X_Array_Voltage = XY_Joystick_Array[X_CountR][0];
    Y_Array_Voltage = XY_Joystick_Array[X_CountR][1];
    SL_Array_Voltage = XY_Joystick_Array[X_CountR][2];
    if (X_Voltage == X_Array_Voltage && Y_Voltage == Y_Array_Voltage && SL_Voltage == SL_Array_Voltage)
    {
      int in1 = XY_Joystick_Array[X_CountR][3];
      int in2 = XY_Joystick_Array[X_CountR][4];
      int pwmValue1 = XY_Joystick_Array[X_CountR][5];
      int in3 = XY_Joystick_Array[X_CountR][6];
      int in4 = XY_Joystick_Array[X_CountR][7];
      int pwmValue2 = XY_Joystick_Array[X_CountR][8]; 
      stbdMotor.setDirection(in1, in2);
      stbdMotor.speed(pwmValue1);
      prtMotor.setDirection(in3, in4);
      prtMotor.speed(pwmValue2);      
      return;
    } 
  }
}

void setup() {

  //Enable Serial Output for Displaying values
  Serial.begin(9600);
  Serial.println("Initialising.....");
  //Enable Joystick inputs
  pinMode(X_Pin, INPUT); //Joystick X Input Pin
  pinMode(Y_Pin, INPUT); //Joystick Y Input Pin
  pinMode(Z_Pin, INPUT); //Input Z Joystick Pin
  pinMode(SL_Pin, INPUT); // XY Joystick Slew input Pin

  //Set Motors to stop -> now done in init()
  //Enable Port motor outputs
  prtMotor.init(prtPWMPin, prtIn1Pin, prtIn2Pin);

  //Enable Starboard Motor Outputs
  stbdMotor.init(stbdPWMPin, stbdIn3Pin, stbdIn4Pin);

  //Enable Vertical Motor Outputs
  vertMotor.init(vertPWMPin, vertIn3Pin, vertIn4Pin);
}

void loop() {
  X_Voltage = scaled_value(X_Pin, 5);
  Y_Voltage = scaled_value(Y_Pin, 5);
  Z_Voltage = scaled_value(Z_Pin, 5);
  SL_Voltage = scaled_value(SL_Pin,5);
    if (Vert_joystickDataHaveChanged(Z_Voltage)) {
      ControlVertMotor();
    }
    if (XY_joystickDataHaveChanged(X_Voltage, Y_Voltage, SL_Voltage)) {
      ControlPortStarbdMotors();
    }
}


So, I have continued to work on this project.

I have added real values instead of the integers for the joystick voltages and used them to calculate PWM values.

I have also added a calibration routine for the X-Y joystick. I was using hard coded constants for the Max and Mins, but they tended to fluctuate too much so that I would have to input new values every time.

What is happening now, is that despite taking the average of 100 values, the max and min values for x and y appear to be overwritten. and I cannot seem to find out why.

Code is below;-


//Port Motor Pins
constexpr int prtPWMPin = 6; //Port Motor PWM
constexpr int prtIn1Pin = 5; //Port Motor In1
constexpr int prtIn2Pin = 7; //Port Motor In2

//Starboard Motor Pins
constexpr int stbdPWMPin = 3; //Starboard Motor PWM
constexpr int stbdIn3Pin = 2; //Starboard Motor In3
constexpr int stbdIn4Pin = 4; //Starboard Motor In4

//Vertical Motor Pins
constexpr int vertPWMPin = 10; //Vertical Motor PWM Pin
constexpr int vertIn3Pin = 8; //Vertical Motor In3 Pin
constexpr int vertIn4Pin = 9; //Vertical Motor In4 Pin

struct motorType {
  byte pwmPin;
  boolean inPin1;
  boolean inPin2;
  void init(byte pwm, byte in1, byte in2) {
    pwmPin = pwm;
    inPin1 = in1;
    inPin2 = in2;
    pinMode(inPin1, OUTPUT);
    pinMode(inPin2, OUTPUT);
    stop();
  }
  void setDirection(boolean in1, boolean in2) {
    digitalWrite(inPin1, in1);
    digitalWrite(inPin2, in2);
  }
  void stop() {
    digitalWrite(inPin1, LOW);
    digitalWrite(inPin1, LOW);
    speed(0);
  }
  void speed(int aSpeed) {
    if (aSpeed >= 0) {
      analogWrite(pwmPin, aSpeed);
    }
  }
  // The following functions are not used here
  // but could be useful in future
  void forward() {
    digitalWrite(inPin1, HIGH);
    digitalWrite(inPin1, LOW);
  }
  void back() {
    digitalWrite(inPin1, LOW);
    digitalWrite(inPin1, HIGH);
  }
};

motorType prtMotor;
motorType stbdMotor;
motorType vertMotor;

#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <HardwareSerial.h>

//initialize the liquid crystal library
//the first parameter is  the I2C address
//the second parameter is how many rows are on your screen
//the  third parameter is how many columns are on your screen
LiquidCrystal_I2C lcd(0x27, 20, 4);

//Joystick input values
double X_Voltage;   //Port/Starboard Joystick input value
double Y_Voltage;   //Forward/Reverse Joystick input value
double Z_Voltage;   //Vertical Joystick input value
//double SL_Voltage;  // XY Joystick Slew value - used in original joystick

double X_Max_Voltage;
double X_Centre_Voltage;
double X_Min_Voltage;

//Constant values of the Y Voltages - Max, Centre and Min
double Y_Max_Voltage;
double Y_Centre_Voltage;
double Y_Min_Voltage ;

  //Constant values of the Slew Voltages - Max, Centre and Min - not used on current joystick
//constexpr double SL_Max_Voltage = 8.9;
//double SL_Centre_Voltage;
//constexpr double SL_Min_Voltage = -8.9;

constexpr double Z_Max_Voltage = 8.88;
double Z_Centre_Voltage;
constexpr double Z_Min_Voltage = -8.96;

// Variables for checking which axis the joystick has been changed
boolean X_Centred, Y_Centred, Z_Centred;

#define X_Pin A0 //Joystick input Port/Starboard pin
#define Y_Pin A1 //Joystick input Forward/Reverse pin
#define Z_Pin A2 //Joystick input Vertical up/down pin
//#define SL_Pin A3 //XY Joystick slew pin - not used on current joystick

//Function for mapping the input ADC value returned from the joystick to a number in a range, e.g. to convert it to a meaningful value
float fmap(float x, float in_min, float in_max, float out_min, float out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

// function to return a scaled value of -10 to +10V from the analogue pins
double scaled_value(int pin) {
  int raw = analogRead(pin);
  double scaled = fmap(raw, 0, 1023, -10, 10.0);
  //scaled = scaled + 1; // add 1 so that 0 not returned at minimum 
  return scaled;
}

//Function to check if the Joystick is centred
boolean JoystickCentred (double Centre_Voltage, double Voltage){
  
  double Min_Centre, Max_Centre;
  double Voltage_Range = 0.7;

  Min_Centre = Centre_Voltage - (Voltage_Range/2);
  Max_Centre = Centre_Voltage + (Voltage_Range/2); 

  if (Voltage >= (Min_Centre) && Voltage <= (Max_Centre)){
    return true;
  }
  else{
    return false;
  }
}

//Function to check if a voltage returned from the joystick is in a range, i.e. between 2 values
boolean VoltageInRange (double Lower_Voltage, double Upper_Voltage, double Voltage){

  if (Voltage > Lower_Voltage && Voltage < Upper_Voltage){
    return true;
  }
  return false; 
}

//Function to calculate the PWM value based on the joystick voltage
int PWM_Val(double voltage, double centre_voltage, double max_voltage, double min_voltage){
  
  int Max_PWM = 255; // Maximum PWM value
  int PWM;

  double Upper_Voltage_Range = max_voltage - centre_voltage;
  double Lower_Voltage_Range = centre_voltage - min_voltage;
  double Upper_PWM_Scaling_Factor = Max_PWM/Upper_Voltage_Range;
  double Lower_PWM_Scaling_Factor = Max_PWM/Lower_Voltage_Range;

  double Voltage_Range = 0.7;
  double temp_upper_Min_Voltage = min_voltage + Voltage_Range;
  double temp_lower_Min_Voltage = min_voltage - Voltage_Range;
  double temp_upper_Max_Voltage = max_voltage + Voltage_Range;
  double temp_lower_Max_Voltage = max_voltage - Voltage_Range;

  double temp_lower_Centre_Voltage = centre_voltage - (Voltage_Range/2);
  double temp_upper_Centre_Voltage = centre_voltage + (Voltage_Range/2);

  boolean voltage_in_upper_range , voltage_in_lower_range, voltage_in_centre_range, voltage_in_max_range, voltage_in_min_range;

  voltage_in_upper_range = VoltageInRange(temp_upper_Centre_Voltage, temp_upper_Max_Voltage, voltage);
  voltage_in_lower_range = VoltageInRange(temp_lower_Min_Voltage, temp_lower_Centre_Voltage, voltage);
  voltage_in_min_range = VoltageInRange(temp_lower_Min_Voltage, temp_upper_Min_Voltage, voltage);
  voltage_in_max_range = VoltageInRange(temp_lower_Max_Voltage, temp_upper_Max_Voltage, voltage);
  voltage_in_centre_range =  VoltageInRange(temp_lower_Centre_Voltage, temp_upper_Centre_Voltage, voltage);

  if (voltage_in_upper_range){
    PWM = (voltage- centre_voltage) * Upper_PWM_Scaling_Factor;
  }
  else if (voltage_in_lower_range){
    PWM = (centre_voltage - voltage) * Lower_PWM_Scaling_Factor;
  }
  else if (voltage_in_min_range){
    PWM = Max_PWM;
  }
  else if (voltage_in_max_range){
    PWM = Max_PWM;
  }
  else if (voltage_in_centre_range){
    PWM = 0;
  }
  //delay(1000);
  if (PWM > 255){
    PWM = Max_PWM;
  }
  else if (PWM < 60){
    PWM = 0;
  }

  return PWM;
}

void ControlVertMotor() {
  
  int PWM_Value; 
  boolean In3;
  boolean In4;
  
  double Min_Z_Centre, Max_Z_Centre;
  double Z_Voltage_Range = 0.7;

  //double temp_Z_Max_Voltage = Z_Max_Voltage + (Z_Voltage_Range/2);
  //double temp_Z_Min_Voltage = Z_Min_Voltage - (Z_Voltage_Range/2);

  Min_Z_Centre = Z_Centre_Voltage - (Z_Voltage_Range/2);
  Max_Z_Centre = Z_Centre_Voltage + (Z_Voltage_Range/2);

  boolean Z_upper, Z_lower;
    
  Z_Centred = JoystickCentred (Z_Centre_Voltage, Z_Voltage);

  Z_upper = VoltageInRange(Min_Z_Centre, Z_Max_Voltage, Z_Voltage);
  Z_lower = VoltageInRange(Z_Min_Voltage, Max_Z_Centre, Z_Voltage);

  
  // If Vertical Joystick centred, stop vertical motor
  if (Z_Centred){
    vertMotor.stop();
    return;
  }
  else if (!Z_Centred){
    // If Voltage between centre value and Max
    if (Z_upper){ //Set direction to forwards (up)
      In3 = 0;
      In4 = 1;
    }
    else if (Z_lower){ //Set direction to backwards (down)
      In3 = 1;
      In4 = 0;
    }
  }
  vertMotor.setDirection(In3, In4);
  PWM_Value = PWM_Val(Z_Voltage, Z_Centre_Voltage, Z_Max_Voltage, Z_Min_Voltage); // Calculate PWM value - scale to Z_Voltage
  vertMotor.speed(PWM_Value);
}

void ControlPortStarbdMotors() {

  //Varaibles for controlling direction the Port and Starboard Motors
  boolean In1;
  boolean In2;
  boolean In3;
  boolean In4;

  // Varaibles for storing the pwm values of the Port and Starboard Motors
  int PWM_Value1;
  int PWM_Value2;

  double voltage_range = 0.7;

  double upper_X_Centre_Voltage = X_Centre_Voltage + (voltage_range/2);
  double lower_X_Centre_Voltage = X_Centre_Voltage - (voltage_range/2);
  //double temp_X_Max_Voltage = X_Max_Voltage + (voltage_range/2);
  //double temp_X_Min_Voltage = X_Min_Voltage - (voltage_range/2);

  double upper_Y_Centre_Voltage = Y_Centre_Voltage + (voltage_range/2);
  double lower_Y_Centre_Voltage = Y_Centre_Voltage - (voltage_range/2);
  //double temp_Y_Max_Voltage = Y_Max_Voltage + (voltage_range/2);
  //double temp_Y_Min_Voltage = Y_Min_Voltage - (voltage_range/2);

  //double upper_SL_Centre_Voltage = SL_Centre_Voltage +(voltage_range/2);
  //double lower_SL_Centre_Voltage = SL_Centre_Voltage - (voltage_range/2);
  //double temp_SL_Max_Voltage = SL_Max_Voltage + (voltage_range/2);
  //double temp_SL_Min_Voltage = SL_Min_Voltage - (voltage_range/2);

  boolean X_upper, X_lower,Y_upper, Y_lower;
  //boolean SL_upper, SL_lower;

  X_upper = VoltageInRange(upper_X_Centre_Voltage, X_Max_Voltage, X_Voltage);
  X_lower = VoltageInRange(X_Min_Voltage, lower_X_Centre_Voltage, X_Voltage);

  Y_upper = VoltageInRange(upper_Y_Centre_Voltage, Y_Max_Voltage, Y_Voltage);
  Y_lower = VoltageInRange(Y_Min_Voltage, lower_Y_Centre_Voltage, Y_Voltage);

  //SL_upper = VoltageInRange(upper_SL_Centre_Voltage, temp_SL_Max_Voltage, SL_Voltage);
  //SL_lower = VoltageInRange(temp_SL_Min_Voltage, lower_SL_Centre_Voltage, SL_Voltage); 
  lcd.setCursor(0,3);
  X_Centred = JoystickCentred(X_Centre_Voltage, X_Voltage);
  Y_Centred = JoystickCentred(Y_Centre_Voltage, Y_Voltage);
  //Check if joystick centred
  lcd.print("uXCV");
  lcd.print(upper_X_Centre_Voltage);
  lcd.print("lXCV");
  lcd.print(lower_Y_Centre_Voltage);
  //lcd.print("Y_u");
  //lcd.print(Y_upper);
  //lcd.print("Y_l");
  //lcd.print(Y_lower);
  if (X_Centred && Y_Centred){
    // If so, stop port and starboard motors
    prtMotor.stop();
    stbdMotor.stop();
    //lcd.print("x & y voltages centred");
    //and exit proc
    return;
  }
  //if Joysticks not centred
  //if X is not centred
  if (X_Centred == LOW){
    if (X_upper == HIGH){
      //move to starboard
      In1 = 0;
      In2 = 0;
      In3 = 1;
      In4 = 0;
      //Starbord Motor is stopped so PWM = 0
      PWM_Value1 = 0;
      //Calculate PWM Value for Port Motor
      PWM_Value2 = PWM_Val(X_Voltage, X_Centre_Voltage, X_Max_Voltage, X_Min_Voltage);
      prtMotor.stop();
      stbdMotor.setDirection(In3, In4);
      stbdMotor.speed(PWM_Value2);
      lcd.print("In1");
      lcd.print(In1);
      lcd.print("In2");
      lcd.print(In2);
      lcd.print("In3");
      lcd.print(In3);
      lcd.print("In4");
      lcd.print(In4);
      return;
    }
    else if (X_lower == HIGH){ 
      //Move to port
      In1 = 1;
      In2 = 0;
      In3 = 0;
      In4 = 0;
      //Calculate PWM Value for Starboard Motor
      PWM_Value1 = PWM_Val(X_Voltage, X_Centre_Voltage, X_Max_Voltage, X_Min_Voltage); 
      //Port Motor is stopped so PWM = 0  
      PWM_Value2 = 0;
      prtMotor.setDirection(In1, In2);
      prtMotor.speed(PWM_Value1);
      stbdMotor.stop();
      lcd.print("In1");
      lcd.print(In1);
      lcd.print("In2");
      lcd.print(In2);
      lcd.print("In3");
      lcd.print(In3);
      lcd.print("In4");
      lcd.print(In4);
      return;
    }
  }
  //Y not centred
  if (Y_Centred == LOW){
    if (Y_upper == HIGH){
      //both motors forwards
      In1 = 1;
      In2 = 0;
      In3 = 1;
      In4 = 0;
      //Calculate PWM Value for Starboard Motor
      PWM_Value1 = PWM_Val(Y_Voltage, Y_Centre_Voltage, Y_Max_Voltage, Y_Min_Voltage);
      //Calculate PWM Value for Port Motor
      PWM_Value2 = PWM_Val(Y_Voltage, Y_Centre_Voltage, Y_Max_Voltage, Y_Min_Voltage);
      prtMotor.setDirection(In1, In2);
      prtMotor.speed(PWM_Value1);
      stbdMotor.setDirection(In3, In4);
      stbdMotor.speed(PWM_Value2);
      lcd.print("In1");
      lcd.print(In1);
      lcd.print("In2");
      lcd.print(In2);
      lcd.print("In3");
      lcd.print(In3);
      lcd.print("In4");
      lcd.print(In4);
      return;
    }
    else if (Y_lower == HIGH){
      //both motors reverse
      In1 = 0;
      In2 = 1;
      In3 = 0;
      In4 = 1;
      //Calculate PWM Value for Starboard Motor
      PWM_Value1 = PWM_Val(Y_Voltage, Y_Centre_Voltage, Y_Max_Voltage, Y_Min_Voltage);
      //Calculate PWM Value for Port Motor
      PWM_Value2 = PWM_Val(Y_Voltage, Y_Centre_Voltage, Y_Max_Voltage, Y_Min_Voltage);
      prtMotor.setDirection(In1, In2);
      prtMotor.speed(PWM_Value1);
      stbdMotor.setDirection(In3, In4);
      stbdMotor.speed(PWM_Value2);
      lcd.print("In1");
      lcd.print(In1);
      lcd.print("In2");
      lcd.print(In2);
      lcd.print("In3");
      lcd.print(In3);
      lcd.print("In4");
      lcd.print(In4);
      return;
    }
  }
  // Following section not currently used - it was written for the original joystick which had a slew function
  // Slew control not centred
  //else if (!SL_Centred){
    //if (SL_upper){
      //starboard forward, port reverse
      //Serial.println("SL Voltage in upper range");
      //In1 = 1;
      //In2 = 0;
      //In3 = 0;
      //In4 = 1;
      //Calculate PWM Value for Starboard Motor
      //PWM_Value1 = PWM_Val(SL_Voltage, SL_Centre_Voltage, SL_Max_Voltage, SL_Min_Voltage);
      //Calculate PWM Value for Port Motor
      //PWM_Value2 = PWM_Val(SL_Voltage, SL_Centre_Voltage, SL_Max_Voltage, SL_Min_Voltage);
    //}
    //else if (SL_lower){
      //Starboard reverse, Port forward
      //In1 = 0;
      //In2 = 1;
      //In3 = 1;
      //In4 = 0;
      //Calculate PWM Value for Starboard Motor
      //PWM_Value1 = PWM_Val(SL_Voltage, SL_Centre_Voltage, SL_Max_Voltage, SL_Min_Voltage);
      //Calculate PWM Value for Port Motor
      //PWM_Value2 = PWM_Val(SL_Voltage, SL_Centre_Voltage, SL_Max_Voltage, SL_Min_Voltage);
    //}
  //}
    
    //prtMotor.setDirection(In1, In2);
    //prtMotor.speed(PWM_Value1);
    //stbdMotor.setDirection(In3, In4);
    //stbdMotor.speed(PWM_Value2);  
}

void calibrate_Joysticks() {
  boolean X_Centred;
  boolean Y_Centred;

  X_Voltage = scaled_value(X_Pin);
  Y_Voltage = scaled_value(Y_Pin);
  Z_Voltage = scaled_value(Z_Pin);

  X_Centre_Voltage = X_Voltage;
  Y_Centre_Voltage = Y_Voltage;
  Z_Centre_Voltage = Z_Voltage;

  double volts[100];
  double av_volts = 0;
  int i;

  double tempXmin, tempXmax, tempYmin, tempYmax;

  X_Centred = JoystickCentred(X_Centre_Voltage, X_Voltage);
  Y_Centred = JoystickCentred(Y_Centre_Voltage, Y_Voltage);
  lcd.setCursor(0,0);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("X-Y Joystick Up");
  while(Y_Centred){
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("X-Y Joystick Up");
    Y_Voltage = scaled_value(Y_Pin);
    Y_Centred = JoystickCentred(Y_Centre_Voltage, Y_Voltage);
  }
  while(!Y_Centred){
    if (Y_Voltage > Y_Centre_Voltage){
      for (i = 1; i< 100; i++){
        Y_Voltage = scaled_value(Y_Pin);
        volts[i] = Y_Voltage;
        av_volts = av_volts+ volts[i];
      }
      av_volts=av_volts/100;
      lcd.setCursor(0,1);
      lcd.print("Average Voltage");
      lcd.print(av_volts);
      tempYmax = av_volts;
      lcd.print("Y_Max_Voltage");
      lcd.print(tempYmax);
      Y_Centred = JoystickCentred(Y_Centre_Voltage, Y_Voltage);
      if (Y_Centred){
        break;
      }
    }
  }  
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("X-Y Joystick Down");
  while (Y_Centred){
    lcd.setCursor(0,0);
    lcd.print("X-Y Joystick Down");
    Y_Voltage = scaled_value(Y_Pin);
    Y_Centred = JoystickCentred(Y_Centre_Voltage, Y_Voltage);
  }
  while(!Y_Centred){
    if (Y_Voltage < Y_Centre_Voltage){
      for (i = 1; i< 100; i++){
        Y_Voltage = scaled_value(Y_Pin);
        volts[i] = Y_Voltage;
        av_volts = av_volts+ volts[i];
      }
      av_volts=av_volts/100;
      lcd.setCursor(0,1);
      lcd.print("Average Voltage");
      lcd.print(av_volts);
      tempYmin = av_volts;
      lcd.print("Y_Min_Voltage");
      lcd.print(tempYmin);
      Y_Centred = JoystickCentred(Y_Centre_Voltage, Y_Voltage);
      if (Y_Centred){
        break;
      }
    }
  } 
  lcd.clear();
  lcd.setCursor(0,0); 
  lcd.print("X-Y Joystick left");
  while (X_Centred){
    lcd.setCursor(0,0);
    lcd.print("X-Y Joystick left");
    X_Voltage = scaled_value(X_Pin);
    X_Centred = JoystickCentred(X_Centre_Voltage, X_Voltage);
  }
  while (!X_Centred){
    if (X_Voltage < X_Centre_Voltage){
      for (i = 1; i< 100; i++){
        X_Voltage = scaled_value(X_Pin);
        volts[i] = X_Voltage;
        av_volts = av_volts+ volts[i];
      }
      av_volts=av_volts/100;
      lcd.setCursor(0,1);
      lcd.print("Average Voltage");
      lcd.print(av_volts);
      tempXmin = av_volts;
      lcd.print("X_Min_Voltage");
      lcd.print(tempXmin);
      X_Centred = JoystickCentred(X_Centre_Voltage, X_Voltage);
      if (X_Centred){
        break;
      }
    }
  } 
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("X-Y Joystick right");
  while (X_Centred){
    lcd.setCursor(0,0);
    lcd.print("X-Y Joystick right");
    X_Voltage = scaled_value(X_Pin);
    X_Centred = JoystickCentred(X_Centre_Voltage, X_Voltage);
  }
  while(!X_Centred){
    if (X_Voltage > X_Centre_Voltage){
      for (i = 1; i< 100; i++){
        X_Voltage = scaled_value(X_Pin);
        volts[i] = X_Voltage;
        av_volts = av_volts+ volts[i];
      }
      av_volts=av_volts/100;
      lcd.setCursor(0,1);
      lcd.print("Average Voltage");
      lcd.print(av_volts);
      tempXmax = av_volts;
      lcd.print("X_Max_Voltage");
      lcd.print(tempXmax);
      X_Centred = JoystickCentred(X_Centre_Voltage, X_Voltage);
      if (Y_Centred){
        break;
      }
    }
  }
  lcd.clear();
  X_Max_Voltage = tempXmax;
  X_Min_Voltage = tempXmin;
  Y_Max_Voltage = tempYmax;
  Y_Min_Voltage = tempYmin;
  lcd.print("X_Max_Voltage = ");
  lcd.print(X_Max_Voltage);
  lcd.print("X_Min_Voltage = ");
  lcd.print(X_Min_Voltage);
  lcd.print("Y_Max_Voltage = ");
  lcd.print(Y_Max_Voltage);
  lcd.print("Y_Min_Voltage = ");
  lcd.print(Y_Min_Voltage);
  delay(5000);
  lcd.clear();
}
//Initialise and setup display
void Init_Display() {
//initialize lcd screen
  lcd.init();
  // turn on the backlight
  lcd.backlight();
  //Set Cursor to 0,0
  lcd.setCursor(0,0);
  calibrate_Joysticks();
  lcd.clear();
  return;
}
//Proceedure to display the joytick voltages on the screen
void Display_Voltages(double X_Volts, double Y_Volts, double Z_Volts) {
  // Set Cursor to 0,0
  lcd.setCursor(0, 0);
  //Display the X voltage
  lcd.print("X Voltage: ");
  lcd.print(X_Volts);
  //Move a row down
  lcd.setCursor(0, 1);
  //Display the Y Voltage
  lcd.print("Y Voltage: ");
  lcd.print(Y_Volts);
  //Move a row down
  lcd.setCursor(0, 2);
  //Display the Z Voltage
  lcd.print("Z Voltage: ");
  lcd.print(Z_Volts);
  //Code not used - for Slew function on joystick
  //move a row down
  //lcd.setCursor(0, 3);
  //Display the Slew Voltage
  //lcd.print("Slew Voltage: ");
  //lcd.print(SL_Volts);
}

void setup() {
  //Enable Serial Output for Displaying values
  Serial.begin(9600);
  //while(!Serial){}
  //Enable Joystick inputs
  pinMode(X_Pin, INPUT); //Joystick X Input Pin
  pinMode(Y_Pin, INPUT); //Joystick Y Input Pin
  pinMode(Z_Pin, INPUT); //Input Z Joystick Pin
  //pinMode(SL_Pin, INPUT); // XY Joystick Slew input Pin
  //Initialise the Joystick Centre Values
  X_Voltage = scaled_value(X_Pin);
  Y_Voltage = scaled_value(Y_Pin);
  Z_Voltage = scaled_value(Z_Pin);
  //SL_Voltage = scaled_value(SL_Pin);
  
  //Next 2 lines not used - for Slew Function on joystick
  //SL_Centre_Voltage = SL_Voltage;

  //Enable Port motor outputs
  prtMotor.init(prtPWMPin, prtIn1Pin, prtIn2Pin);
  //Enable Starboard Motor Outputs
  stbdMotor.init(stbdPWMPin, stbdIn3Pin, stbdIn4Pin);
  //Enable Vertical Motor Outputs
  vertMotor.init(vertPWMPin, vertIn3Pin, vertIn4Pin);
  //Initialise the display
  Init_Display();
}

void loop() {
  X_Voltage = scaled_value(X_Pin);
  Y_Voltage = scaled_value(Y_Pin);
  Z_Voltage = scaled_value(Z_Pin);
  //SL_Voltage = scaled_value(SL_Pin);
  Display_Voltages(X_Voltage, Y_Voltage, Z_Voltage);
  ControlVertMotor();
  lcd.setCursor(0,3);
  ControlPortStarbdMotors();
}

It is in the Calibrate Joysticks proc. 

Any ideas please? Tearing my hair out here!

It is in the Calibrate Joysticks proc.

Any ideas please? Tearing my hair out here!

No idea (and no experience with the R4) but I just noticed this:

Those booleans have the values true or false which usually is 1 and 0. Is it your intention to write pins 1 and 0? I'm not sure of the behaviour.

Ah. Thanks for pointing that out.

it should be int for those variables.

I must have changed it yesterday in the confusion, thinking that it was for the actual output values.

I've changed both inPin1 and inPin2 to int.

But the values for the Max and Min joystick voltages are still being stored as the same as the centre values.

I don't think that the board is running out of memory - I saw that yesterday in another post. When I compile the program, it says that only 25% of the memory is being used.

I managed to get it working again.

I added a few debug statements and it seems to slow it down.

What I think is happening is that when the joystick is centred, it is still taking samples. It could be the few milliseconds when the joystick is returning to the centre point.

I don't know for sure, but the main thing is that it is working again.

Apart from the code needs tidying up, I think that is it for just now.

Amended code for the calibration routine is below:-

void calibrate_Joysticks() {
  boolean X_Centred;
  boolean Y_Centred;

  X_Voltage = scaled_value(X_Pin);
  Y_Voltage = scaled_value(Y_Pin);
  Z_Voltage = scaled_value(Z_Pin);

  X_Centre_Voltage = X_Voltage;
  Y_Centre_Voltage = Y_Voltage;
  Z_Centre_Voltage = Z_Voltage;

  double volts[100];
  double av_volts = 0;
  int i;

  double tempXmin, tempXmax, tempYmin, tempYmax;

  X_Centred = JoystickCentred(X_Centre_Voltage, X_Voltage);
  Y_Centred = JoystickCentred(Y_Centre_Voltage, Y_Voltage);
  lcd.setCursor(0,0);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("X-Y Joystick Up");
  while(Y_Centred){
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("X-Y Joystick Up");
    Y_Voltage = scaled_value(Y_Pin);
    Y_Centred = JoystickCentred(Y_Centre_Voltage, Y_Voltage);
  }
  while(!Y_Centred){
    if (Y_Voltage > Y_Centre_Voltage){
      for (i = 1; i< 100; i++){
        Y_Voltage = scaled_value(Y_Pin);
        volts[i] = Y_Voltage;
        av_volts = av_volts+ volts[i];
        lcd.setCursor(0,1);
        lcd.print("Voltage Reading");
        lcd.print(Y_Voltage);
      }
      av_volts=av_volts/100;
      lcd.setCursor(0,1);
      lcd.print("Average Voltage");
      lcd.print(av_volts);
      tempYmax = av_volts;
      lcd.print("Y_Max_Voltage");
      lcd.print(tempYmax);
      Y_Centred = JoystickCentred(Y_Centre_Voltage, Y_Voltage);
      if (Y_Centred){
        break;
      }
    }
  }  
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("X-Y Joystick Down");
  while (Y_Centred){
    lcd.setCursor(0,0);
    lcd.print("X-Y Joystick Down");
    Y_Voltage = scaled_value(Y_Pin);
    Y_Centred = JoystickCentred(Y_Centre_Voltage, Y_Voltage);
  }
  while(!Y_Centred){
    if (Y_Voltage < Y_Centre_Voltage){
      for (i = 1; i< 100; i++){
        Y_Voltage = scaled_value(Y_Pin);
        volts[i] = Y_Voltage;
        av_volts = av_volts+ volts[i];
        lcd.setCursor(0,1);
        lcd.print("Voltage Reading");
        lcd.print(Y_Voltage);
      }
      av_volts=av_volts/100;
      lcd.setCursor(0,1);
      lcd.print("Average Voltage");
      lcd.print(av_volts);
      tempYmin = av_volts;
      lcd.print("Y_Min_Voltage");
      lcd.print(tempYmin);
      Y_Centred = JoystickCentred(Y_Centre_Voltage, Y_Voltage);
      if (Y_Centred){
        break;
      }
    }
  } 
  lcd.clear();
  lcd.setCursor(0,0); 
  lcd.print("X-Y Joystick left");
  while (X_Centred){
    lcd.setCursor(0,0);
    lcd.print("X-Y Joystick left");
    X_Voltage = scaled_value(X_Pin);
    X_Centred = JoystickCentred(X_Centre_Voltage, X_Voltage);
  }
  while (!X_Centred){
    if (X_Voltage < X_Centre_Voltage){
      for (i = 1; i< 100; i++){
        X_Voltage = scaled_value(X_Pin);
        volts[i] = X_Voltage;
        av_volts = av_volts+ volts[i];
        lcd.setCursor(0,1);
        lcd.print("Voltage Reading");
        lcd.print(X_Voltage);
      }
      av_volts=av_volts/100;
      lcd.setCursor(0,1);
      lcd.print("Average Voltage");
      lcd.print(av_volts);
      tempXmin = av_volts;
      lcd.print("X_Min_Voltage");
      lcd.print(tempXmin);
      X_Centred = JoystickCentred(X_Centre_Voltage, X_Voltage);
      if (X_Centred){
        break;
      }
    }
  } 
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("X-Y Joystick right");
  while (X_Centred){
    lcd.setCursor(0,0);
    lcd.print("X-Y Joystick right");
    X_Voltage = scaled_value(X_Pin);
    X_Centred = JoystickCentred(X_Centre_Voltage, X_Voltage);
  }
  while(!X_Centred){
    if (X_Voltage > X_Centre_Voltage){
      for (i = 1; i< 100; i++){
        X_Voltage = scaled_value(X_Pin);
        volts[i] = X_Voltage;
        av_volts = av_volts+ volts[i];
        lcd.setCursor(0,1);
        lcd.print("Voltage Reading");
        lcd.print(X_Voltage);
      }
      av_volts=av_volts/100;
      lcd.setCursor(0,1);
      lcd.print("Average Voltage");
      lcd.print(av_volts);
      tempXmax = av_volts;
      lcd.print("X_Max_Voltage");
      lcd.print(tempXmax);
      X_Centred = JoystickCentred(X_Centre_Voltage, X_Voltage);
      if (Y_Centred){
        break;
      }
    }
  }
  delay(1000);
  lcd.clear();
  X_Max_Voltage = tempXmax;
  X_Min_Voltage = tempXmin;
  Y_Max_Voltage = tempYmax;
  Y_Min_Voltage = tempYmin;
  lcd.print("X_Max_Voltage = ");
  lcd.print(X_Max_Voltage);
  lcd.print("X_Min_Voltage = ");
  lcd.print(X_Min_Voltage);
  lcd.print("Y_Max_Voltage = ");
  lcd.print(Y_Max_Voltage);
  lcd.print("Y_Min_Voltage = ");
  lcd.print(Y_Min_Voltage);
  delay(5000);
  lcd.clear();
}

Thanks for reading

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