NicoHood / HID

Bring enhanced HID functions to your Arduino!
http://www.nicohood.de
MIT License
2.37k stars 409 forks source link

Support more Buttons and Axis in Gamepad mode? #8

Closed unixunion closed 9 years ago

unixunion commented 9 years ago

Hi,

is it possible to support more axis and buttons? I need 8x 16bit axis and 40 buttons or more! is this possible?

/K

NicoHood commented 9 years ago

Hello unixunion, yes and no.

Under Windows the limit is 7 axis as i remember and 32 buttons.

Linux had a lot of problems with joysticks in multireports. I even havent tested it on linux again. You had the problem that the linux recognized too many button/axis or nothing at all.

But in general I'd say: yes its possible. You can add two gamepads (and you may want to remove keyboard etc) and then it might work. Two gamepads would work under Windows as well.

With the new HID Project 2.1 it is possible to create custom HID reports. You "just" have to add this and create your own gamepad api. If this is too complicated to you I have no simpler solution (yet).

I will also work on fixed firmwares with no Serial in it. So the Arduino shows up as Gamepad only for example. This is to avoid problems with OS. You can create seperate endpoints for each gamepad and also consoles like a PS3 may recognize this better. This is also usefull if you want to use your Arduino as keyboard on a phone, because the Serial confuses some devices. Then your Arduino would be an HID device only.

Sorry if you may not understand everything but i wanted to give a more or less detailed answer. I will work on these firmwares soon. I am currently working on the protocol transmission. So its in work, just hold on some more time. Then you may hit me again if its not what you need.

Do you need this to control a flight simulator? There are some flight control reports out there i guess. Maybe this could help you. I am happy to add new features, I just have to focus on the basic Core to get it working without any problems, you know? ;)

Nico

unixunion commented 9 years ago

Hej Nico!

Thanks for all the info! I greatly appreciate it. I am building a Kerbal Space Simulator joystick, so it is flight-sim-like I guess. The difference is that I want to be able to display some values from the game on my joystick into which I am building a Arduino with a LCD also. So I'm quite interested in the HID and PID for feedback aspects of this.

I was thinking of building a multiple arduino setup, with a Mega running the inputs and joystick HID stuff, and then secondary arduinos running the LCD's ( listening on i2c for their value updates from the Mega)

I would need to write a KSP plugin to expose these values to the Joystick somehow.

LCD hud example: untitled 3

My ultimate goal is to be able to edit the HUD via a in-joystick GUI and name the feedback buttons and channels whatever you want so it could work for other sims.

/Kegan

NicoHood commented 9 years ago

could you pleae contact me, to avoid chatting in this issue? I am also online in the chat: https://nicohood.wordpress.com/about/

Yeah that'd be possible to do. I could help you out with this but I have to know a few things: Are you using windows or linux? Do you still need the Serial port? Is the TV picture generated via PC? I am a bit confused about that.

Why do you want to use two Arduinos? With an Arduino Mega you can use the 16u2 with HoodLoader2 to do all the USB stuff and the main MCU could do the LCD stuff. And they are already connected via Serial. Later on I will create these Serial protocol apis to also transmit HID reports. You could also use a special Arduino with a 32u2 to get a better usb chip. But those Arduinos are only selled as Uno, not Mega. Depending on what you want to do it should be fine. And a 32u2 is also able to connect spi peripherals like lcds if the ram/flash is okay for that.

NicoHood commented 9 years ago

Memo to myself: http://stackoverflow.com/questions/29358179/usb-possible-to-define-multiple-distinct-hid-joysticks-on-one-interface

Teiwaz83 commented 9 years ago

Hi -

