Joystick. How to add XX offset angle to X Y for 12 degree offset


Im going to add a angle offset to my stick as it is in the real F16 with a 12 degree rotation offset so when i pull the stick a little back and left it will be like i am pulling straight back. I really have no clue how to do this and i have severe working memory issues so as soon as i look away from a text its pretty much gone so i need very clear and easy to follow examples.

If anyone could help me with this is would be most grateful.

//#include <AnalogSmooth.h>

#include <Joystick.h>
#include <Smoothed.h>

For the true false flags, use this list. Its all in  Joystick.h
    bool includeXAxis = true,
    bool includeYAxis = true,
    bool includeZAxis = true,
    bool includeRxAxis = true,
    bool includeRyAxis = true,
    bool includeRzAxis = true,
    bool includeRudder = true,
    bool includeThrottle = true,
    bool includeAccelerator = true,
    bool includeBrake = true,
    bool includeSteering = true);
  true, true, false, false, false, false,
  true, true, false, false, false);
// Variable

#define YfAxisPin A0
#define YbAxisPin A1
#define XlAxisPin A2 // needed to reverse
#define XrAxisPin A3

// Add pins for the different ranges. Just using a variable for now. 
// Max force from trigger height. 
// Max force for y is about 8kg
// Max force for X left is about 8kg  X right is about 6kg 
// Max force in % 
int YMaxforce = 100;
int XMaxforce = 100;

// add offset to X Y 
int Offset = 0;

// Add smoothing for all axis 
Smoothed <int> YfAxis;
Smoothed <int> YbAxis;
Smoothed <int> XlAxis;
Smoothed <int> XrAxis;

int SmoothValue = 30;

