Reusing an old game port steering wheel
Introduction
Well, I have this bad habit of holding on to everything, so as you can imagine, I have quite a few old stuff lurking around. One of these was this good old thurstmaster formula 1 racing wheel, which served me well back in the days, but is now completely useless as modern PCs have no game ports.
Gameport? What is that?
The game port was a traditional connector for video game input devices back in the day, usually integrated on the sound card. Since USB has taken over for almost all devices out there, the game port has pretty much vanished from the game controller industry. This is indicated clearly by even Microsoft discontinuing game port support from Windows Vista.
It featured a number of analog (converted into digital with an ADC [analog digital converter on the sound card]) and digital signals, which were usually driven by potentiometers and switches. This allowed for 4 digital buttons, and 4 analog axis, which could be used in one joystick, or two with an appropriate splitter cable. (More at: http://en.wikipedia.org/wiki/Game_port)
Thrustmaster Formula 1 Steering Wheel
The steering wheel contains two buttons on the wheel itself, a stick shift with up and down (respectively two more buttons), and an accelerator and brake pedals. The steering wheel and the pedals are the analog signals, using the supplied Vcc and GND to return a voltage corresponding to the position of the wheel. After measuring the signals with a volt meter, the readings did not seem to vary a lot, so putting in an extra resistor on the two analog lines (acting as a voltage divider) allowed for some better measurements.
Arduino
Even though I have been doing some microcontroller programming the last couple of years, I have only recently discovered the Arduino. It seems like a hot topic nowadays, and it turns out it can be pretty useful in certain situations. The aim of the device is to provide everyone a relatively easy start into the microcontroller world, and yet it still manages to keep the flexibility to do advanced stuff too (such as in line assembly or direct register manipulations). It provides some very convenient libraries to prototype projects fast, without having to deal with very low level issues such as timers/interrupt service routines and such. (More at: http://www.arduino.cc/)
The Project
To give a better idea on how the project is built up, here is an overview:
The first step in the process is that the joystick needs to be calibrated. Why? Because every analog joystick is a bit different, which means returns a different range of values for the same position. Moreover, due to mechanical wear, this calibration process needs to be redone every now and then too.
During the calibration process, the two analog axis need to be moved to their furthest possible locations in order to find out the minimum and maximum positions, as well as their center. The center is also important, because there are cases where the center is NOT in the middle of the maximum-minimum location, and in that case the joystick would constantly “turn left” (or right in the case of a steering wheel), or accelerate/brake without pressing the pedals.
So to return meaningful and uniform values from any kind of joystick, the decision was made that it will return the location of each axis in percentage, being 50% the neutral position. (The calculation on how the values were normalized can be found in the source code)
Once the values are read out of the joystick, a packet size of 7 bytes are sent over the serial line to the PC. These 7 bytes consist of the first byte indicating if the joystick has been calibrated or not, then the values for the X and Y axis, and the values for the four buttons. (This could be further optimized by modifying individual bits in a byte for both the calibration and the 4 buttons, but programming wise this was simpler and there aren’t any latency concerns to worry about)
On the PC side, a small C code is sitting and listening on the serial port for packets, once it receives them it does some post processing (inverting axis: I found out that apparently >50 is braking and < 50 is accelerating… would have thought the opposite…), and sends the received values to the PPJoy Virtual Joystick (http://ppjoy.blogspot.com/) over some IOCTLs. PPJoy emulates a joystick device, which can then be used in any game which supports the standard joysticks.
And thats it! A few hours of hacking over the weekend, and the old steering wheel is back in action.
Sure I could have went out and bought a new USB steering wheel, or an existing game-port to USB device, but where is the fun in that? The journey is just as important as the results right?
Posted by admin on March 27th, 2011 :: Filed under Default