1

Here is my code for establishing a bluetooth connection with an ELM327 and comunicating with it using a laptop:

import java.io.*;
import java.util.Vector;
import javax.bluetooth.*;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.swing.*;

 public class elmbtooth implements DiscoveryListener
 {  
 private static Object lock=new Object();

 private static Vector remdevices=new Vector();

private static String connectionURL=null;


public static void main(String args[]) throws IOException
{
    BufferedReader b=new BufferedReader(new InputStreamReader(System.in));

    elmbtooth obj=new elmbtooth();
    LocalDevice locdevice = LocalDevice.getLocalDevice();
    String add= locdevice.getBluetoothAddress();
    String friendly_name= locdevice.getFriendlyName();

    System.out.println("Local Bluetooth Address : "+add);
    System.out.println("" +
            "" +
            "Local Friendly name : "+friendly_name);

    DiscoveryAgent dis_agent= locdevice.getDiscoveryAgent();
    System.out.println("********Locating Devices******");
    dis_agent.startInquiry(DiscoveryAgent.GIAC,obj);
    try
    {

        synchronized (lock)
            {
                lock.wait();
            }
    }
    catch(InterruptedException e)
    {
        e.printStackTrace();
    }

    if(remdevices.size()<=0)
    {
        System.out.println("No devices found");

    }
    else
    {

        for(int i=0;i<remdevices.size();i++)
        {
            RemoteDevice remote_device=(RemoteDevice)remdevices.elementAt(i);
            System.out.println((i+1)+".)"+remote_device.getFriendlyName(true)+" "+remote_device.getBluetoothAddress());
        }
        System.out.println("Choose Device to establish SPP");
        int index=Integer.parseInt(b.readLine());

        RemoteDevice des_device=(RemoteDevice)remdevices.elementAt(index-1);
        UUID[] uuidset=new UUID[1];
        uuidset[0]=new UUID("1101",true);

        dis_agent.searchServices(null, uuidset, des_device, obj);
        try
        {
            synchronized(lock)
            {
                lock.wait();
            }
        }
        catch(InterruptedException e)
        {
            e.printStackTrace();
        }

        if(connectionURL==null)
        {
            System.out.println("Device does not support SPP.");
        }
        else
        {
            System.out.println("Device supports SPP.");

            StreamConnection st_connect=(StreamConnection)Connector.open(connectionURL);
            OutputStream outStream=st_connect.openOutputStream();

            PrintWriter pWriter=new PrintWriter(new OutputStreamWriter(outStream));
            InputStream inStream=st_connect.openInputStream();
            BufferedReader in=new BufferedReader(new InputStreamReader(inStream));


            pWriter.write("AT Z");
            pWriter.flush();
            pWriter.write("AT E0");
            pWriter.flush();
            pWriter.write("AT SP 00");
            pWriter.flush();
            pWriter.write("0100");
            pWriter.flush();
            String line=in.readLine();
            System.out.print(line);
            pWriter.write("AT DP");
            pWriter.flush();    
        }   


    }


}

    public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod)
    {
        if(!remdevices.contains(btDevice))
        {
            remdevices.addElement(btDevice);
        }
    }       

@Override
public void servicesDiscovered(int transID, ServiceRecord[] servRecord)
{
    if(!(servRecord==null)&&servRecord.length>0)
    {
        connectionURL=servRecord[0].getConnectionURL(0, false);
    }


}
@Override
public void serviceSearchCompleted(int transID, int respCode) 
{
    synchronized(lock)
    {
        lock.notify();
    }

}
@Override
public void inquiryCompleted(int discType)
{
    synchronized(lock)
    {
        lock.notify();
    }
    switch(discType)
    {
    case DiscoveryListener.INQUIRY_COMPLETED:
        System.out.println("Inquiry Completed");
        break;

    case DiscoveryListener.INQUIRY_TERMINATED:
        System.out.println("Inquiry Terminated");
        break;

    case DiscoveryListener.INQUIRY_ERROR:
        System.out.println("Inquiry Error");
        break;

    default:
        System.out.println("Unknown Response Code");
    }
}


}

The program provides the following output:

BlueCove version 2.1.1-SNAPSHOT on winsock
Local Bluetooth Address : 7***********1
Local Friendly name : ******PC
********Locating Devices******
Inquiry Completed
1.)OBDII 0**********3
Choose Device to establish SPP
1
Device supports SPP.

(The code to search devices , services and spp has been borrowed from the code provided on www.jsr82.com. I know that's highly condemnable but the code was provided with the explanation and i didn't see how I could make something original after reading the procedure explained on the website.)

