Search code examples
javaandroiddelayobd-ii

Android send ArrayList commands with delay to OBD


I need to send a list of commands to OBD port with some delay because the ELM327 can't manage all commands together...

I'm trying with this code but not work

public void repeatCommand(){


        for (final String command : commandArray){

            Log.d(TAG, "Giro for");

            final Handler handlerTimed = new Handler();
            handlerTimed.postDelayed(new Runnable() {
                @Override
                public void run() {
                    //Do something after 100ms
                    sendMessage(command);
                }
            }, 1000);


        }

        /*String message = "010C\r";
        sendMessage(message);*/
    }

It's only send the first command after 1 sec but the other commands nope. How can i send all comands delayed for let the write to manage all commands sended to the OBD?

Ok i use the suggested method that send the first command and wait for response.... when get response, send the next message.

 private synchronized void manage(BluetoothSocket socket, BluetoothDevice
            device) {
        Log.d(TAG, "connected, Socket Type:");

        // Cancel the thread that completed the connection
        if (mConnectThread != null) {
            mConnectThread.cancel();
            mConnectThread = null;
        }

        // Cancel any thread currently running a connection
        if (mConnectedThread != null) {
            mConnectedThread.cancel();
            mConnectedThread = null;
        }
        // Cancel any thread currently managing connections
        if (mManageThread != null) {
            mManageThread.cancel();
            mManageThread = null;
        }

        // Start the thread to manage the connection and perform transmissions
        mManageThread = new ManageDataThread(socket);
        mManageThread.start();

        // Send the name of the connected device back to the UI Activity
        Message msg = mHandler.obtainMessage(Constants.MESSAGE_DEVICE_NAME);
        Bundle bundle = new Bundle();
        bundle.putString(Constants.DEVICE_NAME, device.getName());
        msg.setData(bundle);
        mHandler.sendMessage(msg);
        // Update UI title
        updateUserInterfaceTitle();
    }

Here the Thread that manage connection..

  public class ManageDataThread extends Thread {

        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;
        private boolean wait_response = false;

        public ManageDataThread(BluetoothSocket socket) {
            Log.d(TAG, "create ManageDataThread: ");

            mmSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            // Get the BluetoothSocket input and output streams
            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) {
                Log.e(TAG, "temp sockets not created", e);
            }

            mmInStream = tmpIn;
            mmOutStream = tmpOut;
            mState = STATE_CONNECTED;

        }

        public void run() {

            while(true) {
                for (final String command : commandArray) {

                    byte[] send = command.getBytes();
                    write(send);
                    //mState = STATE_WAIT_RESPONSE;

                    byte[] buffer = new byte[1024];
                    int bytes;

                    // Keep listening to the InputStream while connected
                    while (wait_response) {
                        try {
                            // Read from the InputStream
                            bytes = mmInStream.read(buffer);

                            //TODO devo gestire l'arrivo di bytes
                            ObdCommand obc = new ObdCommand();
                            obc.readResult(mmInStream);

                            formattedMessage = obc.getResult();
                            //buffer = (byte) obc.getBuffer();

                            // Send the obtained bytes to the UI Activity
                            mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, formattedMessage)
                                    .sendToTarget();

                            wait_response = false;

                        } catch (IOException e) {
                            Log.e(TAG, "disconnected", e);
                            connectionLost();
                            break;
                        }
                    }


                }
            }



        }

It's little bit imperfect but now it's work.... I will open a new post for stop it and update the array list of commands because if i change the list of commands, the loop keep the old array list, so i need to notify the thread that the arraylist has change

EDIT

Don't use while(true) inside thread, better to use a variable set to True e when need to stop thread set the variable to false, or problem occurs when stop thread....


Solution

  • The proper way to work with OBD2 – which is a serial protocol – is to implement something like a command queue with command-specific callbacks that deliver the response to the command you have requested to it. The command queue should work in a background thread, operating the queue and listening to the serial port. Don't even start w/ delays or similar approaches.