Category Archives: IoT Projects

Modifying a Classic Game Controller with the Arduino Leonardo

Introduction

In this article we’ll use an Arduino Leonardo board to convert a classic game controller (with an obsolete game port connector) into a modern controller with USB 2.0. The controller we’re converting is an older Logitech Wingman Formula GP racing wheel, but the concepts you learn can be applied to any old controller or pretty much anything that you’d like to use as a controller.

logitech-wingman-formula-gp
Logitech Wingman Formula GP

We’ll configure the Wingman to look like a USB joystick with six buttons. The joystick X-axis will map to the steering wheel and the Y-axis will map to the accelerator and brake pedals. The joystick buttons will map to the buttons on the steering wheel. This generic configuration will allow our modded controller to be compatible with standard joystick device drivers and any racing games that support joysticks.

Project overview

  • Disassemble the Wingman controller to figure out the wiring
  • Connect the wires to the appropriate pins on the Leonardo board; potentiometers (steering and pedals) to analog pins, buttons to digital pins, and +5V & ground
  • Mod the controller case to accommodate the Leonardo and wires
  • Install modified Arduino USB and HID library files to support joysticks
  • Write an Arduino sketch that reads the potentiometers and buttons and sends the data to the connected computer

Important: Be sure to use an Arduino board like the Leonardo or the Micro. They are based on the ATmega32u4m, which has built-in USB communication and lets the boards act like full speed USB 2.0 devices. Other Arduino boards, like the Uno for example, do not have this native capability.

Arduino Leonardo micro controller board
Arduino Leonardo micro controller board

By the way, I researched off-the-shelf game port-to-USB adapters. They are available and they don’t cost too much, but the reviews on them were inconsistent. I don’t blame the adapters though, as manufacturers of game controllers took many liberties with the game port specification. Some were even multiplexing a proprietary data stream over the button wires to quadruple the number of buttons on the controller. Yeah, it was kind of wild back then!

Figure out the wiring

I thought I’d be keeping the DA-15 game port connector intact and adding a matching connector at the Arduino to hook it up. Unfortunately, not all the pins in the DA-15 cable were connected, and the final implementation needed more wires than the original controller. So I cut off the connector and used a Volt-Ohm meter to identify the wires.

If you’re planning to keep the DA-15 intact, use Wikipedia to look up the “standard” wiring diagram for clues only, and then a Volt-Ohm meter to figure out the real wiring.

The buttons were easy to figure out; find the common ground wire and use an Ohm meter to identify the wire for each button. Label the wires or write down the wire color that’s connected to each button. We’ll need to know that when wiring up the Leonardo.

The steering potentiometer was also easy to figure out. Like any potentiometer that’s connected to the Arduino, the outer wires are +5V and ground, the center wire (wiper) connects to one of the Arduino analog pins. The “brakes” and “gas” were a bit trickier. Each pedal had its own potentiometer and the two were wired in series, which worked like a single rheostat. A neat implementation because this way, pressing both pedals at once would cancel each other out. That is, if you pressed the gas, held it down while also pressing the brakes, the car would slow down.

wingman_pots
The two pedals were wired to function as a single rheostat. A nifty design, but not compatible with the Arduino.

This configuration presented a problem for the Arduino however, which doesn’t measure resistance directly. The Arduino needs three wires to configure a potentiometer as a voltage divider.  The two outer wires go (one each) to +5V and ground, the center wire (wiper) connects to one of the analog pins. This way, as you turn the pot, it maps the range of voltages on the analog pin from 0 to +5V, to the values 0-1023. As long as you’re using a 3-wire potentiometer (and not a 2-wire rheostat) you’re fine.

My workaround was to separate the two pots and give each one its own input on the Arduino board. It was a simple matter to combine the two values in code, before sending a single Y-axis value to the PC.

This is what it all looked like on a breadboard

Breadboard Layout

Arduino Breadboard Layout (fritzing.org)

The software

The standard USB HID library for the Leonardo lets it emulate a keyboard and mouse. This is very cool because without installing special drivers, the computer will just see the Leonardo as a standard keyboard and mouse. I needed a joystick however which means modifying HID descriptors and other things I wasn’t eager to do. Luckily (and like many things Arduino) others have already been working on this stuff! I used the joystick-enabled USB HID libraries I found here: https://github.com/Cryocrat/LeonardoJoystick
Download two files (USBAPI.h and HID.cpp) and copy them to your Arduino IDE installation directory, in  \hardware\arduino\cores\arduino\. You will find there are already two files with the same names in that directory. The downloaded files will replace the ones you already have. If you like to be cautious back them up before you copy over the new files.

There is just one class you’ll be using, called JoyState_t. It has properties for each joystick axis and a bit-aligned “buttons” property. Finally it has a method called “setState()” that sends the HID structure to the computer. I hope you’ll find my code easy to follow. Feel free to leave a comment below if you have any questions about how it all works.

This code was developed and tested with an Arduino Leonardo and the Arduino IDE version 1.6.5

 

Conclusion

In this article we demonstrated how to connect an analog controller with potentiometers and buttons, to the Arduino Leonardo board. We also learned how to download and modify the USB HID library to support Joystick emulation and how to write a sketch to read and send controller data to a PC. The same concepts can be applied to a variety of controllers or sensors that can be connected to the Arduino and used to provide input to a computer.

References

Breadboard diagrams were created with Fritzing
(http://www.fritzing.org/)

The USB and HID files
https://github.com/Cryocrat/LeonardoJoystick

Arduino Leonardo official site
(http://arduino.cc/en/Main/ArduinoBoardLeonardo)

The latest Arduino IDE can be downloaded here
(https://www.arduino.cc/en/Main/Software)

Game port information on Wikipedia
(http://en.wikipedia.org/wiki/Game_port)