Smooth moves on joystick

Hi! Pretty new to arduino and playing around with different modules. Just got a PS2 joystick module.

I tried the sparkfun example and it works greak. But how can I smooth out the start of the motion? If I move it it makes a jump and I cannot hit the area I want.

This is the code I am using:

/* HID Joystick Mouse Example
   by: Jim Lindblom
   date: 1/12/2012
   license: MIT License - Feel free to use this code for any purpose.
   No restrictions. Just keep this license if you go on to use this
   code in your future endeavors! Reuse and share.

   This is very simplistic code that allows you to turn the 
   SparkFun Thumb Joystick (http://www.sparkfun.com/products/9032)
   into an HID Mouse. The select button on the joystick is set up
   as the mouse left click. 
 */
#include <Mouse.h>
int horzPin = A0;  // Analog output of horizontal joystick pin
int vertPin = A1;  // Analog output of vertical joystick pin
int selPin = 2;  // select button pin of joystick

int vertZero, horzZero;  // Stores the initial value of each axis, usually around 512
int vertValue, horzValue;  // Stores current analog output of each axis
const int sensitivity = 500;  // Higher sensitivity value = slower mouse, should be <= about 500
int mouseClickFlag = 0;

void setup()
{
  pinMode(horzPin, INPUT);  // Set both analog pins as inputs
  pinMode(vertPin, INPUT);
  pinMode(selPin, INPUT);  // set button select pin as input
  digitalWrite(selPin, HIGH);  // Pull button select pin high
  delay(1000);  // short delay to let outputs settle
  vertZero = analogRead(vertPin);  // get the initial values
  horzZero = analogRead(horzPin);  // Joystick should be in neutral position when reading these

}

void loop()
{
  vertValue = analogRead(vertPin) - vertZero;  // read vertical offset
  horzValue = analogRead(horzPin) - horzZero;  // read horizontal offset

  if (vertValue != 0)
    Mouse.move(0, vertValue/sensitivity, 0);  // move mouse on y axis
  if (horzValue != 0)
    Mouse.move(horzValue/sensitivity, 0, 0);  // move mouse on x axis

  if ((digitalRead(selPin) == 0) && (!mouseClickFlag))  // if the joystick button is pressed
  {
    mouseClickFlag = 1;
    Mouse.press(MOUSE_LEFT);  // click the left button down
  }
  else if ((digitalRead(selPin))&&(mouseClickFlag)) // if the joystick button is not pressed
  {
    mouseClickFlag = 0;
    Mouse.release(MOUSE_LEFT);  // release the left button
  }
}

Please use code tags. See the how-to-use-this-forum post. The forum eats some of your code if you don't.

It may be a problem with the joystick itself if it's really sticky. Does changing the sensitivity number near the top help in any way?

In a youtube series by iforce2d named cheapass quad there is a section devoted to the transmitter build.
In this he uses a small oled driven by Arduino to check transmission of stick position and it shows the downfall of some elcheapo joysticks.

MorganS:
Please use code tags. See the how-to-use-this-forum post. The forum eats some of your code if you don't.

It may be a problem with the joystick itself if it's really sticky. Does changing the sensitivity number near the top help in any way?

Found the code button now. Was looking for it but didn't find it first.
Changing the sensitivity changed a bit but chaning it to high makes it to slow to move around and the problem is when it starts moving. Might be the joystick dunno how to tell.I would like a function that gradually builds up to the full sensitivity under the first second.

bluejets:
In a youtube series by iforce2d named cheapass quad there is a section devoted to the transmitter build.
In this he uses a small oled driven by Arduino to check transmission of stick position and it shows the downfall of some elcheapo joysticks.

Thx I will try to find it and check it out

Charkel:
I tried the sparkfun example and it works greak. But how can I smooth out the start of the motion? If I move it it makes a jump and I cannot hit the area I want.

Might need to use some code that puts a limit on the rate of change of velocity .... depending on the speed. That's if your system measures speed of a wheel etc. Eg.... if the machine is stationary (ie. measured wheel velocity is zero (or at some relatively slow speed), and then the command value (from joystick) increases by some amount within some short amount of time, then make the code ramp up the voltage to the motor more slowly (aiming to reach the target/command value eventually). So have some kind of velocity profiling condition happening. This would all need to be monitored maybe --- such as...if the velocity is zero, then have a software flag that marks this condition. And when the joystick level suddenly goes high, above some particular value (within some kind of time duration, like 1 millisec or something), then use code to ramp the voltage up more slowly ...... except for the case where the joystick is released .... or the command level is reduced (in which case...either cancel the ramping, or ramp towards the new target level. Some thought might have to be put into all this ..... to make the system behave satisfactorily, without glitchy or unwanted behaviour.

I started typing out a long modification to the above code and then I looked at the math again. With sensitivity set to 500 then the joystick has to move a long way to make any movement. 499/500 is zero when you’re using integers.

Set sensitivity much lower and slow down the loop. You only want the mouse to move in increments of 1 or 2 but not thousands of those per second. Maybe 20 per second and pushing the joystick further lets you move in steps of 1 to 50.

/* HID Joystick Mouse Example
   by: Jim Lindblom
   date: 1/12/2012
   license: MIT License - Feel free to use this code for any purpose.
   No restrictions. Just keep this license if you go on to use this
   code in your future endeavors! Reuse and share.

   This is very simplistic code that allows you to turn the 
   SparkFun Thumb Joystick (http://www.sparkfun.com/products/9032)
   into an HID Mouse. The select button on the joystick is set up
   as the mouse left click. 
 */
