1

After searching for hours, I cannot seem to find a way to read a joystick's axis and buttons in Windows using Python. I don't want to use Pygame due to the fact it has a massive overhead and size. Also, the only code I could find can only read XBox controllers. I've tried using the XInput dll, but it doesn't recognize the joystick.

If anyone can point me in the right direction of what library to use, that would be great.

  • Overhead is an understandable concern; however, the only real dependency that `pygame` would add is a reliance on SDL. Other libraries you could try are `pysdl2` (similar overhead, just on the more modern SDL2, which has a GameController API that might prove useful which basically maps any controller to the xbox360 layout), `pyglet` (which advertises itself as having no external dependencies or installation requirements). These all bring in window management, rendering, audio, and other components that you may or may not need, however. Curious to see what else is out there... – CodeSurgeon Oct 02 '17 at 01:38
  • You can read the joystick data by using the winmm.dll file, I've done this and most functions work fine. – Dudi b Apr 07 '18 at 13:32

1 Answers1

0

Overhead is one thing, another matter is that pygame requires the window to have focus. Which is a real showstopper for me.

Here is an example using pywinusb:

import pywinusb.hid as hid

from time import sleep
from msvcrt import kbhit


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


devices = hid.HidDeviceFilter().get_devices()
print(' i  par       ser  ven  prd  ver  name')
for i, dev in enumerate(devices):
    print("{0:> 3} {1:> 2} {2:>9} {3:04X} {4:04X} {5:04X}  {6:}"
          .format(i, dev.parent_instance_id, dev.serial_number, dev.vendor_id, 
                  dev.product_id, dev.version_number, dev.product_name))

selection = int(input("\nEnter number to select device (0-{})\n".format(i)))
device = devices[selection]
print("You have selected {}".format(device.product_name))
try:
    device.open()
    # set custom raw data handler
    device.set_raw_data_handler(sample_handler)

    print("\nWaiting for data...\nPress any (system keyboard) key to stop...")
    while not kbhit() and device.is_plugged():
        # just keep the device opened to receive events
        sleep(0.5)
finally:
    device.close()

If this does not suit your purpose, you might want to have a look here: https://gist.github.com/rdb/8883307

wittrup
  • 1,535
  • 1
  • 13
  • 23