1

I'm out of ideas as to what is wrong with this. I'm trying to send and receive data from my bluetooth ELM327. Torque works, and I've used a terminal app to send commands and that also returns correct results. So I don't get what I'm doing wrong here. This is the thread that handles all of it. I'm using Pires java obd library, found here

I'm getting back a "?" for all of the initialization commands, but when I start looping the vin command it starts returning "OK" and at one point I was able to actually get the vin correctly, but I had to loop a bunch of times to get it.

The connection is being made as a socket is returned. Commands are sent(per the library) in the format "AT L0" and as such

out.write((cmd + "\r").getBytes()); out.flush();

I have tried putting the parent send and receive commands in separate blocking threads (using Thread.join()) and that didn't change anything. I've put a delay up to Thread.sleep(1500) with no changes. I'm not sure what else to try, and I'm fairly new to android and bluetooth development as well so any help you can give is greatly appreciated.

Here's my code for the thread called from the UI-thread:

public class spawnThread implements Runnable {
    protected BlockingQueue<obj> jobsQueue = new LinkedBlockingQueue<>();
    protected Long queueCounter = 0L;
    protected BluetoothSocket sock = null;
    protected ArrayList<obj> process_list;
    protected Handler main_handler;
    protected setting_objs temp_objs = new setting_objs();
    protected BluetoothDevice bt_device;
    protected boolean initialized = false;
    protected boolean can_continue = true;

public spawnThread(Handler handler, BluetoothDevice bt_device, ArrayList<obj> list) {
    this.jobsQueue = new LinkedBlockingQueue<>();
    this.queueCounter = 0L;
    this.bt_device = bt_device;
    this.process_list = list;
    this.main_handler = handler;
}
public void run() {

    while (!Thread.interrupted() && can_continue) {
        if(sock == null){
            bluetooth_init();
        }
        if(!initialized && can_continue){
            init_commands();
        }
        if(can_continue){
            testing_commands();
        }
    }
}

private void bluetooth_init(){
    UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    try {
        sock = bt_device.createRfcommSocketToServiceRecord(uuid);
        sock.connect();
    } catch (IOException e) {
        e.printStackTrace();
        can_continue = false;
    }
}

private void init_commands(){

    ArrayList<obj> init_objs = temp_objs.init_array;

    for (obj init_cmd:init_objs
         ) {
        queueJob(init_cmd);
    }

    try {
        executeQueue();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

private void testing_commands(){
    String vin = "";
    obj vin_obj = temp_objs.find_by_value("VIN");
    for(int j = 0; j < 15; j++){

        queueJob(vin_obj);
        try {
            executeQueue();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        vin = vin_obj.command.getFormattedResult();
        Log.d("vin count: " + String.valueOf(j)+ " ", vin);
    }
}
private void queueJob(obj current) {
    queueCounter++;
    current.getCommand_job().setId(queueCounter);
    try {
        jobsQueue.put(current);
    } catch (InterruptedException e) {
        current.getCommand_job().setState(ObdCommandJob.ObdCommandJobState.QUEUE_ERROR);
        Log.e("OBD LOG", "Failed to queue job.");
    }
}

private void executeQueue() throws InterruptedException {
    while (jobsQueue.size() > 0) {
        ObdCommandJob job = null;
        obj job_obj = null;

        try {
            job_obj = jobsQueue.take();
            job =  job_obj.getCommand_job();                    
            job.setState(ObdCommandJob.ObdCommandJobState.RUNNING);

                if (sock.isConnected()) {
                    job.getCommand().run(sock.getInputStream(), sock.getOutputStream());
                    //send data to be bundled.
                    if(job_obj != null){
                        bundle_data(job_obj);
                    }
                } else {
                    job.setState(ObdCommandJob.ObdCommandJobState.EXECUTION_ERROR);
                    Log.e("OBD LOG", "Can't run command on a closed socket.");
                }
        } catch (InterruptedException i) {
            Thread.currentThread().interrupt();
        } catch (UnsupportedCommandException u) {
            if (job != null) {
                job.setState(ObdCommandJob.ObdCommandJobState.NOT_SUPPORTED);
                Log.w("OBD LOG", "Command not supported. -> " + u.getMessage());
            }
            Log.w("OBD LOG", "Command not supported. -> " + u.getMessage());
            Log.w("OBD LOG", "Job is null");

        } catch (Exception e) {
            if (job != null) {
                job.setState(ObdCommandJob.ObdCommandJobState.EXECUTION_ERROR);
            }
            Log.e("OBD LOG", "Failed to run command. -> " + e.getMessage());
        }


    }
}
Tony Shepherd
  • 115
  • 1
  • 8
  • Does this link provide any insight? http://stackoverflow.com/questions/12227559/how-to-have-multiple-connections-to-a-single-obd2-bluetooth-device-connected-to?rq=1 – Zoot Jan 21 '16 at 20:30
  • Not really. I'm only working with one thread to handle communication to the ELM327 device. This thread (code above) sets up the bluetooth socket, and runs the commands. There are calls to other classes but it's on the same thread. I tried using AsyncTasks for the functions that write and read from the ELM327 to make sure it wasn't sending/receiving at the same time but that didn't fix/help anything. – Tony Shepherd Jan 21 '16 at 20:38
  • Is the car ignition on? You might have trouble getting a VIN after the modules go back to sleep, which they will if the ignition is off or even after it has been on for a while – Jon Jan 23 '16 at 03:27
  • Yes the car was on during testing. If I loop the vin command eventually I can get it, but it should come on the first call... Not the 10th – Tony Shepherd Jan 23 '16 at 08:31
  • Which ECU are you querying for the VIN? – Jon Jan 23 '16 at 14:53
  • Usually a '?' response means that the ELM327 interpreter hasn't recognised the command sent to it. When sending the initialisation commands, e.g. ATZ\r you don't need a car connected / ignition on, just the 12v and ground will do. – obdkey Jan 24 '16 at 14:42
  • Can you post a complete transcript of the initialization sequence (including queries and responses)? – DrMickeyLauer May 28 '17 at 13:32

0 Answers0