#include <Mouse.h>
int horzPin = A0;  // Analog output of horizontal joystick pin
int vertPin = A1;  // Analog output of vertical joystick pin
int selPin = 2;  // select button pin of joystick

int vertZero, horzZero;  // Stores the initial value of each axis, usually around 512
int vertValue, horzValue;  // Stores current analog output of each axis
const int sensitivity = 50;  // Higher sensitivity value = slower mouse, test and try different numbers
const unsigned long loopPeriod = 50; //milliseconds, use a larger number to slow down the number of moves per second
int mouseClickFlag = 0;

void setup()
{
  pinMode(horzPin, INPUT);  // Set both analog pins as inputs
  pinMode(vertPin, INPUT);
  pinMode(selPin, INPUT);  // set button select pin as input
  digitalWrite(selPin, HIGH);  // Pull button select pin high
  delay(1000);  // short delay to let outputs settle
  vertZero = analogRead(vertPin);  // get the initial values
  horzZero = analogRead(horzPin);  // Joystick should be in neutral position when reading these

}

void loop()
{
  static unsigned long lastLoop; //make it static so it's remembered between calls to this function
  vertValue = analogRead(vertPin) - vertZero;  // read vertical offset
  horzValue = analogRead(horzPin) - horzZero;  // read horizontal offset

  if (vertValue != 0)
    Mouse.move(0, vertValue/sensitivity, 0);  // move mouse on y axis
  if (horzValue != 0)
    Mouse.move(horzValue/sensitivity, 0, 0);  // move mouse on x axis

  if ((digitalRead(selPin) == 0) && (!mouseClickFlag))  // if the joystick button is pressed
  {
    mouseClickFlag = 1;
    Mouse.press(MOUSE_LEFT);  // click the left button down
  }
  else if ((digitalRead(selPin))&&(mouseClickFlag)) // if the joystick button is not pressed
  {
    mouseClickFlag = 0;
    Mouse.release(MOUSE_LEFT);  // release the left button
  }

  //Now the above code runs very quickly. We need to add a delay.
  //But a simple delay() will add to any unpredictable delays in the code.
  //So we look at the time that we last ran and wait until the loop period expires
  while(millis()-lastLoop<loopPeriod) {
    //any high-frequency code like motor controls can go here
  }
  lastLoop = millis();
}

MorganS:
I started typing out a long modification to the above code and then I looked at the math again. With sensitivity set to 500 then the joystick has to move a long way to make any movement. 499/500 is zero when you’re using integers.

Set sensitivity much lower and slow down the loop. You only want the mouse to move in increments of 1 or 2 but not thousands of those per second. Maybe 20 per second and pushing the joystick further lets you move in steps of 1 to 50.

/* HID Joystick Mouse Example

by: Jim Lindblom
  date: 1/12/2012
  license: MIT License - Feel free to use this code for any purpose.
  No restrictions. Just keep this license if you go on to use this
  code in your future endeavors! Reuse and share.

This is very simplistic code that allows you to turn the
  SparkFun Thumb Joystick (http://www.sparkfun.com/products/9032)
  into an HID Mouse. The select button on the joystick is set up
  as the mouse left click.
*/
#include <Mouse.h>
int horzPin = A0;  // Analog output of horizontal joystick pin
int vertPin = A1;  // Analog output of vertical joystick pin
int selPin = 2;  // select button pin of joystick

int vertZero, horzZero;  // Stores the initial value of each axis, usually around 512
int vertValue, horzValue;  // Stores current analog output of each axis
const int sensitivity = 50;  // Higher sensitivity value = slower mouse, test and try different numbers
const unsigned long loopPeriod = 50; //milliseconds, use a larger number to slow down the number of moves per second
int mouseClickFlag = 0;

void setup()
{
  pinMode(horzPin, INPUT);  // Set both analog pins as inputs
  pinMode(vertPin, INPUT);
  pinMode(selPin, INPUT);  // set button select pin as input
  digitalWrite(selPin, HIGH);  // Pull button select pin high
  delay(1000);  // short delay to let outputs settle
  vertZero = analogRead(vertPin);  // get the initial values
  horzZero = analogRead(horzPin);  // Joystick should be in neutral position when reading these

}

void loop()
{
  static unsigned long lastLoop; //make it static so it’s remembered between calls to this function
  vertValue = analogRead(vertPin) - vertZero;  // read vertical offset
  horzValue = analogRead(horzPin) - horzZero;  // read horizontal offset

if (vertValue != 0)
    Mouse.move(0, vertValue/sensitivity, 0);  // move mouse on y axis
  if (horzValue != 0)
    Mouse.move(horzValue/sensitivity, 0, 0);  // move mouse on x axis

if ((digitalRead(selPin) == 0) && (!mouseClickFlag))  // if the joystick button is pressed
  {
    mouseClickFlag = 1;
    Mouse.press(MOUSE_LEFT);  // click the left button down
  }
  else if ((digitalRead(selPin))&&(mouseClickFlag)) // if the joystick button is not pressed
  {
    mouseClickFlag = 0;
    Mouse.release(MOUSE_LEFT);  // release the left button
  }

//Now the above code runs very quickly. We need to add a delay.
  //But a simple delay() will add to any unpredictable delays in the code.
  //So we look at the time that we last ran and wait until the loop period expires
  while(millis()-lastLoop<loopPeriod) {
    //any high-frequency code like motor controls can go here
  }
  lastLoop = millis();
}

Tat actually made the accuracy much better! But now it’s moving on its own even tho I stop moving the stick :confused: Will try to look more into the code tomorro. 6am need to sleep lol