views:

59

answers:

2

Hello, Can you help me
I want to connect my Motorola droid to OBDKey by bluetooth. I use Bluetooth Chat as for example to bluetooth connect, KWP as protocol

Then I write byte[] command

    command[0]=rawToByte(0x02);
 command[1]=rawToByte(0x85);
 command[2]=rawToByte(0x05);
 command[3]=rawToByte(0xc7);
 command[4]=rawToByte(0x33);
 command[5]=rawToByte(0xf1);
 command[6]=rawToByte(0x00);
 command[7]=rawToByte(0x00);
 command[8]=rawToByte(0x00);
 command[9]=rawToByte(0x00);
 command[10]=rawToByte(0x00);
 command[11]=rawToByte(0x00);
 command[12]=rawToByte(0x00);
 command[13]=rawToByte(0x00);
 command[14]=rawToByte(0x76);

where function "rawToByte" is:

public static byte rawToByte(int b) { return (byte) (0xff & b); }

In the result OBDKey sent to device byte 0x02 This value is the first command, so it copy value

What did I do wrong?

A: 

The OBDKey is an ELM327 based bluetooth OBD adapter. It's just like the DealExtreme and scantool.net bluetooth adapters as far as features and method of use. I'm quite familiar with the latter two.

Here's how to send a string to the device, assuming you already opened the socket and stream, and the output socket is named mBTOutputStream

/**
 * Send the exact string provided. 
 * We don't append a CRLF or anything like that - we just send the exact string to the device as-is. 
 * @param sendThis - exact string to send to the device. 
 * @return - returns true unless a problem occurs, in which case we return false;
 */
public boolean sendRaw(String sendThis) {

        // Ya can't send data if we're not connected!
        if (isConnected() != true)
                return false;

        byte bsendThis[] = sendThis.getBytes();

        try {mBTOutputStream.write(bsendThis);} catch (Exception e) {
                ioErrorOccurredDuringOutput();
                return false;
        }

        ioResetOutputErrorCount();
        return true;
}

Also remember to also read from the device, otherwise the input buffer will become full and start blocking I/O.

