Az

Saitek X52 USB HID Mapping

I found my old Saitek X52 HOTAS (joystick + throttle controller) that I used to use with DCS: A-10C Warthog and it made me realise joysticks are such a beautiful interface but one that doesn’t get much use outside the hobby world. I’ve been working on a project lately to use my ancient controller as an interface device for some software. It’s still very early days and I’m not sure if it’s something I’ll keep plugging at, but it’s been fun to get back into development stuff.

One of the major problems I’ve had in getting the device working is reading the commands sent from it. I ended up using the pyhidapi and pywinusb libraries, but that left me trying to map the raw byte output to the controls. So in case anyone else is trying to map the USB HID output to use the Saitek X52 for something random, the following is a mapping of the output to the functions of the joystick.

The Saitek X52 joystick when used as a USB human interface device (HID) sends a 15 byte packet for every action, consisting of the current state of the joystick.

The table below outlines the functions:

Byte Bit Function
0 Nothing
1 1-8 X axis on joystick, lower 8 bits
2 6-8 X axis on joystick, upper 3 bits
2 1-5 Y axis on joystick, lower 5 bits
3 3-8 Y axis on joystick, upper 6 bits
3 1-2 Rotation on joystick, lower 2 bits
3 1-8 Rotation on joystick, upper 8 bits
4 Throttle
5 Rotator around button i
6 Rotator around button e
7 Slider next to button d
8 8 Button e
8 7 Button d
8 6 Pinky trigger
8 5 Button c
8 4 Button b
8 3 Button a (assumed, mine doesn’t work)
8 2 Fire button
8 1 Trigger stage 1
9 8 Upper POV up
9 7 Trigger stage 2
9 6 T6
9 5 T5
9 4 T4
9 3 T3
9 2 T2
9 1 T1
10 8 Mode Selector 1
10 4-7 Throttle POV (up, right, down, left)
10 3 Upper POV right
10 2 Upper POV down
10 1 Upper POV left
11 8 Clicking throttle scroll wheel
11 7 Clicking button next to nubbon on throttle
11 6 Button i
11 5 Reset
11 4 Start/Stop
11 3 Function
11 2 Mode selector 3
11 1 Mode selector 2
12 5-8 Lower POV (up,up+right,down+right,up+left)
12 4
12 3
12 2 Throttle scroll up
12 1 Throttle scroll down
13 5-8 Throttle mouse Y axis
13 1-4 Throttle mouse X axis
14 None/termination

The lower POV is a bit weird, it allows for 8 directions with the following mapping:

  • Up: 16 (bit 5)
  • Up-right: 32 (bit 6)
  • Right: 48 (bits 5, 6)
  • Down-right: 64 (bit 7)
  • Down: 80 (bits 7, 5)
  • Down-left: 96 (bits 7, 6)
  • Left: 112 (bits 7, 6, 5)
  • Up-left: 128 (bit 8)