HID
HID copied to clipboard
Gamepad API Suggestion: 3 additional axes, all axes 16bit.
i modifed the descriptors to give it 3 additional axes (slider, dial, wheel) and made them all 16bit including the two 8 bit z and rz axes.
works fine on gamepad-tester.com both with single (Gamepad) and multiple (Gamepad1 ..2 and 3)
Gamepad.cpp descriptors: (edit SingleGamepad.cpp aswell, but remove hid_reportid_gamepad line)
static const uint8_t _hidMultiReportDescriptorGamepad[] PROGMEM = {
/* Gamepad with 32 buttons and 6 axis*/
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
0x09, 0x04, /* USAGE (Joystick) */
0xa1, 0x01, /* COLLECTION (Application) */
0x85, HID_REPORTID_GAMEPAD, /* REPORT_ID */
/* 32 Buttons */
0x05, 0x09, /* USAGE_PAGE (Button) */
0x19, 0x01, /* USAGE_MINIMUM (Button 1) */
0x29, 0x20, /* USAGE_MAXIMUM (Button 32) */
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
0x75, 0x01, /* REPORT_SIZE (1) */
0x95, 0x20, /* REPORT_COUNT (32) */
0x81, 0x02, /* INPUT (Data,Var,Abs) */
/* 9 16bit Axis */
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
0xa1, 0x00, /* COLLECTION (Physical) */
0x09, 0x30, /* USAGE (X) */
0x09, 0x31, /* USAGE (Y) */
0x09, 0x33, /* USAGE (Rx) */
0x09, 0x34, /* USAGE (Ry) */
0x09, 0x32, /* USAGE (Z) */
0x09, 0x35, /* USAGE (Rz) */
0x09, 0x36, /* USAGE (slider) */
0x09, 0x37, /* USAGE (dial) */
0x09, 0x38, /* USAGE (wheel) */
0x16, 0x00, 0x80, /* LOGICAL_MINIMUM (-32768) */
0x26, 0xFF, 0x7F, /* LOGICAL_MAXIMUM (32767) */
0x75, 0x10, /* REPORT_SIZE (16) */
0x95, 0x09, /* REPORT_COUNT (9) */
0x81, 0x02, /* INPUT (Data,Var,Abs) */
0xc0, /* END_COLLECTION */
/* 2 Hat Switches */
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
0x09, 0x39, /* USAGE (Hat switch) */
0x09, 0x39, /* USAGE (Hat switch) */
0x15, 0x01, /* LOGICAL_MINIMUM (1) */
0x25, 0x08, /* LOGICAL_MAXIMUM (8) */
0x95, 0x02, /* REPORT_COUNT (2) */
0x75, 0x04, /* REPORT_SIZE (4) */
0x81, 0x02, /* INPUT (Data,Var,Abs) */
0xc0, /* END_COLLECTION */
};`
GamepadAPI.h additions to the HID_GamepadReport_Data_t struct
` int16_t zAxis;
int16_t rzAxis;
int16_t sliderAxis;
int16_t dialAxis;
int16_t wheelAxis;
`
and change/add GamepadAPI class public definitions:
` inline void ryAxis(int16_t a);
inline void rzAxis(int16_t a);
inline void sliderAxis(int16_t a);
inline void dialAxis(int16_t a);
inline void wheelAxis(int16_t a);
`
addition to the GamepadAPI.hpp
(edit zAxis and rzAxis to uint16_t)
`void GamepadAPI::zAxis(int16_t a){
_report.zAxis = a;
}
void GamepadAPI::rzAxis(int16_t a){
_report.rzAxis = a;
}
void GamepadAPI::sliderAxis(int16_t a){
_report.sliderAxis = a;
}
void GamepadAPI::dialAxis(int16_t a){
_report.dialAxis = a;
}
void GamepadAPI::wheelAxis(int16_t a){
_report.wheelAxis = a;
}
i tried adding more (Vx, Vy, Vz, Vbrx, Vbry, Vbrz, Vno, Qx, Qy, Qz, Qw and additional buttons) but couldnt find a program that would let me debug them. windows gamepad viewer is quite limited. but it sent the data, no hickups or crashes.
edit: github text formatting sucks
Github text formatting does not suck, you need to use 3 backticks instead of one. I've edited your comment.
I am pretty sure, that I've used this "limited" controller, as it would only consume 16 byte hid reports. Since the 16u2 is also supported and only uses 16 byte usb endpoints, your patch will not work for those arduinos.
What we could do is to create another gamepad with those even more oversized options. The question is: Why do we need that? Wouldnt it make more sense to just use 2 or 3 gamepads, if one is not enough?
This is funny, because I have patched the Gamepad to have less buttons and to remove the Z and RZ axes completely, lol. I was thinking of submitting my patch since it is conditional and can be easily turned off (actually it's off by default).
Of course the best thing would be to have a fully customizable Gamepad class, but that is not easy to achieve. Maybe a "basic" and an "advanced" Gamepad will suffice. What do you guys think?
As I already said, I found no reason to have less buttons, but I found some for having more (comment above). So I'd stick to the current solution, but I might get that wrong. More community Feedback would be helpful here.
Or at least collect the links to variants in the wiki, so everybody can adapt for super special usecases. Cause I cannot support all those combinations, of course.
I also had to patch for less buttons and axes. When we make devices, users expect the operating system to show what the device has. If my physical gamepad has 8 buttons, its confusing to users why are there all these buttons... At minimum, i suggest documenting how to modify class to remove buttons/axis not needed.