Brad Hein
Thanks for response, but what is the string "sendThis"?
vic
You would use the method like this: `sendRaw("ATI" + "\n");` So when you execute the method it sends the string "sendThis".
Brad Hein
Why I must send to device String when it understand only array of bytes(commands)?What does function ioResetOutputErrorCount() do?
vic
the ioError/ioReset methods are used to keep track of IO Errors in my app. I use it as an extra safety measure to know the integrity of the connection. You may remove them before using the method. As for the reason for using a String, it will make your life much better to work with Strings when communicating with this device and let the `sendRaw()` method convert the string to a byte array at the last minute - so you don't have to. Have you obtained the datasheet for the device yet so you know what commands to send it?
Brad Hein
In fact, I already wrote an end to end application for the ELM327 Bluetooth devices. It's on the market as VoyagerConnect. I may be releasing parts of the source code in the future.
Brad Hein
The sending commands depends on protocols(KWP,PWM,VPW and ISO ) . You can see more detail information there http://en.wikipedia.org/wiki/OBD-II_PIDs and in the source open project OBDGaugeAre you sure that OBDKey bluetooth is an ELM327?I read that they are different interfaces
vic
The main problems that I write data to device, but it response the same first byte which I sentWhy do I give such response?
vic
I guess that's the beauty of ELM327 - it hides all the complex logic to the point where people don't even know its an ELM327. You're missing a few key points that are making things difficult for yourself. 1. Yes it is an ELM327 chip. The ELM echo's back your commands along with the response, that is why you are seeing your request echo'd back to you. 2. You have to send the bytes to the device as a string not as binary. In other words, to read the DTCs you have to send the string "03\n" to the device. When that is translated to a `byte[]` it will become 0x30 0x33 0x10... do you understand?
Brad Hein
Thanks now it is more clear. But what does "03\n" mean? How I will know what kind of String I must send?
vic
"03\n" is a basic Java string. the \n is an escape character which translates to a single byte called a "line feed". A Line feed is equivalent to hitting the enter key on the keyboard. Every command you send to the ELM has to be terminated with \n. You will also notice that these characters (0x10 for \n and 0x13 for \r) in the ELM response. They are sent together, and separate the echo back, and the response from the ECU.
Brad Hein
I done some test with My OBDKey At first I send the String "03\n" This is a list of conversation between my device(me) and OBDkey using my programme:03OBDKey:0OBDKey:3I think this is wrong response.So then I decided to connect to OBDKey using your program.Result is Connected to OBDKey ,but then -Initializing the ELM chip -INIT:ATZ=Fail... -sending init commands took 4 extra tries -Result from sendInitCommmands():false
vic
How I understand , they were connected but it didn't send commandsSo my application do the same, I need to send data succesful How can I do this?
vic
Why do you think that is the wrong response? When you send 03, you will get a 0, a 3, a CR/LF, then the response to that command. I'm starting to wonder if you are understanding anything that I am telling you? You must read the elm327 data sheet like I told you. It won't make sense until you read it.
Brad Hein
And how I must read the elm327 data sheet?protected void startDevice() throws IOException, InterruptedException { sock = this.dev.createRfcommSocketToServiceRecord(MY_UUID); sock.connect(); in = sock.getInputStream(); out = sock.getOutputStream(); while (!stop) { ObdCommand echoOff = new ObdCommand("ate0", "echo off", "string", "string"); String result = runCommand(echoOff).replace(" ",""); if (result != null } Thread.sleep(1500); } }
vic
This was example from obd-reader google.code Are you using it on your nice program how a base example? Can you give me example how I must read the elm327 data sheet? I'd appreciate that
vic
The elm327 datasheet is actually a PDF document :) http://www.elmelectronics.com/DSheets/ELM327DS.pdf
Brad Hein
Thanks it's great! I am trying to test my aplication, but the OBDKey didn't response to meAt first I send command : atsp0 - automatically find needed protocolthen I send : ate0 in the result I want to give information about speed
vic
public class SpeedObdCommand extends IntObdCommand { public SpeedObdCommand() { super("010D",ObdConfig.SPEED,"km/h","mph"); } public SpeedObdCommand(SpeedObdCommand other) { super(other); } @Override public int getImperialInt() { if (intValue <= 0) { return 0; } return (int)(intValue * .625); }}
vic
What I did wrong ? Why it didn't response?
vic
Can you give me some code example of sending commands?
vic
The idea here is to ask a single question and answers and choose one. It's time to accept an answer. If you want more advice, we should take this offline, you can email me at my gmail account Linuxbrad.
Brad Hein
A: 

This is my part of testing code. Before this my Motorola was paired and connected to OBDKey

/** * This thread runs during a connection with a remote device. * It handles all incoming and outgoing transmissions. */ private class ConnectedThread extends Thread {

    private final InputStream mmInStream;
    private final OutputStream mmOutStream;

    public ConnectedThread(BluetoothSocket socket) {
        Log.d(TAG, "create ConnectedThread");
        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;
    }

    public void run() {
        Log.i(TAG, "BEGIN mConnectedThread");
        byte[] buffer = new byte[32];
        int bytes;

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

                // Send the obtained bytes to the UI Activity
                mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, bytes, -1, buffer)
                        .sendToTarget();
            } catch (IOException e) {
                Log.e(TAG, "disconnected", e);
                connectionLost();
                break;
            }
        }
    }

/** * Write to the connected OutStream. * @param buffer The bytes to write */ public void write(byte[] buffer) { try { mmOutStream.write(buffer);

            // Share the sent message back to the UI Activity
            mHandler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1, buffer)
                    .sendToTarget();
        } catch (IOException e) {
            Log.e(TAG, "Exception during write", e);
        }
    }

    public void cancel() {
        try {
            mmSocket.close();
        } catch (IOException e) {
            Log.e(TAG, "close() of connect socket failed", e);
        }
    }

/** * Write to the ConnectedThread in an unsynchronized manner * @param out The bytes to write * @see ConnectedThread#write(byte[]) */ public void write(byte[] out) { // Create temporary object ConnectedThread r; // Synchronize a copy of the ConnectedThread synchronized (this) { if (mState != STATE_CONNECTED) return; r = mConnectedThread; } // Perform the write unsynchronized r.write(out); }

I use function "write" to write commands[]. In the rezult it writes bytes, but it reads not corect .

For example, if I send such bytes 02 01 03 it will read 02

if I send such bytes 1C 01 05 it will read 1C

What did I do wrong? Is this a problem with connect to OBDKey or with wrong send byte[] to OBDKey?

vic