Servo Holding position

Hey guys,

I have spent hours or searching before I posted, I just cant seem to find any code that will stop a servo at the its last position. I can get the servo's to move back and forth but I dont want them to return to 0 or original start position. I am using a thumb joystick like from a PS3 controller but from adafruit Analog 2-axis Thumb Joystick with Select Button + Breakout Board : ID 512 : $5.95 : Adafruit Industries, Unique & fun DIY electronics and kits. I want to be able to push the joystick left or right and hold it position, can anyone point me where some code would be for this. I see the question asked a lot but no solutions.
thanks
FYI, brand new to arduino

I want to be able to push the joystick left or right and hold it position

Until when? Next Tuesday at 3:00PM?

How will you know whether a given movement of the joystick is important, or not?

Until its moved again, When the joystick snaps back to 0 the servo should hold position until the joystick is moved in either direction, I guess that would be a dead zone

When the joystick snaps back to 0

How is the Arduino supposed to know that the joystick "snaps back to 0", as opposed to being moved to 0?

If you want the joystick to move the servo sometimes, and not others, you need some way to tell the Arduino that "this move is important". What are you proposing to use to tell it that?

Perhaps your joystick has a push switch (many do) that you could use to indicate when to move or not.

Rather than have the joystick control the position of the servo, have it control how much the servo moves.

When the stick is centered, the servo doesn't move. When the stick is pushed forward, the corresponding servo moves in direction A. The further the joystick is moved forward the faster the servo moves in direction A. When the joystick is released the servo stops moving.

When the joystick is pulled back towards the user, the servo moves in direction B (B is opposite of direction A). Again, when the joystick returns to center, the servo stops moving.

You could add a button to tell the servo to center itself.

If you want to try this and have trouble with the code let us know.

Do yourself a favor, and don't use the "write" command. "writeMicroseconds" has lots of advantages over "write".

I posted some code to smooth out servo movements here. It might help you understand how to use "writeMicroseconds".

I want to be able to push the joystick left or right and hold it position, can anyone point me where some code would be for this. I see the question asked a lot but no solutions.

The spring return joystick issue comes up fairly often. Below are some thoughts.

http://forum.arduino.cc/index.php?topic=161906.msg1210591#msg1210591

DuaneDegn:
Rather than have the joystick control the position of the servo, have it control how much the servo moves.

When the stick is centered, the servo doesn't move. When the stick is pushed forward, the corresponding servo moves in direction A. The further the joystick is moved forward the faster the servo moves in direction A. When the joystick is released the servo stops moving.

When the joystick is pulled back towards the user, the servo moves in direction B (B is opposite of direction A). Again, when the joystick returns to center, the servo stops moving.

You could add a button to tell the servo to center itself.

If you want to try this and have trouble with the code let us know.

Do yourself a favor, and don't use the "write" command. "writeMicroseconds" has lots of advantages over "write".

I posted some code to smooth out servo movements here. It might help you understand how to use "writeMicroseconds".

Well I like the idea, but I have no clue where to start. I am surprised that there isnt a sketch already done for this method on how many times this question comes up. Seems to be a common problem. I have been able to get the servo working and freeze at a position with a button, but its clumsy. and when the button is pressed to release it can move all over. Can you point me to some code that would get me started on the idea above with moving the stick.
Thanks

pbklan:
I am surprised that there isnt a sketch already done for this method on how many times this question comes up. Seems to be a common problem.

I'd be very surprised if there are not lots of sketches which control servos this way. The trick of course is to find the sketch.

If you give this a try, and can't get it to work, there's a good chance someone will help.

