pythonhidjoystick

How to Read Joystick Input from Logitech Extreme 3D Pro in Python?


I'm working on a Python program to read inputs from a Logitech Extreme 3D Pro joystick. I am able to receive raw data from the joystick, but I'm struggling to correctly interpret the X and Y values from this data.

Problem:

I have raw data as shown in the attached image. From the array, each value represents a different key or axis, but I'm having trouble identifying which values correspond to X and Y axis movements. Specifically, I suspect that array[1] and array[2] are the X and Y values, but the readings are inconsistent and don't seem to correlate with the joystick movements. code output

Code:

import pywinusb.hid as hid
from time import sleep
from msvcrt import kbhit

def sample_handler(data):
    print("Raw data: {}".format(data))

# Known Logitech vendor_id
vendor_id = 0x046D  # Logitech

# Find Logitech HID devices
devices = hid.HidDeviceFilter(vendor_id=vendor_id).get_devices()

if not devices:
    print("No Logitech device found.")
    exit()

# Select the device
device = devices[0] if len(devices) == 1 else None
if not device:
    print("Multiple Logitech devices found. Please select one:")
    for i, dev in enumerate(devices):
        print(f"{i}: {dev.product_name} (Product ID: {dev.product_id:04X})")
    selection = int(input("\nEnter the number of the device to select (0-{}): ".format(len(devices) - 1)))
    device = devices[selection]
else:
    print(f"Automatically selected device: {device.product_name}")

# Open the device and set the data handler
try:
    device.open()
    device.set_raw_data_handler(sample_handler)
    print("Waiting for data... Press any key to stop.")
    while not kbhit() and device.is_plugged():
        sleep(0.5)
finally:
    device.close()

Questions:

  1. How can I correctly interpret the X and Y axis values from the raw data I receive?
  2. Are there alternative methods for reading joystick input in Python besides using the inputs library?
  3. I've heard about using HID descriptors to understand joystick control values. How can I use HID descriptors to achieve this?

HID Descriptors:

USB Input Device

