# How can I compensate for a joysticks offset value in neutral position?

I have a joystick that outputs the values 0 - 4095. I want to map these values in this fashion (Yes, the reversed mapping is intended):

``````outputValue = map(inputValue, 4095, 0, -2048, 2047);
``````

However, the neutral central position of the joystick is offset, outputting 145 instead of 0.

Is there a way to map these values - taking the offset value in account - and still have the output values ranging from -2048 to 2047? I fail to do this with the map() function alone, and could need some help with the specific math involved.

• your joystick may have a mechanical adjustment Sep 7, 2023 at 15:36

You can only approximate it, you have to sacrifice something.

The basic problem is that your input range is asymmetric in respect to the mid point. Let's visualize it this way (with a bit of visual exaggeration):

``````min                     mid      max
0----------------------2193-----4095
``````

Another problem is that the whole range 0..4095 may not be physically reachable by the joystick, so your usable range may actually look like this:

``````min                mid        max
433---------------2193-------3722
``````

So, to calibrate your joystick, you need to measure the min, mid and max points that you can physically reach with exactly that joystick on the input scale (joysticks are analog devices, so their actual ranges can differ from joystick to joystick and even from axis to axis in the same physical joystick).

Now, if you have these numbers (I call those calibration values `joy_min`, `joy_mid` and `joy_max`), you need to `map` both parts of your range separately:

``````if( joy_input < joy_mid ) {
output = map(joy_input, joy_min, joy_mid, -2048, 0);
} else {
output = map(joy_input, joy_mid, joy_max, 0, 2047);
}
``````

The downside is that any step in the output may represent a slightly different distance in the movement, depending on whether you are currently lower or higher than the measured midpoint. But I expect that to be negligible.

Also, keep in mind that this is only for one axis of the joystick. You may need completely different calibration values for the other axis. In addition, you may want to implement a "dead zone" around the midpoint, i.e. always returning `output = 0` for `joy_mid-10 < joy_input < joy_mid+10` or something like that.

And as the joystick range may drift (with temperature, age, etc...) and `map` does not constrain the output range, it might be a good idea to apply a `output = constrain(output, -2048, 2047)` afterwards.

(In my code, I assume that you want to map 0..4095 to -2048..2047 as you say in the text; but in your code, you map 4095..0 to -2048..2047, basically flipping the direction. If that part of your code is correct and the text is not, just swap -2048 with 2047 in my code.)

• Thanks for your reply. With regards to the reversed mapping, it's intended. I've updated my question.
– Erik
Sep 7, 2023 at 7:22