Recently I’ve been playing around with building various alternative controller projects for games, typically using an Arduino-compatible microcontroller acting as an HID input device of some sort. The Arduino ecosystem makes it easy to set up these projects to act as either a Keyboard, a Mouse, a DirectInput Joystick, or a composite device that’s a combination of the above. Unfortunately back in 2005 DirectInput was supplanted by XInput with the release of the Xbox 360 controllers, and modern games have been weaning off of it ever since.

These days, many mainstream games barely support DirectInput at all. Games like Rocket League and Overwatch won’t even recognize a DirectInput joystick – you have to use XInput controller emulation software that can be tricky to set up and doesn’t work with every game.

Wouldn’t it be great if there was a simple, turnkey way to make your Arduino emulate an Xbox controller and work out of the box with these newer games?

Introducing: Arduino XInput!

The Arduino XInput Library makes it easy to convert most USB capable Arduino boards into a fully fledged Xbox controller that is plug and play with Windows. The library gives you access to all of the controls available on an Xbox 360 controller:

  • 10 + 1 Digital Buttons
  • 2 Analog Joysticks (16 bit)
  • 2 Analog Triggers (8 bit)
  • 1 Four-Way Directional Pad (D-Pad)

The library also processes received data, so you can read the status of the controller’s 2 rumble motors (8-bit), the assigned player number (1-4), and the index of the current LED animation. Data is sent and received automatically over USB, so the Arduino is free to do whatever else you want in your main sketch.

Boards

The Arduino framework makes it easy to append the USB descriptors but not to replace them altogether. This means that unlike most USB mode libraries (Keyboard, Joystick, MIDI, etc.), this library will not work out of the box without some additional configuration. In this case, a boards package specific to the Arduino you’re trying to use.

I’m launching the library with three boards packages, which add support for the USB capable Arduino AVR boards, SparkFun AVR boards, and the Teensy 3 boards. Over twenty microcontrollers are supported, including:

For a full list of supported boards, see here. Note that Arduino boards without native USB support (Uno, Nano, Mega) are not supported.

Limitations

Much as I hate to say it, unlike most of my other projects this library comes with two main caveats – two main limitations that make this significantly less useful than it could potentially be.

No Console Support

Unfortunately although this will enable the Arduino to act like an Xbox controller for a PC, it will not work with an Xbox console. The Xbox 360 controller contains a dedicated security chip that is used to verify that only authorized devices can communicate with the console. As far as I’m aware this security method has not been fully broken (at least not openly). Without this security chip or a software approximation of it, the Arduino will not be able to communicate with the console.

With some reverse engineering it should be possible to filter for these requests and build a system to pass them on to a security chip that has been desoldered from a genuine controller, but that’s a project for another day.

No Commercial Use

This is a harder pill to swallow but it’s a necessary evil. For this to work the Arduino board emulates an Xbox 360 wired controller, which means it also borrows the use of Microsoft’s USB VID and PID so that the Windows driver will pick it up. Without this VID/PID combination the driver will ignore it, and it won’t function as a controller.

Because this project makes use of Microsoft’s identifiers to work, this is strictly for non-commercial use. Sorry!

For the Future

There’s still some room to grow with this project, mostly in regards to supported boards. Originally this started as a spinoff of Zach Littell’s XInput project working for the Teensy, but I’ve since added support for AVR boards using the Arduino USB stack. With the Arduino IDE’s ability to reference other core files, it’s quite easy to add support for additional boards that use the same architecture (see the SparkFun AVR changes for reference). I believe I’ve covered the basic boards most people will want to use, although with the core defined additional USB capable AVR boards should take only a few minutes to add.

Eventually I’d like this to support other architectures such as ARM. I’ve added some documentation to the library repository explaining how the library’s USB API works, so if anyone wants to build support for other boards please be my guest!

Download

The library is available to download on GitHub, as are the required boards packages. I’ve also written a tutorial post for how to get started with the library. Enjoy!

