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…
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.
I’ll look through that post now
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
![]()
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/GameControll … tToUSB.ino
[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?
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
#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);
}
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
[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.
[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();
}
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.
Here’s my 8 bit Amiga/Atari/C64 joystick to USB adapter – I’m using an HYTiny board since they are well, tiny
Just waiting for a 9 pin sub D connector now ![]()
#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();
}
USBComposite.setVendorId(0x040B);
USBComposite.setProductId(0x6533);
USBComposite.setProductString("Speed-Link Competition Pro");
