带有Xamarin的Visual Studio(C#)中的OBD II应用程序

时间:2016-06-25 18:15:46

标签: c# android xamarin bluetooth obd-ii

我正在开发一款从OBD II蓝牙适配器接收数据的Android应用程序。设置应用程序和适配器之间的连接工作,但当我向适配器发送命令时,我不会得到正确的结果。它要么返回:

+&CONNECTING LT;

或我刚刚发送给适配器的命令。

应用程序在Visual Studio中使用Xamarin进行编码,以便为Android开发。 代码只显示了应用程序的简化版本,只是在01-1f之间为支持的PID提供代码。

BluetoothAdapter myAdapter;
BluetoothSocket socket = null; 
string rawData;
public BluetoothConnect()
    {

        myAdapter = BluetoothAdapter.DefaultAdapter;
        if (myAdapter == null)
        {
            //Device has no Bluetooth
        }
        if (!myAdapter.IsEnabled)
        {
            myAdapter.Enable();
        }
        BluetoothDevice d = myAdapter.GetRemoteDevice("AA:BB:CC:11:22:33");
        socket = d.CreateRfcommSocketToServiceRecord(UUID.FromString("00001101-0000-1000-8000-00805F9B34FB"));
        socket.Connect();

        byte[] cmd = Encoding.ASCII.GetBytes("AT D");
        socket.OutputStream.Write(cmd, 0, cmd.Length);
        ReadAnswer();
        socket.OutputStream.Flush();

        cmd = Encoding.ASCII.GetBytes("AT Z");
        socket.OutputStream.Write(cmd, 0, cmd.Length);
        socket.OutputStream.Flush();

        cmd = Encoding.ASCII.GetBytes("AT E0");
        socket.OutputStream.Write(cmd, 0, cmd.Length);
        ReadAnswer();
        socket.OutputStream.Flush();

        cmd = Encoding.ASCII.GetBytes("AT L0");
        socket.OutputStream.Write(cmd, 0, cmd.Length);
        ReadAnswer();
        socket.OutputStream.Flush();

        cmd = Encoding.ASCII.GetBytes("AT S0");
        socket.OutputStream.Write(cmd, 0, cmd.Length);
        ReadAnswer();
        socket.OutputStream.Flush();

        cmd = Encoding.ASCII.GetBytes("AT H0");
        socket.OutputStream.Write(cmd, 0, cmd.Length);
        ReadAnswer();
        socket.OutputStream.Flush();

        cmd = Encoding.ASCII.GetBytes("AT SP 0");
        socket.OutputStream.Write(cmd, 0, cmd.Length);
        ReadAnswer();
        socket.OutputStream.Flush();




        cmd = Encoding.ASCII.GetBytes("0100");
        socket.OutputStream.Write(cmd, 0, cmd.Length);

        ReadAnswer();


    }

    private void ReadAnswer() {
        try {
            rawData = "";
            int a = 0;

            System.Text.StringBuilder b = new   System.Text.StringBuilder();
            char c;
            while (((a = (byte)socket.InputStream.ReadByte()) > -1)) 
            {

                c = (char)a;
                if (c == '>')
                {
                    break;
                }
                b.Append(c);
            }

            rawData = b.ToString();
            Log.Info("-----------------------------------", "RawData: " + rawData);
            socket.InputStream.Flush();
        }
        catch(System.Exception e)
        {
            Log.Info("", "" + e.Message);
        }



    } 

我已经尝试过不同的初始化命令组合。

我可以想象问题必须与我的读取输入流的方法或发送命令有关但我无法弄清楚要做什么,因为我是Visual Studio,Xamarin和Android开发的新手

希望你们能给我一些建议!

1 个答案:

答案 0 :(得分:0)

现在太旧了,但也许有人需要。下面的代码已使用Xamarin开发的ELM327进行了测试。

 public void SendCommand( string command , Action<string> onDataRecevied )
    {
        if ( BthSocket.IsConnected )
        {
            byte[] cmd = Encoding.ASCII.GetBytes( command + " \r" );
            BthSocket.OutputStream.Write( cmd , 0 , cmd.Length );
            BthSocket.OutputStream.Flush();


            ReadData( out string d );
            if ( d != "" )
            {
                onDataRecevied( d );
            }



        }
    }

并读取数据

public void ReadData( out string data )
    {
        StringBuilder res = new StringBuilder();

        try
        {
            byte b = 0;


            // read until '>' arrives OR end of stream reached
            char c;
            // -1 if the end of the stream is reached
            while ( ( b = ( ( byte )BthSocket.InputStream.ReadByte() ) ) > -1 )
            {
                c = ( char )b;
                if ( c == '>' ) // read until '>' arrives
                {
                    break;
                }
                res.Append( c );
            }

        }
        catch ( Exception e )
        {
            System.Console.WriteLine( e.ToString() );
        }

      data = res.ToString().Replace( "SEARCHING" , "" );

        /*
         * Data may have echo or informative text like "INIT BUS..." or similar.
         * The response ends with two carriage return characters. So we need to take
         * everything from the last carriage return before those two (trimmed above).
         */

        data = data.Replace( "\\s" , "" );

    }

和以下命令用来初始化设备

 obd2.SendCommand( "AT Z" , ( obj ) => { LogMessage( txtData , obj ); } );
             obd2.SendCommand( "AT E0" , ( obj ) => { LogMessage( txtData , obj ); } );
             obd2.SendCommand( "AT E0" , ( obj ) => { LogMessage( txtData , obj ); } );
             obd2.SendCommand( "AT L0" , ( obj ) => { LogMessage( txtData , obj ); } );
             obd2.SendCommand( "AT S0" , ( obj ) => { LogMessage( txtData , obj ); } );
             obd2.SendCommand( "ATD" , ( obj ) => { LogMessage( txtData , obj ); } );
             obd2.SendCommand( "AT SP 6" , ( obj ) => { LogMessage( txtData , obj ); } );
             obd2.SendCommand( "AT H0" , ( obj ) => { LogMessage( txtData , obj ); } );
             obd2.SendCommand( "AT 1" , ( obj ) => { LogMessage( txtData , obj ); } );
             obd2.SendCommand( "ATST 96" , ( obj ) => { LogMessage( txtData , obj ); } );
             obd2.SendCommand( "AT H1" , ( obj ) => { LogMessage( txtData , obj ); } );
             obd2.SendCommand( "AT H0" , ( obj ) => { LogMessage( txtData , obj ); } );

此行数据= res.ToString()。Replace(“ SEARCHING”,“”);可以想象以下响应41 0c 00 0d。 ELM发送字符串!因此,ELM在每个“字节”之间放置空格。请注意我将字节一词放在引号中的事实,因为41实际上在套接字中是两个字节(两个字符)。因此,我们必须做更多的处理。

希望这会有所帮助。