How can I read/write data to and from an OBD-II adapter with Windows Phone 8?

29.7k views Asked by At

I am currently working on a Windows Phone 8 application, which will (hopefully) have the capabilities to connect to a vehicle via bluetooth using a bluetooth OBD-II adapter. I'm reasonably new to programming for WP8, although I'm attempting to not try and to ask for help but I've sort of hit a part where I just can't think nor understand where to go or what to do.

Additionally, if anyone wants to know the device I'm testing with to connect to the car it's this guy here

EDIT:: So far I have set my code to detect if the Bluetooth adapter is enabled, I'm currently looking into (or trying to understand) how can I display to the user the paired devices so they can select one. But my main brain block at the moment is, how I can read (or pull) data from the OBD-II adapter? It says in the software documentation this:

To signify that the Kiwi Wifi or Kiwi Bluetooth is ready to process commands, the device will output a greater-than sign (>).

So if I've understood this correctly, I would need to check for > , right? But how? I've checked loads of sources but none really explain how. I came across stuff like IBuffer, but I have no understanding of that at all.

If what I've said makes no sense, then simply put.

  • Read data from OBD addapter
  • Write data to OBD adapter (The software documentation says I need to send ASCII code, I've got those)

If I can understand how to read/write to it, then I think I should be capable of manipulating the data back to the user; I hope.

EDIT 2::

private async void checkBluetooth()
    {
        SolidColorBrush statuscolor = new SolidColorBrush();
        try
        {
            PeerFinder.AlternateIdentities["Bluetooth:Paired"] = "";
            var devices = await PeerFinder.FindAllPeersAsync(); 
            bluetoothStatus.Text = "Online"; 
            statuscolor.Color = Colors.Green; 
            bluetoothStatus.Foreground = statuscolor; 

            if (devices.Count == 0)
            {
                MessageBox.Show("No paired bluetooth devices have been found, please pair your OBD adapter first!");
                await Windows.System.Launcher.LaunchUriAsync(new Uri("ms-settings-bluetooth:"));
            }

            PeerInformation peerInfo = devices.FirstOrDefault(c => c.DisplayName.Contains("PLX"));
            if (peerInfo == null)
            {
                MessageBox.Show("No paired PLX adapter found, please pair the PLX OBD adapter!");
                await Windows.System.Launcher.LaunchUriAsync(new Uri("ms-settings-bluetooth:"));
            }

            StreamSocket socket = new StreamSocket();
            await socket.ConnectAsync(peerInfo.HostName, "1");

            await socket.ConnectAsync(peerInfo.HostName, peerInfo.ServiceName);
        }
        catch (Exception ex) 
        {
            if ((uint)ex.HResult == 0x8007048F) 
            {
                bluetoothStatus.Text = "Offline"; 
                statuscolor.Color = Colors.Red; 
                bluetoothStatus.Foreground = statuscolor; 
            }
        }
    }
1

There are 1 answers

5
Eric Smekens On

I'm only explaining how you can retrieve data from the OBD-II device by sending data to it, because in my understanding that's the problem you're struggling with.

OBD-II will never send data on it's own, it listens for a command you send and based on that command it will send an answer. So basically you have to do two things if you have a running connection:

  • Send the correct commands to the OBD-II device.
  • Parse the answers into human-readable data.

The ELM327-bluetooth-connector you have translates ASCII commands to voltages. So all you have to do, is send some ASCII commands, and you get ASCII-values back.

The OBD protocol knows several modes and parameter's, but I will explain to get real-time data. That's mode 1.

Mode 1 Sending
Mode 1 is '01'. After that part, you have to send a parameter ID with it. 0C is for RPM, 0D is for speed. And after each command you have to send a Carriage Return. (CR = '\r') So the connector knows when a request is complete.

So basically, for speed, you have to send:

'010D\r'

Receiving Mode 1
The answer you will get back from a Mode 1 query, starts with '41'. After that the parameter ID is returned, and then the value. The value is most of the time in hex. You will have to do some conversion to read a human readable value. For more information, see the link, as formula's to convert are provided too.

Example:

'410D17'

So 17 is the value of your current speed in hex. 17 to decimal is 23, so you're driving with 23 km/h.

This wikipedia page has some good information about it:
OBD-II Parameters

And for the bluetooth part:

STEP 1: Connect to the desired device over RFCOMM

PeerFinder.AlternateIdentities["Bluetooth:PAIRED"] = ""; 
var available_devices = await PeerFinder.FindAllPeersAsync(); 
if (available_devices.Count == 0) 
{ 
       return false;             
} 
else
{             
       PeerInformation pi= // Get the required device using 
                          // index or searching for the device name
}
StreamSocket socket = new StreamSocket(); 
await socket.ConnectAsync(pi.HostName, "1");

STEP 2: Direct winsock to perform an SPP lookup

await socket.ConnectAsync(pi.HostName, pi.ServiceName);

Source: Windows Phone 8 Bluetooth SSP

I hope this helps you out, I'm getting excited about it. ^^ If you need help, let me know.