Connection Status   Device connected
Current Configuration   1
Speed   Full
Device Address  3
Number Of Open Pipes    1
Device Descriptor Extreme 3D pro
Offset  Field   Size    Value   Description
0   bLength 1   12h 
1   bDescriptorType 1   01h Device
2   bcdUSB  2   0200h   USB Spec 2.0
4   bDeviceClass    1   00h Class info in Ifc Descriptors
5   bDeviceSubClass 1   00h 
6   bDeviceProtocol 1   00h 
7   bMaxPacketSize0 1   08h 8 bytes
8   idVendor    2   046Dh   Logitech, Inc.
10  idProduct   2   C215h   
12  bcdDevice   2   5711h   57.11
14  iManufacturer   1   01h "Logitech"
15  iProduct    1   02h "Extreme 3D pro"
16  iSerialNumber   1   03h "00000000002A"
17  bNumConfigurations  1   01h 
Configuration Descriptor 1 Bus Powered, 100 mA
Offset  Field   Size    Value   Description
0   bLength 1   09h 
1   bDescriptorType 1   02h Configuration
2   wTotalLength    2   0022h   
4   bNumInterfaces  1   01h 
5   bConfigurationValue 1   01h 
6   iConfiguration  1   04h "HID Config"
7   bmAttributes    1   80h Bus Powered
4..0: Reserved      ...00000    
5: Remote Wakeup        ..0.....    No
6: Self Powered     .0......    No, Bus Powered
7: Reserved (set to one)
(bus-powered for 1.0)       1.......    
8   bMaxPower   1   32h 100 mA
Interface Descriptor 0/0 HID, 1 Endpoint
Offset  Field   Size    Value   Description
0   bLength 1   09h 
1   bDescriptorType 1   04h Interface
2   bInterfaceNumber    1   00h 
3   bAlternateSetting   1   00h 
4   bNumEndpoints   1   01h 
5   bInterfaceClass 1   03h HID
6   bInterfaceSubClass  1   01h Boot Interface
7   bInterfaceProtocol  1   00h 
8   iInterface  1   00h 
HID Descriptor
Offset  Field   Size    Value   Description
0   bLength 1   09h 
1   bDescriptorType 1   21h HID
2   bcdHID  2   0111h   1.11
4   bCountryCode    1   00h 
5   bNumDescriptors 1   01h 
6   bDescriptorType 1   22h Report
7   wDescriptorLength   2   007Ah   122 bytes
Endpoint Descriptor 81 1 In, Interrupt, 1 ms
Offset  Field   Size    Value   Description
0   bLength 1   07h 
1   bDescriptorType 1   05h Endpoint
2   bEndpointAddress    1   81h 1 In
3   bmAttributes    1   03h Interrupt
1..0: Transfer Type     ......11    Interrupt
7..2: Reserved      000000..    
4   wMaxPacketSize  2   0007h   7 bytes
6   bInterval   1   01h 1 ms
Interface 0 HID Report Descriptor Joystick
Item Tag (Value)    Raw Data
Usage Page (Generic Desktop)    05 01 
Usage (Joystick)    09 04 
Collection (Application)    A1 01 
    Collection (Logical)    A1 02 
        Report Count (2)    95 02 
        Report Size (10)    75 0A 
        Logical Minimum (0) 15 00 
        Logical Maximum (1023)  26 FF 03 
        Physical Minimum (0)    35 00 
        Physical Maximum (1023) 46 FF 03 
        Usage (X)   09 30 
        Usage (Y)   09 31 
        Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02 
        Report Size (4) 75 04 
        Report Count (1)    95 01 
        Logical Maximum (7) 25 07 
        Physical Maximum (315)  46 3B 01 
        Unit (Eng Rot: Degree)  66 14 00 
        Usage (Hat Switch)  09 39 
        Input (Data,Var,Abs,NWrp,Lin,Pref,Null,Bit) 81 42 
        Unit (None) 65 00 
        Report Size (8) 75 08 
        Logical Maximum (255)   26 FF 00 
        Physical Maximum (255)  46 FF 00 
        Usage (Rz)  09 35 
        Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02 
        Push    A4 
        Report Count (8)    95 08 
        Report Size (1) 75 01 
        Logical Maximum (1) 25 01 
        Physical Maximum (1)    45 01 
        Usage Page (Button) 05 09 
        Usage Minimum (Button 1)    19 01 
        Usage Maximum (Button 8)    29 08 
        Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02 
        Pop B4 
        Usage (Slider)  09 36 
        Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02 
        Report Count (4)    95 04 
        Report Size (1) 75 01 
        Logical Maximum (1) 25 01 
        Physical Maximum (1)    45 01 
        Usage Page (Button) 05 09 
        Usage Minimum (Button 9)    19 09 
        Usage Maximum (Button 12)   29 0C 
        Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02 
        Report Count (4)    95 04 
        Input (Cnst,Ary,Abs)    81 01 
    End Collection  C0 
    Collection (Logical)    A1 02 
        Report Count (4)    95 04 
        Report Size (8) 75 08 
        Logical Maximum (255)   26 FF 00 
        Physical Maximum (255)  46 FF 00 
        Usage Page (Vendor-Defined 1)   06 00 FF 
        Usage (Vendor-Defined 1)    09 01 
        Feature (Data,Var,Abs,NWrp,Lin,Pref,NNul,NVol,Bit)  B1 02 
    End Collection  C0 
End Collection

Additional Information:

I know libraries like pywinusb.hid, but I want to explore other options if possible.

Any guidance on creating a program to parse and interpret joystick values using HID descriptors automatically would also be appreciated.


Solution

  • I have found a package called Pygame which is used to easily read remote data. It automatically reads the HID descriptor to determine the number of buttons and analogue controls.

    Using the Pygame package is a good solution for this issue.