In this article we will look at the OBD-II sub-system and instrument cluster application of the Project Detroit Mustang we built with West Coast Customs. If you’re not familiar with this project.
OBD-II
OBD stands for On-Board Diagnostics. In the world of cars, this can be thought of as the computer which has a variety of data points which can be queried, such as speed, fuel level, and even trouble codes that relate to the check engine light. If you’ve ever taken your car in for service, your service center has hooked up the car to a computer via the OBD port to get the status of the car and what may not be working properly.
Getting Started
To use the OBD library with your vehicle, first you need an OBD-ii to USB or serial cable. These can be found in numerous places, but we recommend this cable from carobdcode.com, which was used with the Project Detroit car and our software. Here’s how to get connected:
- With the car off, plug the OBD end into your vehicle. The port is in a different location in every vehicle, but it’s guaranteed to be somewhere near the driver’s location.
- Plug the USB/serial end of the cable into your computer and note which COM port the cable is connected to.
- Update the app.config file of the InstrumentCluster project with that COM port.
- Start the car.
- Run the InstrumentCluster application, and data should start flowing.
Calling the OBD library programmatically
- Create an instance of the ObdDevice class
- Call the Connect method with the appropriate COM port, baud rate, and, if known, OBD protocol
- From here, the library works in two ways: automatic polling or manual polling
- Automatic – Pass true to the Connect method. This will poll the OBD as quickly as it can requesting RPM, MPH, MPG, Fuel Level and Engine Coolant Temperature. Note that not all vehicles will support all of these. In this mode, hook the ObdChanged event to receive an ObdState packet with the new data.
- Manual – Pass false to the Connect method. Then, create your own thread and call the ObdDevice‘s Get methods to retrieve the data you want as quickly as you want it. This is the way we used the library in Project Detroit. We polled manually, collecting the speed, RPM, and other critical data as quickly as possible, while only reading things like fuel level every few seconds.
OBD-ii is a polled system, so data can only be returned as quickly as the time it takes to request it and return it. In short, only retrieve what you need when you need it.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
ObdDevice obd; obd = new ObdDevice(); obd.ObdChanged += _obd_ObdChanged; // com port, baud rate, protocol (if known), automatic polling obd.Connect( "COM1" , 115200, ObdDevice.UnknownProtocol, true ); ... void obd_ObdChanged( object sender, ObdChangedEventArgs e) { e.ObdState.ToString(); } |
Customizing the Instrument Cluster
The Instrument Cluster application is a WPF application that has 3 different skins which can be viewed by swiping left or right in the application, either with a finger, or the mouse. This is a simplified version of the actual application we used in the Project Detroit car, modified to talk straight to the OBD port instead of our intermediate WCF service. Please note that this isn’t a robust, drop-in replacement application for a car dashboard, but only a sample of how the OBD library can be used.
Internally, the application uses the OBD library and hooks the ObdChanged event. The ObdChanged event returns a minimal amount of important data. When the event fires, the the SetInstrumentClusterValues method is run, which sets the OBD values to each gauge in whichever skin is currently visible.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
private void SetInstrumentClusterValues(ObdState measurement) { foreach ( var item in _skins) { if (!item.IsVisible) continue ; item.IsMalfunctionVisible = measurement.MilLightOn; item.IsLowFuelVisible = item.Fuel < 10; item.MPG = measurement.MilesPerGallon; item.MPH = measurement.MilesPerHour; item.RPM = measurement.Rpm; item.Fuel = measurement.FuelLevel; item.Temperature = measurement.EngineCoolantTemperature; } } |
Known Issues / Limitations
- This is known to work with cables that uses the ELM323/327 chipset. The specific cable that was used to develop this library is available from carobdcode.com, however other ELM323/327 OBD-II to USB cables should work.
- There are a variety of different OBD-II signal protocols. This library only supports a few of them. If your car’s OBD protocol is not supported, please feel free to add it and send us the changes to integrate back into the library!
- If the vehicle has multiple ECUs, the ECU with the most PIDs is used. The other ECUs are ignored.
- Not every standard PID is supported.
- No custom manufacturer/model-specific PIDs are supported.