Part 2: Hardware Design
Now, let’s start with a clear problem statement. My goal is to get mouse and keyboard support for games working with an Xbox One.
The way I’m going to solve this is by “hijacking” the input of an existing controller, and then I will use a piece of custom hardware to simulate button presses, the analog sticks moving, and so forth. The controller (and whatever it is plugged into) won’t have any idea that it isn’t a person controlling the game.
The Sacrificial Controller
I recently retired an old Xbox 360 controller – specifically, a Razer Onza TE. I’ve had nothing but trouble with the Onzas I’ve owned. They don’t quite recenter right, and the triggers don’t always register that they’ve been pulled fully. I went back and forth with Razer’s support on this, and had several replacements that all failed.
Needless to say, I’m not going to miss this hunk of junk. What if I could convert it into a device I could control using my PC? Then, I could use any input device that works on PC, and translate that to buttons pressed and sticks moved on the controller!
(Yes, it’s an Xbox 360 controller, and my goal is Xbox One. However, the Xbox One app on Windows 10 accepts a 360 controller just fine, so no issues there.)
Handling the Digital Inputs
My background in computer engineering (almost enough to minor in electrical engineering) tells me that the buttons on most controllers are probably simple switches that connect two terminals together. Usually, one terminal is connected to a pin on the controller’s CPU, and the other is connected to ground. When the switch is pressed, the two pins connect, and the CPU reads that the switch is closed. It then sends a message to the console, telling it that the button has been pressed.
This is not that hard to automate – all I really have to do is connect the CPU pin to a pin on a device that I control. Then I can set that device’s pin to ground, and the controller will think someone pressed the button. This is pretty simple to do, so no problem!
Handling the Analog Inputs
That covers most of the controller’s inputs. However, there’s still the analog inputs to consider. The analog inputs are the two sticks and the triggers.
Each stick as two axes, and each trigger has one. These are actually implemented using variable resistors, called “potentiometers” or “pots.” As you move the stick or trigger, you’re actually moving a “wiper” across the pot, which changes the resistance between sets of its pins. The controller’s CPU is measuring the voltage across these pins, and can use that information to determine where the stick or trigger is along each axis.
This is a trickier problem to solve, since we have to fake an analog voltage, which is a bit harder than just pulling a pin to ground. Luckily, “digital pots” exist. These devices can have their resistance programmed, allowing them to be set by a computer rather than a person.
OK, we’ve determined conceptually how we’re going to remove the human element from the controller, and replace it with the PC. Now we actually have to put some hardware together that is up to the task.
- Something that the PC can talk to – a USB device, probably. This is how we’ll send commands to our controller.
- A bunch of digital I/O pins that can be wired up to the buttons.
- A set of digital pots (6 total) that can control the 4 stick axes and the 2 joystick axes.
- A way to control the digital pots and interface them with the rest of the system.
This sounds complicated, but luckily in recent history there have been lots and lots of very sophisticated boards available that can solve a lot of these things in one fell swoop. On top of that, they’re easy to program, which keeps the amount of support software we have to write to a minimum.
The Microcontroller Board: Teensy 3.1
The board I chose for this project is the Teensy, specifically this Teensy 3.1 from Newark. There are a bunch of different ways to get a Teensy – I picked this one at Newark because I wanted to order the rest of my parts there.
The Teensy has a ton of I/O pins (check), it can be controlled over USB via serial (double check), and it can interface with other chips via SPI (triple check)!
Choosing the Right Digital Pots
Now all we need are some digital pots that are SPI-programmable. There’s just a ton of them out there, with all sorts of different values and features.
I measured the total resistance of the controller’s pots to be around 20kOhms, so I wanted something that could go at least that high, just in case that was important for the functioning of the analog sticks. There are “volatile” pots that don’t remember their last settings when the power is removed, and that’s fine since my Teensy will be taking care of setting them up when they power on.
Digital pots are also rated by how many “steps” they have – the more steps, the more fine-grained control I’d have over the sticks. However, the minimum number seemed to be 128, which seems like a LOT for an analog stick. Probably most people can’t get more than 3 or 4 different positions between “centered” and “fully pushed.” I went with 256 steps anyhow, just because it didn’t really matter in terms of cost.
Finally, I chose a digital pot that had 2 pots in one chip. That way, I only had to buy 3 of them, and there are fewer pins to worry about overall. They make some that go as high as 6 pots on a single chip. This would be great for my project, since I need exactly 6. However, it was a little too expensive to justify.
The final part I settled on was MCP4251-503E/P, which runs around $0.75 as of this writing.
Hacking the Sacrificial Controller
Now that the parts are on order, it’s time for demolition. The first step of the mouse and keyboard to controller build is disassembling the sacrificial Xbox 360 controller. I took the controller apart and desoldered almost everything on the board. Rumble motors? Trashed. Switches? Trashed. Analog sticks? Also trashed. Some of it was kind of tricky to desolder, and unfortunately I pulled the via for the X button off. (Whoops!) Luckily, this controller has extra programmable buttons, so I just set one of them to be the X button instead.
In place of all the important switch terminals, I put regular male header pins instead. I did this so that I could have a bit more flexibility in how the controller is put together, and so that I could change out the “brains” on the PC control side if I so choose. Some multicolor jumper wires connect the remnants of the controller board to my breadboard, where the custom hardware is.
Wiring the Teensy
The Teensy came with a nice full-color, glossy card explaining all of its pins, and that was a big help. I worked with the digial pots first, wiring them up to the SPI bus.
SPI is a serial protocol that has a clock pin, an input pin, and an output pin. There’s also a “chip select” pin, which allows me to reuse the same input/output/clock pins for multiple chips. I pick which chip is going to receive a command by pulling the corresponding chip select pin to ground.
Unfortunately, I had a lot of trouble getting the pots working. A lot of the time, the pots wouldn’t change their values properly, or they’d report success even when I sent down an obviously invalid command.
I eventually suspected that signal integrity was to blame, so I installed some very small caps and resistors to try to mitigate any sort of weirdness introduced by the breadboard or anything else in my system. This improved things immensely, and got me back on track.
The digital switches were connected to the Teensy’s IO pins, and these worked the first time with no issues.
OK, great! Now the Teensy can command the controller. We’re one step closer to being able to use a mouse and keyboard with the Xbox One. Now, we’ve got to write the software.