Thursday, April 29, 2010

iRacing USB Racing Dashboard

I've had a broken leg for a while so I've been finding more and more elaborate ways to waste my spare time...

One such way was to increase my iRacing safety racing so I can graduate out of the rookie class and drive some fun cars. For anyone who hasn't driven iRacing I would highly recommend it, its the closest thing to a real racing I've found.

I've had a Microchip PIC18F4550 microcontroller lying around for a while which was destined for my motion seat controller. So I dug it out and thought I'd see how easy it was to create a simple led dashboard similar to those in current F1 cars, from the minimum of parts on some breadboard.

It doesn't look pretty, but I was really surprised how easy it was to build a functioning USB device. All in all it took about a day spread out over the weekend. I was lucky to find the wiki of Simon Inns. His article on building a USB pic device was great.

First step was to get the PIC working and hooked up to my PICKit 2 programmer. This was straight forward. It's important to use the power smoothing capacitor otherwise you get programming errors.

After I sorted that I was able to read and program the chips flash memory without trouble. However it had no inputs or outputs so wasn't particularly fascinating!

USB Interface
The PIC18F4550 contains a fully working USB interface. In order to run USB the PIC has particular clock speed requirements - using a 20mHz clock crystal and a couple of small capacitors gave an external clock source compatible with USBs requirements.

I had to build a small adapter to fit the USB plug onto the breadboard. This was a bit of strip board with some pins soldered into it.

In order to test the USB you need to download the Microchip USB framework which is contained in the Microchip Application Libraries. This gives you a fully working USB stack for the device and some PC source code to communicate with it in a variety of examples that are ready to go using MPLAB and the M18 C Compiler.

It took quite a while to get the PC and PIC talking over USB due to a short between the socket case and the adapter board. Once that was solved I was able to program the device with the USB Bootloader.

The bootloader allows you to program the device via USB, so now the PICKit 2 is consigned to my desk drawer. All thats needed is to short a pin when you turn the device on (or add a switch ;-) and the device will enter the bootloader, otherwise it runs your code.

Both the USB stack and boot loader have a configuration file that needs altering for your specific configuration (as you could have switches and leds on any port on the PIC). Choosing the config for the PICDEM2 usb board was approximate to my configuration, I modified this to suit my needs.

The Display
The displays are 7 segment led displays and the rpm indicator is 15 superbright 3mm leds.
7 control lines connect the anodes of each segment to the PICs PORTB output.
PORTA is used as an open collector output to ground the cathode to the relevant display. To do this the output is set to zero, and the TRISA register bit to 0 when the output should current sink (led on) and 1 when it should drain (led off).

The same control scheme is used for the LEDs, arranged into 3 banks of 5.

The firmware I wrote for the PIC multiplexes the output for all the displays, activating the required segments of each display (or led bank) one at a time - switching between them faster than the eye can see to make a solid display.

iRacing Telemetry
Hacking together a quick console app to control the Dash from iRacing was relatively simple too. I took the code from the Microchip USB PC sample (removed it's dependancy on .NET - a case of changing it to use CStrings and the correct Setup API func prototypes) and integrated in into the iRacing sample app to send the rpm and gear to the dash.

Here's the result:

1 comment:

DAN said...

Hi Matt,

Any chance that you would be willing to share the code for the PC telemetry app part of your project? Would like to replicate what you have done with my PIC32.