12 Comments

  1. Hey, I wanted to try the code for a small project.
    But after installing both the library and the boards files and loading the blink test and I try to compile with one xinput boards selected it fails with:
    “cc1.exe: error: -fno-fat-lto-objects are supported only with linker plugin.”

    With the standard boards (ex. leonardo) the code compiles fine..
    I’m on Win10, and Arduino 1.8.9.

    Martin A
    1. That error seems to indicate that there’s a problem with the XInput boards finding the path for the compilation tools. I’d double check that you’ve installed the boards correctly.

      If you still need help, please create an issue on the relevant boards repository with full steps to reproduce and I can look into it more.

      Dave
      1. Hi, just tested on another machine (a raspberry pi) and there it works. So guess somethings borked on my windows machine. 🙂

        Btw, is there any chance of making this work on the 16u2 on a Arduino Mega? So that the 16u2 just sets up a controller over the usb and then have a simple serial protocol to talk to the main atmega mcu..

        Martin A
        1. Fantastic, glad to hear you got it working.

          At this time I don’t have any interest in building a set of tools to get ArduinoXInput working on the Uno/Mega’s 16U2. Personally I’ve always thought that the 16U2 USB mode firmwares were a bit hack-y. Although if there’s enough interest I might come back to this and add 16U2 support at a later date.

          If you’d like to tackle it yourself, I have another blog post that breaks down the USB descriptors required. You’ll also need to make a few modifications to the endpoints in order to get them to play nice with the AVR USB controller.

          Dave
  2. Hi Mate!

    Cool thing you did here! I got a few knock off Leonardo boards and tried this for my arcade machine that I built.

    Question… When I use them, they work pretty well apart from a small number of PC games (which I assume they are just really fussy with controllers). I’m using a program called reWASD, which remaps X-input buttons to keyboard keys or other X-Input buttons. When I map to keyboard keys and test it out on Notepad, each button press will type out the letter two or three times. It seems that every time I press a button, it actually activates 2 or 3 times. It’s probably been doing that even before I used the remapping program, but it just didn’t cause an issue. It’s definitely the Leonardo board, because it doesn’t happen with a real Xbox controller.

    OK, so finally the actual question… do you think it’s an issue with the knock-off Leonardo board? A driver issue? Or and issue with the code that it’s flashed with?

    You can test it yourself if you’re interested. The software is called reWASD and there’s a free trial. You just need to map a button to a keyboard and test it on Notepad. Don’t use any of the shift-key function as you’ll need a license.

    Thanks!

    Joe
    1. Hey there!

      Out of curiosity, which PC games were giving you trouble? Was the controller not working at all or was it not behaving like you expected?

      What you’re experiencing is called ‘bouncing‘. When you press down on the switch the metal contacts’ springiness can cause them to push apart momentarily before they make steady contact. The Xbox controller probably have some on-board “debouncing”, either in hardware or software. My library is intentionally barebones because it gives you precise control over the outputs, but that means if you want the outputs debounced you need to do it yourself.

      Check out something like the Bounce2 library, which provides easy to use software debouncing. Just call the XInput ‘set’ functions whenever the debounce object’s state changes. As you experienced, foregoing the debouncing usually isn’t an issue because most games can’t take input that quickly anyways. But it usually doesn’t hurt to add.

      For what it’s worth, if you’re just using the Leonardos for keyboard inputs you could use the Keyboard library instead of my XInput one and forego the remapping software. Unfortunately you can’t use them at the same time.

      Hope that helps!

      Dave
      1. Thanks for the reply.

        I’ll get back to you on those games that I have trouble with. But in the meantime, the bouncing thing you’re talking about… It sounds like a great theory, but sometimes the button deactivates while I still have my finger on the button and I have to let the button go and press it again to activate it again. Would that still be a “bouncing” issue?

        Thanks.

        Joe
  3. Hi Dave, thanks for your great work!

    Unfortunately I always get the same error as Martin A. when compiling for Arduino boards using Arduino IDE 1.8.9 Windows10 x64:

    cc1.exe: error: -fno-fat-lto-objects are supported only with linker plugin

    When compiling for Teensy another error appears:

    recipe.preproc.macros missing

    So currently no way to compile for AVR and Teensy, Which IDE version did you use?

    Thanks in advance!

    Dieter P.
    1. I tested with 1.8.9 on both Windows and Linux before release.

      Questions: Are you installing the IDE from the Windows 10 store or from the standalone installer? What directory are you installing to? When you install the XInput boards are you installing to the AppData cache or the installation directory? Are you sure you’re using the matching Teensyduino version?

      The Teensyduino error in particular seems to indicate that you’re installing something incorrectly, because the replacement files for Teensy XInput don’t modify the platform recipes (platform.txt).

      Please provide steps to reproduce and I can look into it.

      Dave
      1. Dave,

        thanks a lot for your answer!
        Well, what should I say, everything is working now 😉
        I reinstalled everything from scratch, and compiling now works flawlessly on both Windows and my Raspberry.
        So, thanks again for your great work, looking forward to my lightgun-project using your library.

        Dieter P.

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.