HID Usage tables that allow for many buttons, axis, and toggle controls

Hi everyone

I'm new to the forum and haven't used arduino in a long time. Please excuse me if the question seems completely obvious. I am making a "button board" for my friends virtual racing setup and want to communicate with the computer about button presses, switch flicks (They are three position toggle switches), and rotary encoder turns. I have been looking over the usage tables for HID and have not been able to find what I need, it seems weird because many of the sub-subsections do not contain any information about what controls can be used with them. I have tried finding specific usage tables for these online and have not found anything. I have been using V-USB with my arduino nano on data pins 0 and 1 as D- and D+ respectively. I have also been following this video by sinelab which has brought me most of the way through. Does anyone know how to solve this issue?

Thank you in advance.

My guess would be Usage Tables Page 0x02: Simulation

I have looked through there multiple times and have not found what I need, the board has 3 switches 2 rotary encoders and fully inclusive 15 buttons. Nothing I have found in there has enough room for that

is it OK for your friend?

No, he gave me very precise specifications, and I don't think that he will be happy to change it. But I do wonder what HID device did you find that would support all of that, as it may be the solution.

so sad, he will definitely kill you if you make this:


1 Like

I'm not sure if I made myself clear but I am talking specifically about the HID protocol to get the data over USB, I don't need any help with designing.

this above is HID table "Gamepad", do you hear something about that table?

and this one utilize HID Table "Keyboard":

All that the datasheet gives is an explanation of what gamepad is, but there is nothing on how to use it. Keyboard is worse, it has a usage table but they are all buttons/switches. Gamepad would seem promising if I knew the usage table for it.

noone know it, but they not care about and using it:
(example from NicoHood library)

/*
 Copyright (c) 2014 NicoHood
 See the readme for credit to other people.

 Gamepad example project

 Press physical buttons to press USB Gamepad buttons.
 This can be used for a simple SNES Controller.

 Make sure the Gamepad report is set in:
 sketchbook/hardware/HID/avr/variants/hid_descriptors/hid_descriptors.h
*/

// pin mappings
const int pinButton0 = 0;
const int pinButton1 = 1;
const int pinButton2 = 2;
const int pinButton3 = 3;
const int pinButton4 = 4;
const int pinButton5 = 5;
const int pinButton6 = 6;
const int pinButton7 = 7;
const int pinButton8 = 8;
const int pinButton9 = 9;
const int pinButton10 = 10;
const int pinButton15 = 15;
const int pinButton14 = 14;
const int pinButton16 = 16;
const int xAxis = A0;
int readValue = 0;
int outputValue = 0;

void setup(){
  // pinsetup
  pinMode(pinButton0, INPUT_PULLUP);
  pinMode(pinButton1, INPUT_PULLUP);
  pinMode(pinButton2, INPUT_PULLUP);
  pinMode(pinButton3, INPUT_PULLUP);
  pinMode(pinButton4, INPUT_PULLUP);
  pinMode(pinButton5, INPUT_PULLUP);
  pinMode(pinButton6, INPUT_PULLUP);
  pinMode(pinButton7, INPUT_PULLUP);
  pinMode(pinButton8, INPUT_PULLUP);
  pinMode(pinButton9, INPUT_PULLUP);
  pinMode(pinButton10, INPUT_PULLUP);
  pinMode(pinButton15, INPUT_PULLUP);
  pinMode(pinButton16, INPUT_PULLUP);
  pinMode(pinButton14, INPUT_PULLUP);

  // Sends a clean report to the host. This is important on any Arduino type.
  Gamepad.begin();
}

void loop(){
  // check each button and press Gamepad if needed
    if (!digitalRead(pinButton0))
    Gamepad.press(0);
  else
    Gamepad.release(0);
  
  if (!digitalRead(pinButton1))
    Gamepad.press(1);
  else
    Gamepad.release(1);

  if (!digitalRead(pinButton2))
    Gamepad.press(2);
  else
    Gamepad.release(2);

  if (!digitalRead(pinButton3))
    Gamepad.press(3);
  else
    Gamepad.release(3);

  if (!digitalRead(pinButton4))
    Gamepad.press(4);
  else
    Gamepad.release(4);

  if (!digitalRead(pinButton5))
    Gamepad.press(5);
  else
    Gamepad.release(5);

  if (!digitalRead(pinButton6))
    Gamepad.press(6);
  else
    Gamepad.release(6);

  if (!digitalRead(pinButton7))
    Gamepad.press(7);
  else
    Gamepad.release(7);

  if (!digitalRead(pinButton8))
    Gamepad.press(8);
  else
    Gamepad.release(8);

  if (!digitalRead(pinButton9))
    Gamepad.press(9);
  else
    Gamepad.release(9);



  if (!digitalRead(pinButton10))
    Gamepad.press(10);
  else
    Gamepad.release(10);

  if (!digitalRead(pinButton15))
    Gamepad.press(15);
  else
    Gamepad.release(15);
    
     if (!digitalRead(pinButton14))
    Gamepad.press(14);
  else
    Gamepad.release(14); 
    
      if (!digitalRead(pinButton16))
    Gamepad.press(16);
  else
    Gamepad.release(16);
readValue = analogRead(A0);
 outputValue = map(readValue, 0, 1023, 32767, -32768);
    
    Gamepad.xAxis(outputValue);

  // write the information to the host now!
  Gamepad.write();
}

1 Like

Can I see the github page, or where ever you got that from, the solution is probably contained within

it looks then in windows :

зображення
зображення

other people may like MMJoy2 project, or Freejoy based on Blue Pill

This is great, I have been scanning the documents for their Report Descriptors that are usually just a bunch of lines of hexadecimal. I need these because I have to work with my own hardware and these programs don't seem to like that. I've been looking for some time now and I don't think that anything like that is on these. I'm not fully sure if they are on here or how these programs work and I don't want to spend hours parsing. I would like to leave this as a last resort.

I think that I just found it in some YouTube video, it is not perfect but it'll do good enough to test around with it. Here is the file containing the report descriptor itself. Here is the video that I found it in by Print 'N Play (This is for rasberry pi but same ideas apply). Here is it written out:

    0x05, 0x01,  # Usage Page (Generic Desktop Ctrls)
    0x09, 0x05,  # Usage (Game Pad)
    0xA1, 0x01,  # Collection (Application)
    0x85, 0x04,  #   Report ID (4)
    0x05, 0x09,  #   Usage Page (Button)
    0x19, 0x01,  #   Usage Minimum (Button 1)
    0x29, 0x10,  #   Usage Maximum (Button 16)
    0x15, 0x00,  #   Logical Minimum (0)
    0x25, 0x01,  #   Logical Maximum (1)
    0x75, 0x01,  #   Report Size (1)
    0x95, 0x10,  #   Report Count (16)
    0x81, 0x02,  #   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0x05, 0x01,  #   Usage Page (Generic Desktop Ctrls)
    0x15, 0x81,  #   Logical Minimum (-127)
    0x25, 0x7F,  #   Logical Maximum (127)
    0x09, 0x30,  #   Usage (X)
    0x09, 0x31,  #   Usage (Y)
    0x75, 0x08,  #   Report Size (8)
    0x95, 0x02,  #   Report Count (4)
    0x81, 0x02,  #   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    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) */
    0x25, 0x01,	 #  INPUT (Data,Var,Abs) */
    0xC0,        # End Collection

I will mark this is the solution but I may come back to this in a few days explain how one can edit it after I do some testing myself.

HID works slightly differently than I had thought. You supply the type of the item and then different pieces of what you want from different parts of the usage tables.

thank you very much for help

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.