The 7 axis limit and 32 button limit is actually a restriction of the built-in device profiler in Windows, and not actually a limitation of the OS. The properties of the device in the control panel will only ever show 7 axes and 32 buttons, but Windows is able to accept input from (at least) 8 axes and 128 buttons. I've been using Pointy's Joystick Test Application (http://www.planetpointy.co.uk/joystick-test-application/) to check that things are working with more inputs than windows device properties shows. (Note, however, that some applications will still impose the 32 buttons-from-a-device limit. Especially older games or ones with mediocre joystick support.)

It sounds like I'm working on something similar to the OP. I've been attempting to set up an Arduino to represent itself to Windows as 4 joysticks, effectively giving me 32 axes + 1024 buttons to work with. (It's mostly the additional axes I need.) However, it's been very difficult: Windows, annoyingly, combines the separate virtual devices into a single, mega-joystick which immediately runs into the 8/128 limit.

From what I've gathered, there are two ways around this: Windows will recognize the different reports as different devices as long as they originate from separate top-level collections as defined in the HID descriptor. That's easy enough to do in theory, but I haven't had any luck getting it to work. Windows keeps assigning a hardware ID which indicates that it thinks it's a multi-application, single TLC device instead of a multi-application, multiple TLC device. (See here: https://msdn.microsoft.com/en-us/library/windows/hardware/ff538842%28v=vs.85%29.aspx) which seems to conflict with the HID descriptor and causes the USB device to fail to start. I've had no luck whatsoever figuring out why this is happening, or where this ID is assigned. I've begun to suspect that it's actually defined in the Windows driver for the Arduino, and would both require a new VID/PID to work around ($5000!), and would probably break my ability to program the Arduino easily.

The second way around this seems to be that Windows won't group the devices together if their reports originate from separate endpoints. I don't have this working yet, as the endpoint descriptors are buried pretty deep, and so require a lot of changes to get to... and if anything goes wrong along the way, the USB device will just fail to start with that ever-so-unhelpful code 10, which basically has been meaning returning to square one for the changes for me since I have no way to determine what went wrong or where.

I believe the second approach is the more practical. Or at least, it's one I haven't run into any hard blockers on yet. I've moved over to using this project's development branch as a basis for this work, as NicoHood has significantly cleaned up the complete mess that is the Arduino HID code. The endpoint stuff lives at a lower level than what Nico has done, but his nicer code at least gets me closer to it, which means less to break and cause error 10s before I can change what I need to add additional endpoints. But Nico, if you want to support this sort of thing, it would be a big win if there were a way to add and specify additional endpoint descriptors at the final HID class level like you did for HID descriptors.

Teiwaz83 commented 9 years ago

...I've spent the last couple hours digging through the new PluggableUSB stuff, and it looks like more endpoints would not be doable without modifying the HID library that this library is built on top of.

If I'm not mistaken - and I may well be, USB is still outside of my comfort zone - the HID class is what requests its own endpoint from PluggableUSB, it only ever asks for one, and it's a singleton so you can't have more than one HID created.

So if you want multiple endpoints to allow multiple joysticks in Windows, you're going to have to drop down a couple levels from this library, and work with PluggableUSB directly. Fortunately, it seems a lot nicer than the core USB stuff was before 1.6.6, and even (gasp!) has examples and documentation! (https://github.com/arduino/Arduino/wiki/PluggableUSB-and-PluggableHID-howto)

NicoHood commented 9 years ago

I am working on this. To get Gamepads working without problems you need an endpoint for each gamepad. This is not possible with a 16u2 (has no more free endpoints) but with a 32u4 (has 2 more, 4 already used by serial + 1 hid).

I need to modify the hid class. I try to also push those updates to the upstream Arduino project.

Feel free to develop a MegaGamepad class which adds more axis and buttons. If it works, I can also test under linux. But I guess in most cases this will cause problems.

I guess you have to wait a bit still. But I definitely keep this feature on eyes. Pluggable USB will help us a lot here.

Feel Free to test the 2.4 dev version till then.

Teiwaz83 commented 9 years ago

I managed to screw up my Leonardo last night, and am out of action until an ICSP arrives to let me fix it, so it'll be a little while before I'm back into it. My impressions of 2.4 are good, pluggable USB and the core override stuff in Arduino 1.6.6 are lifesavers. I started work on a multi-stick which sits on top of PluggableUSB and creates a separate HID interface with its own endpoint. The problem is that Pluggable USB doesn't play nice with multiple instances of a class due to requiring static function pointers to talk to your pluggable class, and I don't want to go down the road of working around that until I have a working single joystick first. (The order of operations when interacting with PluggableUSB is weirdly circular, especially when setting up your getInterface function.) It compiles now, but with USB that's like 10% of the battle, so I'm not going to be making progress until I can fix the Leonardo and test on it. If your multi-pluggable HID stuff from the other thread is working by then, I'll happily change over to that and let you know what I think. (Keep fighting the good fight on that - if before it's released is too late to change an API to improve it, when can you?)

NicoHood commented 9 years ago

Yep. I will work on the Pluggable USB static change soon. I also want to note that I do that in my free time, I am not an official dev.

You can also use a 2nd Arduino to burn a new bootloader. But you dont have to normally. Just hit upload, then the IDE waits, then you press the reset button and it should recognize this and upload a new sketch again.

NicoHood commented 9 years ago

Meow. Try the latest dev version. You have up to 4 gamepads there. I recomment to read the wiki API Documentation section, since only 3 Gamepads will work at the moment with Serial. Use Gamepad1,2,3

Teiwaz83 commented 9 years ago

Is the Gamepad example still working? The comments talk about the new gamepad functionality. I grabbed dev 2.4 and a new hourly build from arduino, but if I run the gamepad example, while the Leonardo is recognized as a game controller with the correct report and no errors, I'm not getting the random inputs that the Gamepad example is supposed to be feeding it according to the Windows device properties or my Joystick test application. It's possible my Leonardo is just still broken, though. It seems to be mostly working (Windows 7+ does some really, really stupid crap with USB devices and the registry which I had to muck out) but my ICSP still isn't here so there may still be some bad stuff on it.

Teiwaz83 commented 9 years ago

Woops, nevermind. I didn't read the sketch closely enough and missed the whole pin 2 button thing. Works fine, it looks like I'm back in business.

NicoHood commented 9 years ago

Windows has a lot of problems on a device change. The ISERIAL patch will be published sooner or later I think. I just tested under linux real quick and it worked. Is that enough now, or do you still need more buttons etc? Those are now separate gamepads, but its now inside the limits of the OS though.

NicoHood commented 9 years ago

Closing this now, since up to 3 Gamepads as single report are now supported. If that is not enough, feel free to code your own descriptors, its so easy now. Feel free to provide a PR with a patch. but I guess using just 3 Gamepads will also fit perfectly.