Understanding USBHID_DESC report Recently Ran the USBHID_DESC program on my Arduino Uno with a USB hub attached to my joystick. I wanted to be able to program my joystick to integrate with my project. Circuits@Home developed the code and have 2 articles dealing with understanding the report. But they are very sparse with details and only have a single example to go off of. Many of the fields that I got returned are not described at all in the tutorial. Further more, attempting to dig through the official documentation from USB.org itself has been extremely overwhelming. I don't really know how to start. Can anyone help me interpret the data fields for this controller?

This is the data that I recieved from the serial monitor:


  Start
  0000: 05 01 09 04 A1 01 09 01 A1 00 09 30 09 31 09 32
  0010: 09 BB 15 80 25 7F 46 FF 00 66 00 00 66 00 00 75
  0020: 08 95 04 81 02 C0 09 39 15 01 25 08 35 00 46 3B
  0030: 01 65 14 75 04 95 01 81 02 05 09 19 01 29 04 15
  0040: 00 25 01 75 01 95 04 81 02 95 08 81 01 05 08 09
  0050: 43 15 00 26 FF 00 35 00 46 FF 00 75 08 95 04 91
  0060: 82 55 00 65 00 55 00 65 00 55 00 C0
  Usage Page Gen Desktop Ctrls(01)
  Usage Game Pad
  Collection Application
  Usage Pointer
  Collection Physical
  Usage X
  Usage Y
  Usage Z
  Usage Undef
  Logical Min(80)
  Logical Max(7F)
  Physical Max(FF00)
  Unit(0000)
  Unit(0000)
  Report Size(08)
  Report Count(04)
  Input(00000010)
  End Collection
  Usage Hat Switch
  Logical Min(01)
  Logical Max(08)
  Physical Min(00)
  Physical Max(3B01)
  Unit(14)
  Report Size(04)
  Report Count(01)
  Input(00000010)
  Usage Page Button(09)
  Usage Min(01)
  Usage Max(04)
  Logical Min(00)
  Logical Max(01)
  Report Size(01)
  Report Count(04)
  Input(00000010)
  Report Count(08)
  Input(00000001)
  Usage Page LEDs(08)
  Usage Slow Blk On Time
  Logical Min(00)
  Logical Max(FF00)
  Physical Min(00)
  Physical Max(FF00)
  Report Size(08)
  Report Count(04)
  Output(10000010)
  Unit Exp(00)
  Unit(00)
  Unit Exp(00)
  Unit(00)
  Unit Exp(00)
  End Collection Game Pad Pointer X Y Z Undef(00)(00)(7F)(00)
  Hat Switch(00)
  Btn0001
  (00) Btn0002
  (00) Btn0003
  (00) Btn0004
  (00)
  (00)(00)(00)(00)(00)(00)(00)(00)
  Slow Blk On Time
It's pretty easy to follow if you indent and break it up right.  Let me add some annotation too:

Usage Page Gen Desktop Ctrls(01)  // Usages describe what the
Usage Game Pad                    // following data is used for.
Collection Application
    Usage Pointer        // Use the settings for a physical
    Collection Physical  // pointing device
        Usage X       // It has four axes - 
        Usage Y       // X, Y, Z and some other undefined axis.
        Usage Z
        Usage Undef
        Logical Min(80) // Output the values 0x80 to 0x7F, which when
        Logical Max(7F) // interpeted as signed bytes is -128 to 127.
        Physical Max(FF00) // The input has a range 0 to 255
        Unit(0000)
        Unit(0000)
        Report Size(08)  // The report value is 8 bits long, 
        Report Count(04) // and there are 4 of them (one per axis)
        Input(00000010)  // This ends this "input" section. 
    End Collection

    Usage Hat Switch // Describing a HAT Switch now.
    Logical Min(01)  // Interpret it as a value between 1 and 8
    Logical Max(08)
    Physical Min(00) // The input to it is between 0 and 0x3B01.
    Physical Max(3B01) // Not sure that value is interpreted properly.
    Unit(14)
    Report Size(04)  // The report has 4 bits in it, 
    Report Count(01) // and there is just one of them.
    Input(00000010)  // And end the input section.

    Usage Page Button(09)  // Next come the buttons.
    Usage Min(01)      // These are basically button numbers
    Usage Max(04)      // - there's 4 buttons, 1 through 4.
    Logical Min(00)    // A button is either off (0) 
    Logical Max(01)    // or on (1).
    Report Size(01)    // And can only have one state, so size 1.
    Report Count(04)   // There's 4 buttons, so 4 reports.
    Input(00000010)    // And end the input.

    Report Count(08)   // This is a special one. It keeps the settings
    Input(00000001)    // from before (the haven't been changed), but
                       // is just a dummy one to pad out the data to
                       // the right size. Alignment is key.

    Usage Page LEDs(08)    // Now we have 4 LEDs with an 
    Usage Slow Blk On Time // 8-bit PWM value. 0-FF which doesn't
    Logical Min(00)        // need interpreting, so 0=0 and FF=FF.
    Logical Max(FF00)
    Physical Min(00)
    Physical Max(FF00)
    Report Size(08)    // As I said, 8 bit,
    Report Count(04)   // and there's 4 of them.
    Output(10000010)   // And it's output.

    Unit Exp(00)   // Now there seems to be a bit of junk.
    Unit(00)
    Unit Exp(00)
    Unit(00)
    Unit Exp(00)
End Collection Game Pad // And the end.


So interpreting that, you get a report sent to you that has:

Byte     Function
0        X Axis 0-255 which you map to -128 to 127
1        Y Axis 0-255 which you map to -128 to 127
2        Z Axis 0-255 which you map to -128 to 127
3        Another Axis 0-255 which you map to -128 to 127
4        Upper 4 bits buttons, lower 4 bits HAT direction
5        Padding byte to make ita multiple of 16 bits long


And you can send a 4 byte report where:

Byte     Function
0        LED 1 PWM
1        LED 2 PWM
2        LED 3 PWM
4        LED 4 PWM


Those "LEDs" could be force feedback motors or vibrators.

Also I suspect there is maybe a small amount of corruption or mis-interpretation of multi-byte values in the output.