# Reducing the sentivity of the joystick in easyC Pro

possible or not?

I read that you’ll need to change the joystick’s linear function to a cubic one?

so how do you do that in easyC?

I think you’ll need a look up table to save processing power calculating it…so how do you implement that in easyC?
also I’m a newbie, so try to make it so that a 10 year old could understand it or you can upload the easyC file =D

thanks for the help,
neurovirus

There are two things you can do fairly easily that might work for you:

1. Establish a deadband for your joystick. A deadband gives an area for your joystick that won’t move the robot. For example you can set a deadband of 20 so that unless your joystick moves past 147 or 107, then it sends 127 to the robot. When past 147 input joystick -20 to the robot. When past 107 input joystick + 20 to the robot. This solution is easy, but you loose the extremes and your bot may still be too twitchy.

2. Use Excel to generate your lookup table. An array of 256 values. You may prefer to use a hyperbolic function so that values close to joystick center have very little effect, but extreme values will input full power to your motors. You could combine this with your deadband for best effect. Save the file as a comma delimited text for easier transfer into EasyC.

Hope this helps!

Dan

I have been playing around with different functions for the joysticks as well. One method that I have been playing around with is a simple linear function that reduces the overall speed of the bot, with the deadband in there, and allowing it to go to full speeds when the driver holds down a button. I know you are using easy c, but this should be understandable:

``````
if(p1_sw_trig==1)
{
pwm01=Set_Neutral(p1_y);
pwm02=Set_Neutral(p2_y);
}

else
{
pwm01 = Set_Neutral(  ( (.44)*p1_y)+70  );
pwm02 = Set_Neutral(  ( (.44)*p2_y)+70  );
}

``````

Set_Neutral is my deadband function. So right now the maximum forward I can go is 181 and opposite with the reverse. If the driver wants to go full speed ahead right now they just hold down the left trigger. I have heard that too much floating point arithmetic puts more strain on the processor though, so just don’t use too much. Hope this helps

This was last year’s drive code:

``````if(p1_sw_trig && p2_sw_trig) {
Left(p1_y);
Right(p2_y);
} else {
Left(Scale_Offset(p1_y,driveScale);
Right(Scale_Offset(p2_y,driveScale);
}

//later, not in the routine that loops every 26.2 ms...

int driveScale = 3;

int Scale_Offset(int speed, int scaleFactor) {
return ((speed-127)/scaleFactor) + 127;
}
``````

It worked really well for us :]

This is how this would look in easyC

``````
void OperatorControl ( void )
{
int joy_y_port1;
int joy_y_port2;
unsigned char left_output;
unsigned char right_output;
while ( 1 )
{
joy_y_port1 = GetOIAInput ( 1 , 2 ) ;  // Get Joystick Data
joy_y_port2 = GetOIAInput ( 2 , 2 ) ;  // Get Joystick Data
/* Remove 127 Setting the joystick scale from 0-255 to -127 0 127.
Then Divide the output in half and then add 127 back to return the
scale to 0-255.*/
left_output  = ((joy_y_port1 - 127 ) / 2) +127 ; //See Above
right_output  = ((joy_y_port2 - 127 ) / 2) +127 ; // See Above
SetPWM ( 1 , left_output ) ;  //Send left output to PWM1
SetPWM ( 2 , right_output ) ; //Send right output to PWM 2
}
}

``````

Instead of using a floating point constant like this:

``````foo = bar * 0.44;
``````

you can do this:

``````foo = bar * 44 / 100;
``````

Note that the following, with the divide operation first, is not the same, because integer division throws away any remainder:

``````foo = bar / 100 * 44; // BAD IDEA!
``````

Even better (if bar is always positive) you could do this:

``````foo = (bar * 113) >> 8;
``````

The " >> 8 " divides the result by 256 (shifts the bits to the right eight places). The value 113 is .44 times 256. Be sure to use an int type for bar (16 bits), not a char type (8 bits); The shift operator " >> " behaves unpredictably for negative numbers.

Would simply configuring a Tank or Arcade function remove the need for all of that code, or is it necessary to do it like that?

You can simply use a tank or arcade function to drive your robot. The poster in this case wanted to “numb” the output form the joystick for what ever reason so these are examples of how it can be done. This is defiantly not required…

This was brought up in a previous thread. One of the easiest ways to do this is :

``````
#define Motor_Max (put your maximum value here)
#define Motor_Min (put your minimum value here)

``````

#define statements go at the top of your code

``````
if (GetRxInput(1,1) > Motor_Max)
SetMotor(1, Motor_Max); //Don't go any faster than your max

else if (GetRxInput(1,1) < Motor_Min)
SetMotor(1, Motor_Min); //Likewise, don't let the motor go slower than the min, regardless of what the joystick says.

else
SetMotor(1, GetRxInput(1,1)); //If the joystick is not above the max or below the minimum, assign it directly to the input.

``````

When you have the x and y coordinates, just multiply them by themselves minus a constant and then take the square root. It should look like:

``````joystickx=joystickx*(joystickx-2);
joystickx=squareroot(joystickx);
joysticky=joysticky*(joysticky-2);
joysticky=squareroot(joysticky);
``````

then just use the coordinates as you normally would. This will reduce the sensitivity a little but will still allow extremes.