【问题标题】:OBD II App in Visual Studio(C#) with XamarinVisual Studio(C#) 中的 OBD II 应用程序与 Xamarin
【发布时间】:2016-06-25 18:15:46
【问题描述】:

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

+连接

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

应用在 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 开发的新手。

希望大家能给我一些建议!

【问题讨论】:

  • 尝试将您的蓝牙启用和初始化套接字连接代码封装在 try catchs 中。
  • 验证您是否拥有正确的蓝牙权限,或者在未经明确同意的情况下使用它来启用它。 developer.android.com/reference/android/bluetooth/…ASCII 是正确的编码吗?
  • @Terrance 感谢您的快速回复!刚试过你的建议。 try catch 构造工作正常 - 没有异常。检查权限(启用蓝牙和蓝牙管理) - 应该是我发送和接收所需的全部。在单独的类中尝试了 ASCII 方法,似乎该方法按预期工作。

标签: c# android xamarin bluetooth obd-ii


【解决方案1】:

现在太旧了,但也许有人需要。下面的代码是用 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 ); } );

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

希望这会有所帮助。

【讨论】:

  • 所有这些命令都是在向设备发送其他命令之前初始化设备所必需的吗?
  • @perozzo,是的,这些是设备初始命令,如果您不想依赖 ELM 版本,可以跳过一些。这是pdf,它将告诉您每个命令的作用:sparkfun.com/datasheets/Widgets/ELM327_AT_Commands.pdf
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-19
  • 2010-11-14
  • 1970-01-01
相关资源
最近更新 更多