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

not working in linux at all #230

Open makerio90 opened 2 years ago

makerio90 commented 2 years ago

i'm trying build a flight simulator wireless dongle. but for some reason, Linux (manjaro, i3) does not detect it at all. any idea why?

ColinPitrat commented 8 months ago

I think I have a similar problem.

I found the mention of the usbhid.quirks in the FAQ, which I had to adapt to pass it to the kernel's command line because AFAIU the /boot/cmdline.txt is only for raspbian. But it didn't help. Which is probably not surprising because the symptoms I observe do not correspond to what's mentioned in the blog post

When I plug the Arduino Micro, I do see a /dev/event/js0 appear. When I cat /dev/event/js0 | hexdump -C I do see some updates when I move my joystick.

But the gamepad doesn't appear in games (e.g. SuperTux Kart, which automatically detects regular joysticks) and is not recognized by Gamepad Tester either (which also recognize without any issue my regular joystick).

The output of lsusb -v for the Arduino is the following:

Bus 005 Device 005: ID 2341:8037 Arduino SA Arduino Micro
Device Descriptor:
  bLength                18
  bDescriptorType         1     
  bcdUSB               2.00     
  bDeviceClass          239 Miscellaneous Device
  bDeviceSubClass         2     
  bDeviceProtocol         1 Interface Association
  bMaxPacketSize0        64
  idVendor           0x2341 Arduino SA
  idProduct          0x8037 
  bcdDevice            1.00     
  iManufacturer           1 Arduino LLC
  iProduct                2 Arduino Micro
  iSerial                 3 HIDLD
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x0064
    bNumInterfaces          3
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xa0
      (Bus Powered)
      Remote Wakeup
    MaxPower              500mA
    Interface Association:
      bLength                 8
      bDescriptorType        11
      bFirstInterface         0
      bInterfaceCount         2
      bFunctionClass          2 Communications
      bFunctionSubClass       2 Abstract (modem)
      bFunctionProtocol       0
      iFunction               0
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         2 Communications
      bInterfaceSubClass      2 Abstract (modem)
      bInterfaceProtocol      0
      iInterface              0
      CDC Header:
        bcdCDC               1.10
      CDC Call Management:
        bmCapabilities       0x01
          call management
        bDataInterface          1
      CDC ACM:
        bmCapabilities       0x06
          sends break
          line coding and serial state
      CDC Union:
        bMasterInterface        0
        bSlaveInterface         1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0010  1x 16 bytes
        bInterval              64
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass        10 CDC Data
      bInterfaceSubClass      0
      bInterfaceProtocol      0
      iInterface              0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0
      bInterfaceProtocol      0
      iInterface              0
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.01
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      59
         Report Descriptors:
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x84  EP 4 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1

I'm not an expert in USB, what I see is 2 interfaces for communication and 1 HID interface. I'm surprised to see bNumDescriptors=1 for the HID interface, shouldn't it be 3 (one for keyboard, one for mouse, one for joystick)? The ** UNAVAILABLE ** in Report descriptors also looks fishy.

Comparing to my regular joystick, it also has the **UNAVAILABLE** . Actually, comparing the two, the only differences are (left=regular joystick, right=Arduino micro):

ColinPitrat commented 8 months ago

I tried capturing the initialization of the Arduino USB device and it does send back a Report mentioning GamePad so it's probably just lsusb which isn't able to properly recognize or display it.

I'll try to compare the regular joystick and the Arduino and link to captured packets in case someone more versed with USB protocol can get something out of it.

ColinPitrat commented 8 months ago

Comparing the regular joystick and the Arduino part, I have a telling difference in /dev/input: both have a /dev/input/js entry but only the regular one has entries in by-path:

$ ls -l /dev/input/by-path/p*joystick
lrwxrwxrwx 1 root root 9 15 oct.  15:54 /dev/input/by-path/pci-0000:00:1d.0-usb-0:2:1.0-event-joystick -> ../event8
lrwxrwxrwx 1 root root 6 15 oct.  15:54 /dev/input/by-path/pci-0000:00:1d.0-usb-0:2:1.0-joystick -> ../js1
$ ls /dev/input/js*
/dev/input/js0  /dev/input/js1

By unplugging and plugging each joystick, I can verify that they both have a /dev/input/event entry (event7 for Arduino, event8 for regular). Interestingly, there's a single event7 for the Arduino when I expected 3 (keyboard, mouse and joystick).

ColinPitrat commented 8 months ago

Testing with jstest (by running jstest /dev/input/js0) my Arduino joystick works well. Same with evtest /dev/input/event7. This suggests that udev doesn't recognize the joystick.

Looking at logs with:

$ udevadm control --log-priority=debug
$ journalctl -f

I found:

js0: Input device has 1 joystick buttons and 0 axes but also 0 keyboard key sets, assuming this is a keyboard, not a joystick.

Although I do configure a single button, I have 2 axes configured too so this is weird.

ColinPitrat commented 8 months ago

So, in the end, adding more buttons allowed it to work fine. It seems the minimal number of buttons for a joystick under linux is 2. Forget about the good old single button joysticks :-D

Not sure if the initial problem was the same, but hopefully the debugging information can be helpful to dig what's wrong.