MHeironimus / ArduinoJoystickLibrary

An Arduino library that adds one or more joysticks to the list of HID devices an Arduino Leonardo or Arduino Micro can support.
GNU Lesser General Public License v3.0
2.06k stars 403 forks source link

Troubles with 15th and 16th bit in joystick axis #250

Open andreasdahl1987 opened 1 year ago

andreasdahl1987 commented 1 year ago

I'm having an issue with using 16 bit values in joystick axis. I'm using custom PCB with 32U4s. Two of the joystick axis I'm using as bit fields for conveying information about the controller and special button states. I read out the axis values with an application (SimHub) and pack out the information in the bit fields to create elements in a sim racing dashboard UI.

The issue I'm having is with the 15th and 16th bit of the joystick value. If these bits are 1, it looks like the whole value is subtracted by 1. So '0100000000000000' from my joystick returns 16384, and '0100000000000001' returns the same number, 16384. I've tested this with several applications reading joystick values, they all come out the same. So it seems like there is something going wrong in the library. I've printed my bit fields just before setting the axis, and nothing is off there.

Any values that only uses the first 14 bits work perfectly.

If this was just a clutch being 1 value off, of course it isnt a problem. But when I use it as a bit field this screws everything up :( I can of course avoid the last two bits, but I'd like to have to option to use them.

I've set the joystick range to 0 - 65535 Joystick.setZAxisRange(0, 65535); //Making bit fields 16 bit and used exclusively int32_t type for anything that goes into joystick axis or calculation of these values

Below are some readouts comparing the value from serial monitor and the value read out by windows application.

Looks good Below 15th bit everything is fine Minus 1 16th bit active Effectively -1 Reads 2nd bit as 1st bitJPG Doesnt read 1st bit 15th bit No bits .

MHeironimus commented 1 year ago

Can you add a comment with the relevant source code?

andreasdahl1987 commented 1 year ago

Thanks for the fast reply. The source code is about 5000 lines over 25 files. And much of it is relevant. Here is what happens to the joystick axis in essence:

These are called as global variables:

int32_t encoderField = 0; int32_t buttonField = 0;

In the setup() scope.

    Joystick.setZAxisRange(0, 65535); //Making bit fields 16 bit
    Joystick.setYAxisRange(, 65535);

In the loop scope:

    encoderField = 0;
    buttonField = 0;

//Loads of fuction calls that alter the values of encoderField and buttonField

    Joystick.setZAxis(encoderField);
    Joystick.setYAxis(buttonField);

By the way, I checked with a pre-march 28th version of your library, and it all works. I'm then using:

    Joystick.setZAxisRange(-32768, 32767); //Making bit fields 16 bit
    Joystick.setYAxisRange(-32768, 32767);

and

    Joystick.setZAxis(encoderField - 32767);
    Joystick.setYAxis(buttonField - 32767);

This version is before you changed the joystick axis to unsigned value. -32 767 to 32767 is one less than 0 to 65535. Could there be something there?

andreasdahl1987 commented 1 year ago

No actually, the setup I commented for the earlier version of the library is not working perfectly either. Works as long as bit 15 and bit 16 are not both 1 at the same time.

andreasdahl1987 commented 1 year ago

And by using

   Joystick.setZAxisRange(-32767, 32767); //Making bit fields 16 bit
   Joystick.setYAxisRange(-32767, 32767);

It behaves like I first described, but now only the 16th bit having issues, the 15th bit is fine.

MHeironimus commented 1 year ago

I'll have to investigate this further. I have only thoroughly tested using 10-bit values, since Arduino boards only contain a 10-bit analog to digital converter.

andreasdahl1987 commented 1 year ago

Great, thanks for looking into this 👍

MirkMandulisMinute commented 2 weeks ago

Hello, someone has any news ? In my side, when I go from 0 to 32768 on an axis, I have only 128 values .... But from 32768 to 65535, I have all values.