Here's some pseudo code off the top of my head to see if I can help get you started.

  if (potPosition < LOW_CENTER_THRESHOLD)
  {
    servoSpeed = (potPosition - LOW_CENTER_THRESHOLD) / POT_TO_SPEED_CONSTANT; 
    // negative speed proportional to distance from center pot
  }
  else if  (potPosition > HIGH_CENTER_THRESHOLD)
  {
    servoSpeed = (HIGH_CENTER_THRESHOLD - potPosition / POT_TO_SPEED_CONSTANT; 
    // positive speed
  }
  else // pot in dead zone
  {
    servoSpeed = 0;
  }
  servoPosition += servoSpeed; // but you should make sure "servoPosition" stays within endpoints

You'll want to decide what values to use as thresholds. If the reading from the pot can be from 0 to 1023 and we want a 5 unit dead zone on either side of center then possible threshold could be:

const long LOW_CENTER_THRESHOLD = 506;
const long HIGH_CENTER_THRESHOLD = 516;

You'll want to experiment to determine the best value of "POT_TO_SPEED_CONSTANT" but I'd start with a value around 10.

The example I linked to earlier shows how to limit the servo calculations to 50Hz. At 50Hz, the servo's position is going to change pretty quickly at all by low speeds.

As I said, give this a try and let us know if you need help. There are a lot of us suckers nice guys willing to help.

Well I like the idea, but I have no clue where to start. I am surprised that there isnt a sketch already done for this method on how many times this question comes up. Seems to be a common problem.

Well, what you want to do may be a little more complex than you realize. I made a program in basic many years ago that used the joystick with a button where the joystick was only active when the button was pressed. It was usable because I made a display that saved the last x/y positions when the button was released, and below these were the real time x/y positions of the joystick. I had to match the positions before pulling the trigger so the servos would not jerk much. Your best bet is to make a basic servo sweep setup based on the current position of the joystick. Below is some test code (not sure if i ever tested it) that is meant to move a servo slowly based on a button position. A variation probably could be made based on the output of a joystick.

//zoomkat servo button sweep test 12-23-2013
// Powering a servo from the arduino usually *DOES NOT WORK*.

#include <Servo.h>
int button1 = 5; //button pin, connect to ground to move servo
int press1 = 0;
int button2 = 6; //button pin, connect to ground to move servo
int press2 = 0;
Servo servo1;
int pos = 90; // variable to store and set the servo position 

void setup()
{
  Serial.begin(9600);
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  servo1.attach(7);
  servo1.write(pos); //starting position
  digitalWrite(5, HIGH); //enable pullups to make pin high
  digitalWrite(6, HIGH); //enable pullups to make pin high
  Serial.println("servo button sweep test 12-23-2013");
}

void loop()
{
  press1 = digitalRead(button1);
  if (press1 == LOW)
  {
    pos=(pos+1);
    if(pos>180) pos=180; //limit upper value
    Serial.println(pos); //for serial monitor debug
    servo1.write(pos); // tell servo to go to position in variable 'pos' 
    delay(150); // waits 150ms to slow servo movement 
  }    

  press2 = digitalRead(button2);
  if (press2 == LOW)
  {
    pos=(pos-1);
    if(pos<0) pos=0; //limit lower value
    Serial.println(pos); //for serial monitor debug
    servo1.write(pos); // tell servo to go to position in variable 'pos' 
    delay(150); // waits 150ms to slow servo movement
  }
}

If this is so complex, maybe I am going at this all wrong. All I am trying to do is make a simple (my idea of what should be simple) Pan tilt camera control. So I can record sports games at the field while the camera is on a very high pole. I just want to be able to control the pan tilt for the camera positions but the camera needs to stay put, maybe I am better off with two potentiometers, or maybe there is a completely better way of doing this or with stepper motors etc, can you offer any advice in a different direction or should I stay the course?
Thanks

maybe I am better off with two potentiometers

Yes, since your problem is that the joystick wants to return to center when you let go of it. A potentiometer would not do that.

Give this a try.

/* JoystickServoSpeed151116a
 *
 *  by Duane Degn
 *  December 16, 2015
 *
 *  A ring buffers are used to average the
 *  ADC readings from two poteniometers.
 *  This average is used to control
 *  speed of two hobby servos.
 *
 */

#include <Servo.h>

// User changeable.
#define SERVO_X_PIN 2                           // User changeable.
#define SERVO_Y_PIN 3                           // User changeable.

// "JOYSTICK_X_PIN" and "JOYSTICK_Y_PIN" need to be assigned to analog pins.
#define JOYSTICK_X_PIN A0                       // User changeable.
#define JOYSTICK_Y_PIN A1                       // User changeable.

const int MIN_PULSE = 900;                      // User changeable.
const int MAX_PULSE = 2100;                     // User changeable.
const int MIN_POT = 0;                          // User changeable.
const int MAX_POT = 1023;                       // User changeable.
const int POWER_OF_TWO_TO_AVERAGE = 4;          // User changeable.
// Changing "POWER_OF_TWO_TO_AVERAGE" changes several other constants.
// The constants "BUFFER_SIZE" and "BUFFER_LIMIT" are calculated based on "POWER_OF_TWO_TO_AVERAGE".


const long SERVO_PULSE_RANGE = MAX_PULSE - MIN_PULSE; // This needs to be a long for the equations to work correctly.
const int START_PULSE_X = MIN_PULSE + (SERVO_PULSE_RANGE) / 2;  // User changeable.
const int START_PULSE_Y = MIN_PULSE + (SERVO_PULSE_RANGE) / 2;  // User changeable.

const int POT_RANGE = MAX_POT - MIN_POT;

const int BUFFER_SIZE = 1 << POWER_OF_TWO_TO_AVERAGE; // Do not change.
const int BUFFER_LIMIT = BUFFER_SIZE - 1;             // Do not change.

// Time constants and variables should be unsigned longs.
const unsigned long ANALOG_READ_PERIOD = 5000;  // read pots at 200Hz "ANALOG_READ_PERIOD" must be <= "DEBUG_PERIOD"
const unsigned long DEBUG_PERIOD = 100000;  // update serial at 4Hz "DEBUG_PERIOD" must be <= "SERVO_PERIOD"
const unsigned long SERVO_PERIOD = 20000;  // update servo at 50Hz

const int LOW_CENTER_THRESHOLD = 506;     // User changeable.
const int HIGH_CENTER_THRESHOLD = 516;    // User changeable.
const int POT_TO_SPEED_CONSTANT = 10;     // User changeable.

int averagingBufferX[BUFFER_SIZE];
int averagingBufferY[BUFFER_SIZE];
int bufferIndex = 0;
int servoPosition[2];

long bufferTotalX = 0;
long bufferTotalY = 0;

unsigned long lastDebug;
unsigned long lastServo;
unsigned long lastAnalogRead;

Servo myServo[2];
//Servo servoY;

void setup()
{
  Serial.begin(115200);
  myServo[0].writeMicroseconds(1500);
  myServo[1].writeMicroseconds(1500);
  myServo[0].attach(SERVO_X_PIN, MIN_PULSE, MAX_PULSE);
  myServo[1].attach(SERVO_Y_PIN, MIN_PULSE, MAX_PULSE);

  for (byte i; i < BUFFER_SIZE; i++) // Fill buffer with start position.
  {
    averagingBufferX[i] = START_PULSE_X;
    averagingBufferY[i] = START_PULSE_Y;
    bufferTotalX += averagingBufferX[i];
    bufferTotalY += averagingBufferY[i];
  }

  lastDebug = micros();
  lastServo = lastDebug;
  lastAnalogRead = lastDebug;
}

void loop()
{
  checkAnalogReadTime();
}

void checkAnalogReadTime()
{
  if (micros() - lastAnalogRead > ANALOG_READ_PERIOD)
  {
    lastAnalogRead += ANALOG_READ_PERIOD;
    int joystickInputX = analogRead(JOYSTICK_X_PIN);
    int joystickInputY = analogRead(JOYSTICK_Y_PIN);

    bufferIndex++;
    bufferIndex &= BUFFER_LIMIT;

    bufferTotalX -= averagingBufferX[bufferIndex]; // out with the old
    bufferTotalY -= averagingBufferY[bufferIndex];
    averagingBufferX[bufferIndex] = joystickInputX;
    averagingBufferY[bufferIndex] = joystickInputY;
    bufferTotalX += averagingBufferX[bufferIndex]; // in with the new
    bufferTotalY += averagingBufferY[bufferIndex];

    checkServoTime();
  }
}


void checkServoTime()
// Called from "checkAnalogReadTime" function.
{
  if (micros() - lastServo > SERVO_PERIOD)
  {
    lastServo += SERVO_PERIOD;
    controlServo();
  }
}

void controlServo()
// Called from "checkServoTime" function.
{

  int average[2];
  int servoSpeed;
  

  average[0] = bufferTotalX >> POWER_OF_TWO_TO_AVERAGE; // it might be a good idea to make averageX global so it can be used elsewhere in program
  average[1] = bufferTotalY >> POWER_OF_TWO_TO_AVERAGE;

  for (int i = 0; i < 2; i++)
  {
    if (average[i] < LOW_CENTER_THRESHOLD)
    {
      servoSpeed = (average[i] - LOW_CENTER_THRESHOLD) / POT_TO_SPEED_CONSTANT;
      // negative speed proportional to distance from center pot
    }
    else if  (average[i] > HIGH_CENTER_THRESHOLD)
    {
      servoSpeed = HIGH_CENTER_THRESHOLD - average[i] / POT_TO_SPEED_CONSTANT;
                    // positive speed
    }
    else // pot in dead zone
    {
      servoSpeed = 0;
    }
    servoPosition[i] += servoSpeed; // but you should make sure "servoPosition" stays within endpoints
    if (servoPosition[i] > MAX_POT)
    {
      servoPosition[i] = MAX_POT;
    }
    else if (servoPosition[i] < MIN_POT)
    {
      servoPosition[i] = MIN_POT;
    }
    myServo[i].writeMicroseconds(servoPosition[i]);
  }

  checkDebugTime(average[0], average[1], servoPosition[0], servoPosition[1]);
}

void checkDebugTime(int averageX, int averageY, int servoOutputX, int servoOutputY)
// Called from "checkServoTime" function.
// Serial output slows down code execution.
// This method checks to see if it's time to
// display data.
// It would probably be a good idea to remove this section of code
// once the program is working as hoped and when serial
// output is now longer desired.
{
  if (micros() - lastDebug > DEBUG_PERIOD)
  {
    lastDebug += DEBUG_PERIOD;

    Serial.print(F("average = "));
    Serial.print(averageX, DEC);
    Serial.print(F(", "));
    Serial.print(averageY, DEC);
    Serial.print(F(", Servo = "));
    Serial.print(servoOutputX, DEC);
    Serial.print(F(", "));
    Serial.println(servoOutputY, DEC);
  }
}

You will likely need to tweak some of the constants as I mentioned earlier.

DuaneDegn thanks for trying to help, I tried the code and tried changing some of the constants that made sense to me, but to be honest its a bit over my head right now, being new to the programming. Take a look at this video, this guys got it nailed, but hes not responding.

pbklan:
DuaneDegn thanks for trying to help, I tried the code and tried changing some of the constants that made sense to me, but to be honest its a bit over my head right now, being new to the programming.

So what did it do you didn't want it to do?

What was displayed in the terminal when the joystick was centered?

If you let us know what the "average" values were, I can help you adjust the constants.

Did the servos move when you moved the joystick?

I've done lots of servo projects. I'm sure I can help you get this to work well if you describe what's happening.

ok thanks, I really appreciate you taking your time, So on first load, with no changes e The servo didnt do much of any thing, Moving the joystick would move them just a touch, and then they would slowly return to the start position, but it barley moved.

This was the standing output without touching the joystick

average = 489, 493, Servo = 260, 396
average = 489, 493, Servo = 254, 391
average = 489, 493, Servo = 248, 386
average = 489, 493, Servo = 242, 381

Joystick moved
verage = 1000, 1023, Servo = 1023, 1023
average = 1001, 1023, Servo = 1023, 1023
average = 1001, 1023, Servo = 1023, 1023
average = 1002, 1023, Servo = 1023, 1023

average = 12, 0, Servo = 0, 0
average = 12, 0, Servo = 0, 0
average = 12, 0, Servo = 0, 0

average = 1022, 493, Servo = 1023, 0
average = 1022, 493, Servo = 1023, 0
average = 1022, 493, Servo = 1023, 0
average = 1022, 493, Servo = 1023, 0
average = 1022, 493, Servo = 1023, 0

average = 934, 493, Servo = 1023, 406
average = 914, 493, Servo = 1023, 401
average = 855, 493, Servo = 1023, 396
average = 849, 493, Servo = 1023, 391
average = 856, 493, Servo = 1023, 386

Output after the joystick was moved and then it slowly moved back to standing position

average = 487, 493, Servo = 0, 0
average = 487, 493, Servo = 0, 0
average = 487, 493, Servo = 0, 0
average = 487, 493, Servo = 0, 0

Robotic programs rarely work just right on the first attempt.

Often there are bugs in the program which need to be fixed (I had a couple your output revealed) and the various parameters need to be tuned (which is also apparent from the output).

I had the center position of the pot set to be between 506 and 516. The output shows in the neutral position the pots on your joystick are 489 and 493. Since both these values are outside the two thresholds, the program assumes the joystick is being used and moves the servos.

I had introduced a bug to the program by using the pot extremes to limit the servo movement.

I've adjusted a few of the constants and fixed the comparison bug. Here's another version of the code to try.

WARNING! Buggy Code! Use the code in reply #22.

/* JoystickServoSpeed151116a
 *
 *  by Duane Degn
 *  December 16, 2015
 *
 *  A ring buffers are used to average the
 *  ADC readings from two poteniometers.
 *  This average is used to control
 *  speed of two hobby servos.
 *
 */

#include <Servo.h>

// User changeable.
#define SERVO_X_PIN 2                           // User changeable.
#define SERVO_Y_PIN 3                           // User changeable.

// "JOYSTICK_X_PIN" and "JOYSTICK_Y_PIN" need to be assigned to analog pins.
#define JOYSTICK_X_PIN A0                       // User changeable.
#define JOYSTICK_Y_PIN A1                       // User changeable.

const int MIN_PULSE = 900;                      // User changeable.
const int MAX_PULSE = 2100;                     // User changeable.
const int MIN_POT = 0;                          // User changeable.
const int MAX_POT = 1023;                       // User changeable.
const int POWER_OF_TWO_TO_AVERAGE = 4;          // User changeable.
// Changing "POWER_OF_TWO_TO_AVERAGE" changes several other constants.
// The constants "BUFFER_SIZE" and "BUFFER_LIMIT" are calculated based on "POWER_OF_TWO_TO_AVERAGE".


const long SERVO_PULSE_RANGE = MAX_PULSE - MIN_PULSE; // This needs to be a long for the equations to work correctly.
const int START_PULSE_X = MIN_PULSE + (SERVO_PULSE_RANGE) / 2;  // User changeable.
const int START_PULSE_Y = MIN_PULSE + (SERVO_PULSE_RANGE) / 2;  // User changeable.

const int POT_RANGE = MAX_POT - MIN_POT;

const int BUFFER_SIZE = 1 << POWER_OF_TWO_TO_AVERAGE; // Do not change.
const int BUFFER_LIMIT = BUFFER_SIZE - 1;             // Do not change.

// Time constants and variables should be unsigned longs.
const unsigned long ANALOG_READ_PERIOD = 5000;  // read pots at 200Hz "ANALOG_READ_PERIOD" must be <= "DEBUG_PERIOD"
const unsigned long DEBUG_PERIOD = 100000;  // update serial at 4Hz "DEBUG_PERIOD" must be <= "SERVO_PERIOD"
const unsigned long SERVO_PERIOD = 20000;  // update servo at 50Hz

const int LOW_CENTER_THRESHOLD = 482;     // User changeable.
const int HIGH_CENTER_THRESHOLD = 510;    // User changeable.
const int POT_TO_SPEED_CONSTANT = 4;     // User changeable.

int averagingBufferX[BUFFER_SIZE];
int averagingBufferY[BUFFER_SIZE];
int bufferIndex = 0;
int servoPosition[2];

long bufferTotalX = 0;
long bufferTotalY = 0;

unsigned long lastDebug;
unsigned long lastServo;
unsigned long lastAnalogRead;

Servo myServo[2];
//Servo servoY;

void setup()
{
  Serial.begin(115200);
  myServo[0].writeMicroseconds(1500);
  myServo[1].writeMicroseconds(1500);
  myServo[0].attach(SERVO_X_PIN, MIN_PULSE, MAX_PULSE);
  myServo[1].attach(SERVO_Y_PIN, MIN_PULSE, MAX_PULSE);

  for (byte i; i < BUFFER_SIZE; i++) // Fill buffer with start position.
  {
    averagingBufferX[i] = START_PULSE_X;
    averagingBufferY[i] = START_PULSE_Y;
    bufferTotalX += averagingBufferX[i];
    bufferTotalY += averagingBufferY[i];
  }

  lastDebug = micros();
  lastServo = lastDebug;
  lastAnalogRead = lastDebug;
}

void loop()
{
  checkAnalogReadTime();
}

void checkAnalogReadTime()
{
  if (micros() - lastAnalogRead > ANALOG_READ_PERIOD)
  {
    lastAnalogRead += ANALOG_READ_PERIOD;
    int joystickInputX = analogRead(JOYSTICK_X_PIN);
    int joystickInputY = analogRead(JOYSTICK_Y_PIN);

    bufferIndex++;
    bufferIndex &= BUFFER_LIMIT;

    bufferTotalX -= averagingBufferX[bufferIndex]; // out with the old
    bufferTotalY -= averagingBufferY[bufferIndex];
    averagingBufferX[bufferIndex] = joystickInputX;
    averagingBufferY[bufferIndex] = joystickInputY;
    bufferTotalX += averagingBufferX[bufferIndex]; // in with the new
    bufferTotalY += averagingBufferY[bufferIndex];

    checkServoTime();
  }
}


void checkServoTime()
// Called from "checkAnalogReadTime" function.
{
  if (micros() - lastServo > SERVO_PERIOD)
  {
    lastServo += SERVO_PERIOD;
    controlServo();
  }
}

void controlServo()
// Called from "checkServoTime" function.
{

  int average[2];
  int servoSpeed;
  

  average[0] = bufferTotalX >> POWER_OF_TWO_TO_AVERAGE; // it might be a good idea to make averageX global so it can be used elsewhere in program
  average[1] = bufferTotalY >> POWER_OF_TWO_TO_AVERAGE;

  for (int i = 0; i < 2; i++)
  {
    if (average[i] < LOW_CENTER_THRESHOLD)
    {
      servoSpeed = (average[i] - LOW_CENTER_THRESHOLD) / POT_TO_SPEED_CONSTANT;
      // negative speed proportional to distance from center pot
    }
    else if  (average[i] > HIGH_CENTER_THRESHOLD)
    {
      servoSpeed = HIGH_CENTER_THRESHOLD - average[i] / POT_TO_SPEED_CONSTANT;
                    // positive speed
    }
    else // pot in dead zone
    {
      servoSpeed = 0;
    }
    servoPosition[i] += servoSpeed; // but you should make sure "servoPosition" stays within endpoints
    if (servoPosition[i] > MAX_PULSE)
    {
      servoPosition[i] = MAX_PULSE;
    }
    else if (servoPosition[i] < MIN_PULSE)
    {
      servoPosition[i] = MIN_PULSE;
    }
    myServo[i].writeMicroseconds(servoPosition[i]);
  }

  checkDebugTime(average[0], average[1], servoPosition[0], servoPosition[1]);
}

void checkDebugTime(int averageX, int averageY, int servoOutputX, int servoOutputY)
// Called from "checkServoTime" function.
// Serial output slows down code execution.
// This method checks to see if it's time to
// display data.
// It would probably be a good idea to remove this section of code
// once the program is working as hoped and when serial
// output is now longer desired.
{
  if (micros() - lastDebug > DEBUG_PERIOD)
  {
    lastDebug += DEBUG_PERIOD;

    Serial.print(F("average = "));
    Serial.print(averageX, DEC);
    Serial.print(F(", "));
    Serial.print(averageY, DEC);
    Serial.print(F(", Servo = "));
    Serial.print(servoOutputX, DEC);
    Serial.print(F(", "));
    Serial.println(servoOutputY, DEC);
  }
}

pbklan:
All I am trying to do is make a simple (my idea of what should be simple) Pan tilt camera control.

Believe it or not, this program is simple. The averaging buffer is likely an added complexity which may not be needed but I bet the servo movements will benefit from it.

Here are the constants you'll likely need to adjust to tune your setup.

const int LOW_CENTER_THRESHOLD = 482;     // User changeable.
const int HIGH_CENTER_THRESHOLD = 510;    // User changeable.
const int POT_TO_SPEED_CONSTANT = 4;     // User changeable.

The smaller the "POT_TO_SPEED_CONSTANT" is the faster the servos should move. It had previously been set to 10. The program won't work with values less than one for this constant. If the servo doesn't move fast enough with this constant set to 1 then the program will need to be modified slightly.

It's possible the desired speed can't be found by setting POT_TO_SPEED_CONSTANT by itself. If one setting is too slow but the next setting is too fast, then we can add another parameter to set the speed as a ratio of two values. This would allow the speed to be fine tuned. This of course will make the program more complex.

Thanks again,

Definitely getting closer. So now they Range is better its moving when the joystick is pushed however its moving both servos simultaneously.

Stationary
average = 493, 487, Servo = 2100, 2100
average = 493, 487, Servo = 2100, 2100

moved
average = 493, 1022, Servo = 2100, 2100
average = 493, 1023, Servo = 2100, 2100

average = 493, 487, Servo = 2100, 2100
average = 493, 487, Servo = 2100, 2100

average = 1023, 1005, Servo = 2100, 2100
average = 1023, 1005, Servo = 2100, 2100
average = 1023, 1005, Servo = 2100, 2100

average = 0, 16, Servo = 900, 900
average = 0, 16, Servo = 900, 900

pbklan:
Definitely getting closer. So now they Range is better its moving when the joystick is pushed however its moving both servos simultaneously.

Do you see the averages changing independent from each other?

When both servos move, is either average within the thresholds?

You might need to move the thresholds away from the center so you don't accidentally cause a servo to move.

In the numbers you posted, the servo values were all at the extreme position. Where there ever times with the two servo values didn't match? It looks like you had different servo values in the first set of data.

Here's a program with more debug data.

WARNING! Buggy Code! Use the code in reply #22.

/* JoystickServoSpeed151117b
 *
 *  by Duane Degn
 *  December 17, 2015
 *
 *  A ring buffers are used to average the
 *  ADC readings from two poteniometers.
 *  This average is used to control
 *  speed of two hobby servos.
 *
 */

#include <Servo.h>

// User changeable.
#define SERVO_X_PIN 2                           // User changeable.
#define SERVO_Y_PIN 3                           // User changeable.

// "JOYSTICK_X_PIN" and "JOYSTICK_Y_PIN" need to be assigned to analog pins.
#define JOYSTICK_X_PIN A0                       // User changeable.
#define JOYSTICK_Y_PIN A1                       // User changeable.

const int MIN_PULSE = 900;                      // User changeable.
const int MAX_PULSE = 2100;                     // User changeable.
const int MIN_POT = 0;                          // User changeable.
const int MAX_POT = 1023;                       // User changeable.
const int POWER_OF_TWO_TO_AVERAGE = 4;          // User changeable.
// Changing "POWER_OF_TWO_TO_AVERAGE" changes several other constants.
// The constants "BUFFER_SIZE" and "BUFFER_LIMIT" are calculated based on "POWER_OF_TWO_TO_AVERAGE".


const long SERVO_PULSE_RANGE = MAX_PULSE - MIN_PULSE; // This needs to be a long for the equations to work correctly.
const int START_PULSE_X = MIN_PULSE + (SERVO_PULSE_RANGE) / 2;  // User changeable.
const int START_PULSE_Y = MIN_PULSE + (SERVO_PULSE_RANGE) / 2;  // User changeable.

const int POT_RANGE = MAX_POT - MIN_POT;

const int BUFFER_SIZE = 1 << POWER_OF_TWO_TO_AVERAGE; // Do not change.
const int BUFFER_LIMIT = BUFFER_SIZE - 1;             // Do not change.

// Time constants and variables should be unsigned longs.
const unsigned long ANALOG_READ_PERIOD = 5000;  // read pots at 200Hz "ANALOG_READ_PERIOD" must be <= "DEBUG_PERIOD"
const unsigned long DEBUG_PERIOD = 100000;  // update serial at 4Hz "DEBUG_PERIOD" must be <= "SERVO_PERIOD"
const unsigned long SERVO_PERIOD = 20000;  // update servo at 50Hz

const int LOW_CENTER_THRESHOLD = 482;     // User changeable.
const int HIGH_CENTER_THRESHOLD = 510;    // User changeable.
const int POT_TO_SPEED_CONSTANT = 4;     // User changeable.

int averagingBufferX[BUFFER_SIZE];
int averagingBufferY[BUFFER_SIZE];
int bufferIndex = 0;
int servoPosition[2];

long bufferTotalX = 0;
long bufferTotalY = 0;

unsigned long lastDebug;
unsigned long lastServo;
unsigned long lastAnalogRead;

Servo myServo[2];
//Servo servoY;

void setup()
{
  Serial.begin(115200);
  myServo[0].writeMicroseconds(1500);
  myServo[1].writeMicroseconds(1500);
  myServo[0].attach(SERVO_X_PIN, MIN_PULSE, MAX_PULSE);
  myServo[1].attach(SERVO_Y_PIN, MIN_PULSE, MAX_PULSE);

  for (byte i; i < BUFFER_SIZE; i++) // Fill buffer with start position.
  {
    averagingBufferX[i] = START_PULSE_X;
    averagingBufferY[i] = START_PULSE_Y;
    bufferTotalX += averagingBufferX[i];
    bufferTotalY += averagingBufferY[i];
  }

  lastDebug = micros();
  lastServo = lastDebug;
  lastAnalogRead = lastDebug;
}

void loop()
{
  checkAnalogReadTime();
}

void checkAnalogReadTime()
{
  if (micros() - lastAnalogRead > ANALOG_READ_PERIOD)
  {
    lastAnalogRead += ANALOG_READ_PERIOD;
    int joystickInputX = analogRead(JOYSTICK_X_PIN);
    int joystickInputY = analogRead(JOYSTICK_Y_PIN);

    bufferIndex++;
    bufferIndex &= BUFFER_LIMIT;

    bufferTotalX -= averagingBufferX[bufferIndex]; // out with the old
    bufferTotalY -= averagingBufferY[bufferIndex];
    averagingBufferX[bufferIndex] = joystickInputX;
    averagingBufferY[bufferIndex] = joystickInputY;
    bufferTotalX += averagingBufferX[bufferIndex]; // in with the new
    bufferTotalY += averagingBufferY[bufferIndex];

    checkServoTime();
  }
}


void checkServoTime()
// Called from "checkAnalogReadTime" function.
{
  if (micros() - lastServo > SERVO_PERIOD)
  {
    lastServo += SERVO_PERIOD;
    controlServo();
  }
}

void controlServo()
// Called from "checkServoTime" function.
{

  int average[2];
  int servoSpeed[2];
  

  average[0] = bufferTotalX >> POWER_OF_TWO_TO_AVERAGE; // it might be a good idea to make averageX global so it can be used elsewhere in program
  average[1] = bufferTotalY >> POWER_OF_TWO_TO_AVERAGE;

  for (int i = 0; i < 2; i++)
  {
    if (average[i] < LOW_CENTER_THRESHOLD)
    {
      servoSpeed[i] = (average[i] - LOW_CENTER_THRESHOLD) / POT_TO_SPEED_CONSTANT;
      // negative speed proportional to distance from center pot
    }
    else if  (average[i] > HIGH_CENTER_THRESHOLD)
    {
      servoSpeed[i] = HIGH_CENTER_THRESHOLD - average[i] / POT_TO_SPEED_CONSTANT;
                    // positive speed
    }
    else // pot in dead zone
    {
      servoSpeed[i] = 0;
    }
    servoPosition[i] += servoSpeed[i]; // but you should make sure "servoPosition" stays within endpoints
    if (servoPosition[i] > MAX_PULSE)
    {
      servoPosition[i] = MAX_PULSE;
    }
    else if (servoPosition[i] < MIN_PULSE)
    {
      servoPosition[i] = MIN_PULSE;
    }
    myServo[i].writeMicroseconds(servoPosition[i]);
  }

  checkDebugTime(average[0], average[1], servoPosition[0], servoPosition[1], servoSpeed[0], servoSpeed[1]);
}

void checkDebugTime(int averageX, int averageY, int servoOutputX, int servoOutputY, int speedX, int speedY)
// Called from "checkServoTime" function.
// Serial output slows down code execution.
// This method checks to see if it's time to
// display data.
// It would probably be a good idea to remove this section of code
// once the program is working as hoped and when serial
// output is now longer desired.
{
  if (micros() - lastDebug > DEBUG_PERIOD)
  {
    lastDebug += DEBUG_PERIOD;

    Serial.print(F("average = "));
    Serial.print(averageX, DEC);
    Serial.print(F(", "));
    Serial.print(averageY, DEC);
    Serial.print(F(", Servo = "));
    Serial.print(servoOutputX, DEC);
    Serial.print(F(", "));
    Serial.print(servoOutputY, DEC);
    Serial.print(F(", Spead = "));
    Serial.print(speedX, DEC);
    Serial.print(F(", "));
    Serial.println(speedY, DEC);
  }
}

The program should behave the same as before but now we can see the speed values (though come to think of it, this probably wouldn't have helped with the last set of data).

Here is a quick video to show you what the servos are doing

this is what I see.

Center
average = 493, 489, Servo = 2100, 2100, Spead = 0, 0
average = 493, 489, Servo = 2100, 2100, Spead = 0, 0

Moving joystick left to right
All the way left
average = 493, 1022, Servo = 2100, 2100, Spead = 0, 255
average = 493, 1022, Servo = 2100, 2100, Spead = 0, 255

All the way Right (Doesnt Change)
average = 493, 486, Servo = 2100, 2100, Spead = 0, 0
average = 493, 486, Servo = 2100, 2100, Spead = 0, 0

Moving down to up
All the way down
verage = 0, 19, Servo = 900, 900, Spead = -120, -115
average = 0, 19, Servo = 900, 900, Spead = -120, -115