USBComposite, Some help making a gaming HID…

Nutsy
Sun Mar 03, 2019 12:12 am
Hi while I still have the opportunity to I wanted to ask a couple of questions about making a USB HID…

Someone mentioned to me the USBComposite library in the core and this seems like the best option to make my custom game controller i have in mind for a project.

The only trouble is the examples included arent very detailed, and dont really make it clear how to set multiple buttons and inputs.

For instance I want 2 analogue sticks and several buttons.

What is the best way to organise all this?

Is there a more detailed example I can look at to get a better idea how best to organise my program?

So I put all my button and analogue state changes into interrupts? Or do i just run the elements of the hid in the main loop, so with each loop it checks the state of each button and analogue stick?

Also is there a more detailed set of documentation of the USBCompoite library? Googling hasnt really found anything.

Such as all the elements and components and how to use them…


mrburnette
Sun Mar 03, 2019 12:39 am
Have you go through the post: https://stm32duino.com/viewtopic.php?f=19&t=4046

It has been years since I have done anything with HID, so long ago it was an 8-bit AVR… But, as I remember, it all distills down to keycode combinations.


Nutsy
Sun Mar 03, 2019 12:46 am
I did wonder if it could be done in avr, but I think my googlefu is weak… It was only because someone else mentioned usbcomposite as they used it to control a retro arcade…

I’ll look through that post now


ag123
Sun Mar 03, 2019 4:24 am
hid is a very flexible protocol and because of the protocol design, it is complex.
it would be necessary to get familiar with the protocol and you can start with the specs
https://www.usb.org/hid
core to hid protocol are ‘report descriptors’ which are capable of describing a whole complex set of buttons, controls etc
https://eleccelerator.com/tutorial-abou … scriptors/
i’m still trying to learn that though. and to get started with a shorter learning curve i think starting with usb composite as a base would help
and get a usb protocol sniffer and app, as i worked in linux, linux has usbmon built-in and i can use wireshark to look at the packets
https://wiki.wireshark.org/CaptureSetup/USB
^^ for windows the above link mentions USBPcap https://desowin.org/usbpcap/

in addition do get familiar with usb itself if you aren’t
http://www.usbmadesimple.co.uk/index.html

i’ve wanted to make a short cut keypad, the blue pill / maple mini is ideal for it, it is literally just wires and key switches (easily available searching ebay / aliexpress for mechanical key switches), and an idea is to throw in rotrary encoders so that they can be used to scroll the pages vert & horiz :)
but that means the same learning about usb HID
https://hackaday.com/2017/06/19/diy-shortcut-keyboard/

and these days people do wacky stuff with their keyboards
https://hackaday.com/2014/11/23/sprite_ … ays-snake/
https://youtu.be/enzU9u328Fc
:lol:


arpruss
Fri Mar 08, 2019 2:15 pm
Look at USBHID.h in the library. The HIDJoystick class defines a lot of axes, so two analog sticks aren’t a problem, and I think there are 32 buttons available.

You might also look at my GameCube controller to USB adapter code. It’s pretty complex as it lets you emulate USB gamepad, Xbox gamepad, and various keyboard configurations, and it supports input from an exercise machine and a Nunchuck, too.

https://github.com/arpruss/gamecube-usb-adapter


arpruss
Fri Mar 08, 2019 2:23 pm
There is also this much simpler example code for an adapter from an analog four axis eight button GamePort joystick to USB:
https://github.com/arpruss/GameControll … tToUSB.ino

BennehBoy
Fri Mar 08, 2019 2:49 pm
[arpruss – Fri Mar 08, 2019 2:23 pm] –
There is also this much simpler example code for an adapter from an analog four axis eight button GamePort joystick to USB:
https://github.com/arpruss/GameControll … tToUSB.ino

Interesting, is there any way to convert from an up/down left/right micro-switched joystick for X & Y rather than an analogue input?


ag123
Fri Mar 08, 2019 5:00 pm
hi apruss, cool project and
the instructables is awesome
https://www.instructables.com/id/Gamecu … ng-Starte/
and wow it seem you have already done it in USB composite itself, the sketch merely shows the ‘high level’ parts of it :D
#include <USBComposite.h>
#include <libmaple/usb.h>

USBHID HID;
HIDKeyboard Keyboard(HID);
HIDJoystick Joystick(HID);
HIDMouse Mouse(HID);

void setup() {
USBHID.begin(HID_KEYBOARD_MOUSE_JOYSTICK);
while (!usb_is_connected(USBLIB) || !usb_is_configured(USBLIB)) delay(100);
Keyboard.println("Hello world!");
}

void loop() {
Joystick.X(0);
Joystick.Y(0);
digitalWrite(PB12, 0);
delay(500);
Joystick.X(1023);
Joystick.Y(1023);
delay(500);
digitalWrite(PB12, 1);
}


mrburnette
Fri Mar 08, 2019 6:27 pm
HID is not just for keyboards and joysticks, one can also do serious data-logging, too:

https://www.hackster.io/rayburne/rpi-da … ng-usb-hid
https://www.hackster.io/rayburne/arduin … sing-v-usb
https://www.hackster.io/rayburne/analog … viewer-usb

Or, a clone of Adafruit’s tiny85 Trinket
https://www.hackster.io/rayburne/chachk … ny85-clone
Or, a tiny85 DigiSpark
https://www.hackster.io/rayburne/trinke … e-exorcism