The console keeps operatiing but the elm doesn't provide any response to the AT commands sent by the pWriter object.Where am I going wrong? The device provides readings for speed and RPM on my cellphone app. So it can't be defective.

Flame of udun
  • 2,136
  • 7
  • 35
  • 79
  • can you please see this Question http://stackoverflow.com/questions/18528792/unable-to-send-atz-command-to-elm-327-after-establishing-connection-with-elm327 – Sankar Ganesh PMP Sep 10 '13 at 11:50

2 Answers2

2

I don't know if the p.Writer.flush() already does this, but try to include a carriage return after each command, so the device knows the command ends.

pWriter.write("AT Z" + "\r");

Edit: I think it's default set to not read spaces, not sure. Been a long time ago since I worked with OBD-II. pWriter.write("ATZ" + "\r");

Most likely not the case, as each CR (\r), the device sends something back. So the problem is somewhere else, I think.

Eric Smekens
  • 1,602
  • 20
  • 32
  • The `flush` method is meant for something else. The explanation for the `flush` method given by `Eclipse` is : Flushes the stream. If the stream has saved any characters from the various write() methods in a buffer, write them immediately to their intended destination. – Flame of udun Aug 26 '13 at 13:25
  • Is pairing necessary to communicate with the device?I don't think I've paired my laptop with the device as it didn't ask for the access code, which I believe is 1234 – Flame of udun Aug 26 '13 at 13:37
  • With my OBD-II connector I couldn't connect if I didn't pair with it. – Eric Smekens Aug 26 '13 at 16:17
  • Probably without the space? The command should get there, and a response should come in. If it's not, something is wrong with the OBD-II device/car or something is wrong with the connection write/read. – Eric Smekens Aug 28 '13 at 06:11
  • I've tried it without the space and also direct requests for parameters such as speed and rpm...didn't work. I had the same concerns regarding input and output streams. I used the `toString()` method to make sure they were being created.And they were. – Flame of udun Aug 28 '13 at 09:27
  • The car and the obd were working when I used obdautodoctor pro in nokia and torque for android. How is pairing established? Will setting the first parameter of the `servRecord[0].getConnectionURL` method to `1` or `2` ensure pairing or is there another procedure to pair devices? – Flame of udun Aug 28 '13 at 09:32
  • I am not familiar with pairing devices programatically. In the OS you can pair devices, but if you didn't pair for Torque, it shouldn't have worked there too. – Eric Smekens Aug 28 '13 at 12:49
  • I managed to pair the devices using `getConnectionURL` but still didn't get a reply.Also sometimes my obd fails to acknowledge requests for SPP – Flame of udun Aug 28 '13 at 17:12
  • After pairing (which is done primarily by win7 , not my program) the OS displays message bubbles saying that OBD2 is coonected on COMxx. The toString() method , when used with st_connect method shows a valid RFComm channel though. Should I then create another part for serial communication along with bluetooth? – Flame of udun Aug 28 '13 at 17:23
  • What I did, is to write to this rfcomm channel or COM-port directly. If the OS bounds it to a COMxx, you can write over that connection. – Eric Smekens Aug 29 '13 at 10:23
  • Win7 changes the COM port on which it establishes the connection on every pairing operation.Therefore that cannot be done here.Perhaps I must incorporate a code to go through an `enum` of all availble ports and look for live connections? Am I sending the correct AT commands?Should they be sent in a string or some other way? – Flame of udun Aug 29 '13 at 10:32
  • Thanks or all the help!+1 – Flame of udun Sep 02 '13 at 13:47
  • Did you find a solution? I would like to know if you did! – Eric Smekens Sep 03 '13 at 06:31
  • Erik.another impediment:(----[link](http://stackoverflow.com/questions/18575839/how-to-halt-operation-until-bluetooth-device-is-paired) – Flame of udun Sep 03 '13 at 14:46
1

Sorry for writing this as an answer cuz I don't have enough reputation to add comment.

Try it: Send data first then close the inputStream (or the socket) of the receiving side. It works for UDP in Java. The methods for receiving of UDP in Java won't stop waiting after receiving data even when they have no more space in buffer. Perhaps Bluetooth receiving method has the same problem.

I couldn't close the socket of the receiver on my Android Device. Let me know if it helped.

  • Well, I could make my code work but the problem was a mistake in Threads, I made a constructor on each class and at the end of my constructors I was calling `run();` method and that was the reason my code couldn't work. –  Sep 08 '13 at 10:45