// init joystick libary
void setup() {
  // Ranges are 1023 by default
  Joystick.setYAxisRange(0, 2048);
  Joystick.setXAxisRange(0, 2048);

// Begin smoothing.     
    YfAxis.begin(SMOOTHED_AVERAGE, SmoothValue);
    YbAxis.begin(SMOOTHED_AVERAGE, SmoothValue);
    XlAxis.begin(SMOOTHED_AVERAGE, SmoothValue);
    XrAxis.begin(SMOOTHED_AVERAGE, SmoothValue);

void loop() {

// Read the value from the sensor
  int YfAxisValue = analogRead(YfAxisPin);
  int YbAxisValue = analogRead(YbAxisPin);
  int XlAxisValue = analogRead(XlAxisPin);
  int XrAxisValue = analogRead(XrAxisPin);

 // Add the new value to both sensor value stores

// ******** Y Axis ***************

  int YfAxisCValue = YfAxis.get();
  int YbAxisCValue = YbAxis.get();
  int YAxisfront = YbAxisCValue;
  // remap Yaxisback
   YbAxisCValue = map(YbAxisCValue, 1023, 0, 0, 1023);
  int  YcombinedValue = YfAxisCValue + YbAxisCValue;
// Set joystick Axis
  Joystick.setYAxis(YcombinedValue + Offset);
 // Serial.println (String("Yf:") + YfAxisCValue);
 // Serial.println (String("Bf:") + YbAxisCValue);
 // Serial.println (String("Y combined:") + YcombinedValue);
 /* // rememnats from another stick, just use it to remember
     if (throttleValue > 666) {
    throttleValue = 670;
    else if (throttleValue < 273) {
    throttleValue = 270;
    if (lastThrottleValue != throttleValue) {
     lastThrottleValue = throttleValue;
// *********  X axis  **************

  int XlAxisCValue = XlAxis.get(); 
  int XrAxisCValue = XrAxis.get(); 

  XrAxisCValue = map(XrAxisCValue, 1023, 0, 0, 1023);
  int  XcombinedValue = XlAxisCValue + XrAxisCValue;

  // Set joystick Axis
  Joystick.setXAxis(XcombinedValue + Offset);
 // Serial.println (String("Xl:") + XlAxisCValue);
 // Serial.println (String("Xr:") + XrAxisCValue);
 // Serial.println (String("X combined:") + XcombinedValue);

 // Serial.println (String("X:") + XAxisCValue);
   if (brake < 0 or brake < 8) {
    brake = 0;
   if (lastBrakeValue != brake) {
     lastBrakeValue = brake;


why are there 2 sensors per axis and not just one

just add a "trim" value to the reading

I had to fix a strain gauge joystick and since i only had amps with 1x strain gauges on each i couldnt do a proper wheatstone bridge. Also since its only 10 bit i decided to use the 4 on the stick. Front back, Left right and double the resolution. That's why i invert one of them so one is pos and one neg. Then combine.

I would appreciate it if you could elaborate on just add "trim"

Thank you

  int XlAxisValue = analogRead(XlAxisPin) + xTrim;
  int XrAxisValue = analogRead(XrAxisPin) + xTrim;

While i very much appreciate the help pay attention to "i need very clear and easy to follow examples." Just assume im clueless and need a proper explanation of what, how/why it works

From how i understand this I dont see how adding + xTrim with say a value of 20 to both those would rotate the whole axis in such a way. It will just move the center point for X. Or in this case since i combine these two they will cancel each other out.

int XlAxisValue = analogRead(XlAxisPin) + Offset; int XrAxisValue = analogRead(XrAxisPin) + Offset;

Serial monitor with offset 300

X combined:1023

you'll have to better explain your hardware

i fly gliders. there's a trim setting on the stick that adjusts where the springs hold the stick without any force applied.

presumably your stick has something similar. there's some reading (analogRead()) that results without any pressure on the stick if you add some value to the measure or where is it used then the unforced value will have an offset.

can't imagine why there are two X axis values. what is the final x value

you can argue that you'll lose some range. then i need a better understanding of both the electrical and mechanical design

Ok, for arguments sake to make things easier lets just work from Y X being one. I shouldnt have any issue adjusting that.

Ill do a brief explanation though so its easier to understand. Keep in mind this is a force sensing stick with strain gauges. Not a moving standard joystick. Check these links

This is more of a work around as they should most likely be in a wheat stone bridge working as one with a different amp and so on but i dont have access to all that.

Since the range of the strain gauge is limited from 0.5-4.5v ive choosen to increase the resolution and range of the stick by setting all amps to 0v.Y ou set the center V with a pot. and setting it to 0 will give me only one working direction. Then i get twice the resolution and gain a bit of range. The main thing is for extra range in the form of possible kg on the stick as the amp will max out before i reach the 9kg of pull. Also since they are on the same side of the metal plate they will just cancel each other out as one expands and the other contracts. That's why i use map() to invert one of them before i combine them to have one axis. Now the top will function as positive and the bottom one will do negative.

Yb low Yb max c Yf low Yf full
0__________1023_________ 2048

Its a bit tricky to visualize how it interacts but here you can see it.

Im not looking to add a Trim like you have in real aircraft such as a glider. The tendency you have when using a force sensing stick with 20 lbs force on the Y axis is to pull slightly towards your body and this is why there is a 12 degree rotation offset (Rotating everything) within the FLCS software on the f16. The easiest way to picture this is if you just set your real stick at a 12 degree angle but instead of doing that you keep the real stick at 0 degree and do it within the software instead.

ok not trim.

my understanding this is compensation for the pilot not pulling straight back into his gut but toward the shoulder.

i believe these would be the x values (-10, 10) for y values from 10 to -10 (showing a # of angles to make sure we're on the same page)

      y    -15    -12     -9     -6     -3      0 deg
     10  -2.68  -2.13  -1.58  -1.05  -0.52   0.00
      9  -2.41  -1.91  -1.43  -0.95  -0.47   0.00
      8  -2.14  -1.70  -1.27  -0.84  -0.42   0.00
      7  -1.88  -1.49  -1.11  -0.74  -0.37   0.00
      6  -1.61  -1.28  -0.95  -0.63  -0.31   0.00
      5  -1.34  -1.06  -0.79  -0.53  -0.26   0.00
      4  -1.07  -0.85  -0.63  -0.42  -0.21   0.00
      3  -0.80  -0.64  -0.48  -0.32  -0.16   0.00
      2  -0.54  -0.43  -0.32  -0.21  -0.10   0.00
      1  -0.27  -0.21  -0.16  -0.11  -0.05   0.00
      0  -0.00  -0.00  -0.00  -0.00  -0.00   0.00
     -1   0.27   0.21   0.16   0.11   0.05  -0.00
     -2   0.54   0.43   0.32   0.21   0.10  -0.00
     -3   0.80   0.64   0.48   0.32   0.16  -0.00
     -4   1.07   0.85   0.63   0.42   0.21  -0.00
     -5   1.34   1.06   0.79   0.53   0.26  -0.00
     -6   1.61   1.28   0.95   0.63   0.31  -0.00
     -7   1.88   1.49   1.11   0.74   0.37  -0.00
     -8   2.14   1.70   1.27   0.84   0.42  -0.00
     -9   2.41   1.91   1.43   0.95   0.47  -0.00
    -10   2.68   2.13   1.58   1.05   0.52  -0.00

if this understanding is correct the next step is how to implement this.

my understanding would be for a y value of 7, an x value of -1.49 should be considered zero.


This looks correct to me. Thanks! Looking forward to see how this would be implemented

again, i assume that ultimately there's a single x and y value, presumably signed such that left or back values are negative.

for the y value, there's an offset added to the x value that shifts its zero point left or right.

knowing the angles, the coefficient, K, for determining the x offset from the y value is the sine of the angle / cosine. for 12 degrees, K is 0.213. the xOffset = 0.213 * y and x becomes x + K * y.

since x and y as well as K are signed, when the stick if forward and being pushed away from the pilots shoulder to the left (a negative x value) , adding the offset moves x closer to zero.

when the stick is back and pulled to the right toward the pilots shoulder the negative y * K value shifts x to the left, closer to zero

hope this make sense and is what you're looking for

seeing the code determining the pitch and roll would help

Thank you for the update. We are on the same page.

X axis: Full left stick is 0 full right is 2048 . Yaxis: Full forward stick is 0 full back is 2048
In DI view its the same but windows calibrate will see it like this. Both seems to be registering it as 16 bit.

windows sees it

I am using this library and i set the axises Joystick.setYAxis(YcombinedValue);

are you following any of the math?

there are the x offsets for positive only values of stick position, max 1023

      0   -512 -108.8    403
    128   -384  -81.6    430
    256   -256  -54.4    458
    384   -128  -27.2    485
    512      0    0.0    512
    640    128   27.2    539
    768    256   54.4    566
    896    384   81.6    594
   1024    512  108.8    621

i'm guessing that the joystick code you want to modify provides two positive values, x and y to the flight simulator and you would like to "adjust" the x value before it is given the simulator?

I have a fair idea of what is going but yeah memory issues, i need a week for even the simplest equation. Normal people can hold 3-4 things in their working memory and i can hold 1 and 2 once its in my long term. Equations can be a bit of a B... So really appreciate your amazing help here.

You are correct. It will give two positive values and I need to adjust the axis value before its given to the sim so that it compensates. Everything you have posted looks correct to me. Im assuming we can just use the same table to move the X too so the whole system is shifted.

Would it also be possible to easily generate this table for any angle and range with two variables in angle, int range? Looks like you have that figured out already really


for any angle there's a coefficient, K

    K = sin(ang) / cos(ang)

and then for every y, there's an x offset added to x

   x -= K * y

range issues still need to be sorted out

presumably angle should be negative (to the left) or positive

(forward stick results in x further to the left, smaller smaller value. want to add a positive value to compensate (subtract -108). back stick results in larger x value, need to subtract adjustment from it (subtract 108))

You may be doing, but the way I would solve this is

Consider the point x, y that is the joystick input departure from the origin.

Convert to polar coordinates.

Rotate that vector by 12 degrees (add 12 to theta) and

convert to back rectangular coordinates.

I’m not at the big rig, ifn this is what you are actually doing, ok, if not I’ll try to put it in codely terms L8R.

It may be more math than the processor has time for. In that case some table lookup or close enough lower order approximations isn’t suffice.

This would be equivalent to physically rotating the entire joystick, which is what Imthink you are asking for.


It is somewhat more simple, see

again when I am not typing with my nose I’ll code it if you haven’t done by then.

No trig, as the angle is constant.


that's essentially what's being suggested for a specific angle using a pre-computed coefficient using sine/cosine.

Yeah, I thought maybe. But I only saw one axis being handled, it didn’t seem to be rotating the joystick just messing with X.

Which may indeed be all and what the OP wants. Or I am going to find Y when I read the whole thread again after waking up a bit. :sleeping:


Appreciate the input. Its good to have you smart guys around! Ideally the whole system X and Y will be rotated by 12 degrees.

are you saying the y values should also be adjusted?

and then how accurate do you need this to me? you're just trying to grossly compensate for a person's body position relative to the stick, right?