From the old arduino.cc forum, some now ancient examples that would be easy to implement with the STM32F1xx HID library:
http://forum.arduino.cc/index.php?topic=135623.0

Point is, HID is a gateway drug to cross over USB.

Ray


ag123
Fri Mar 08, 2019 9:05 pm
thanks ray, it gives me more incentive to explore hid from there, usb-serial is ‘universal’ but ‘artificially slow’, there is little reason not to use the full 10mbps usb-full speed rather than artificially limiting to 115200 bps. i think the main reason usb-serial exist is due to the ubiquitous virtual com: ports, most apps works without programming wizardry and few people wants to venture into ‘driver’ stuff especially on the desktop :lol:

MoDu
Mon Mar 11, 2019 4:37 pm
[mrburnette – Fri Mar 08, 2019 6:27 pm] – Point is, HID is a gateway drug to cross over USB.

Definitely. Especially if you use custom software to deal with HID on the PC side, then driverless heaven is yours.


arpruss
Tue Mar 12, 2019 4:12 am
[BennehBoy – Fri Mar 08, 2019 2:49 pm] –
Interesting, is there any way to convert from an up/down left/right micro-switched joystick for X & Y rather than an analogue input?

Sure. Do something like:

const uint32 leftSwitch = PA1;
const uint32 rightSwitch = PA2;
const uint32 upSwitch = PA3;
const uint32 downSwitch = PA4;
const bool switchActive = 1; // 1 if microswitch is connected to VCC and pulled down

...

void setup() {
...
Joystick.setManualReportMode(true);
}

void loop() {
if (digitalRead(leftSwitch) == switchActive) Joystick.X(0);
else if (digitalRead(rightSwitch) == switchActive) Joystick.X(1023);
else Joystick.X(512);
if (digitalRead(upSwitch) == switchActive) Joystick.Y(0);
else if (digitalRead(downSwitch) == switchActive) Joystick.Y(1023);
else Joystick.Y(512);
Joystick.send();
}


BennehBoy
Tue Mar 12, 2019 8:00 am
Excellent, thanks.

Nutsy
Tue Mar 12, 2019 11:11 am
Ha i missed all these updates because gmail classed it spam :(

Thanks everyone for contributing… its made things a whole bunch clearer for me now…

Im going to be starting this handheld retrogaming unit thing pretty soon…. Already been ordering the basic parts, and going to start putting together a circuit schematic… Mostly just jigsaw stuff cobbling together various module parts and integrating it into a single board.

To save on power, I was thinking of compiling this in the underclocked state (48mhz) This is still plenty fast enough for polling the button states… But should cut my power usage on this device by nearly half… (maybe a third…)

Power is a consideration as I want to run this on batteries.


BennehBoy
Thu Mar 14, 2019 2:25 pm
I can’t believe how simple this was!

Here’s my 8 bit Amiga/Atari/C64 joystick to USB adapter – I’m using an HYTiny board since they are well, tiny :D Just waiting for a 9 pin sub D connector now :D

#include "USBComposite.h" // https://github.com/arpruss/USBHID_stm32f1

#define LED_BUILTIN PA1 // change to match your board ; PB12 for some black pills ; PC13 for blue/red pill

const uint32 leftSwitch = PA7;
const uint32 rightSwitch = PA6;
const uint32 upSwitch = PA5;
const uint32 downSwitch = PA4;
const uint32 fireSwitch = PA3;
const bool switchActive = 1; // 1 if microswitch is connected to VCC and pulled down

USBHID HID;
HIDJoystick Joystick(HID);

void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
pinMode(PA7, INPUT_PULLDOWN);
pinMode(PA6, INPUT_PULLDOWN);
pinMode(PA5, INPUT_PULLDOWN);
pinMode(PA4, INPUT_PULLDOWN);
pinMode(PA3, INPUT_PULLDOWN);
USBComposite.setProductId(0xE004);
USBComposite.setProductString("MapleGameportToUSB");
HID.begin(HID_JOYSTICK);
digitalWrite(LED_BUILTIN, 1);
adc_set_sample_rate(ADC1, ADC_SMPR_13_5); // ADC_SMPR_13_5, ADC_SMPR_1_5
Joystick.setManualReportMode(true);
}

void loop()
{
if (digitalRead(leftSwitch) == switchActive) Joystick.X(0);
else if (digitalRead(rightSwitch) == switchActive) Joystick.X(1023);
else Joystick.X(512);
if (digitalRead(upSwitch) == switchActive) Joystick.Y(0);
else if (digitalRead(downSwitch) == switchActive) Joystick.Y(1023);
else Joystick.Y(512);
if (digitalRead(fireSwitch) == switchActive) Joystick.button(1,true);
else Joystick.button(1,false);
Joystick.send();
}


BennehBoy
Thu Mar 14, 2019 4:48 pm
If you change the VID/PID to the following then it will be recognised ‘out of the box’ as a usable joystick on the Amibian RPi Amiga distro…

USBComposite.setVendorId(0x040B);
USBComposite.setProductId(0x6533);
USBComposite.setProductString("Speed-Link Competition Pro");


ag123
Thu Mar 14, 2019 6:04 pm
+1 cool :D

Leave a Reply

Your email address will not be published. Required fields are marked *