收到的数据添加到arduino的变量中

时间:2014-09-12 07:57:22

标签: android arduino android-bluetooth

我想将从Arduino收到的数据添加到单个变量中。从Arduino我将发送速度,压力,扭矩数据。 速度 - 2字节(0-3500rpm),压力4传感器(0-10.0bar) - 4字节,扭矩 - 2字节(0-500Nm)。我认为最好的方法是将其发送到一条消息中?或者更好的是发送单独的消息? 如果我发送这样的消息,也许有一种方法可以从字符串中获取数据。

s{B1 B2}s p{B1 B2 B3 B4}p t{B1 B2}t

目前我正在尝试做这样的事情:

  private String output = "";
  private String speed = "0";
  private String speedStart = "s{";
  private String speedEnd = "}s";
  private String pressureStart = "p{";
  private String pressureEnd = "}p";
  private String torqueStart = "t{";
  private String torqueEnd = "}t";

...

byte[] readBuf = (byte[]) msg.obj;
            String readMessage = new String(readBuf, 0, msg.arg1);
            Log.d(TAG, "readMessage="+ readMessage); // For debugging 
            output += readMessage;
            if (output.startsWith(speedStart)){ // At the moment it works only with message s{data}s
                if (output.endsWith(speedEnd)){
                    speed = output;
            txtArduino.setText("Speed: "+ speed);
          Log.d(TAG, "Output="+ output); // For debugging
                output = "";
                }
            }
            else{ // If received string wihtout proper start delete it
                Log.d(TAG, "Output from else before delete="+ output); // For debugging
             output = "";} // If received string wihtout 

从arduino获得更有效的方法吗?可能或任何有效的地图。

另外我应该提一下,有时android会从arduino中分离出消息,例如:

发送字符串"Hello world\n"

接收2条消息中的字符串:

"H" "ello world\n"

修改

经过几次测试后,我注意到蓝牙正在做疯狂的事情。 我发送的#S0270Pa05Pb09Pc10Pd01T013没有换行,所以有26个字节。

我有

case BLUETOOTH_RECEIVED:
        byte[] buffer = (byte[])msg.obj;
        int len = msg.arg1;
        Log.i(LOGGER_TAG, String.format("*** CASE *** Received: " + "%d bytes", len));
        if (len > 0 && buffer != null) {
            onBluetoothRead(buffer, len);
        }
        break;

然后

private void onBluetoothRead(byte[] buffer, int len) {      
    String output = new String(buffer, 0, len); // Add read buffer to new string
    outputTemp += output;
    valid = valid + len;
    //Log.i(LOGGER_TAG, String.format("*** onBluetoothRead *** Received: "+ output + " , " + ", %d lenght", len));
    if (valid == 26){
        Log.i(LOGGER_TAG, String.format("*** subString *** from: " + outputTemp));
         //01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 
         //#  S  0  2  7  0  P  a  0  5  P  b  0  9  P  c  1  0  P  d  0  1  T  0  1  3  \n
    m_deviceOutputSpeed.setText("RPM = " + outputTemp.substring(2, 6));
    m_deviceOutputPrs.setText(
            "Pressure 1 = " + outputTemp.substring(8, 10) + 
            "\nPressure 2 = " + outputTemp.substring(12, 14)+
            "\nPressure 3 = " + outputTemp.substring(16, 18)+
            "\nPressure 4 = " + outputTemp.substring(20, 22));
    outputTemp = "";
    valid = 0;
    }}

和LogCat:

09-16 09:14:34.344: I/DeviceActivity(17610): Bluetooth connected
09-16 09:14:35.334: I/DeviceActivity(17610): *** CASE *** Received: 1 bytes
09-16 09:14:35.344: I/DeviceActivity(17610): *** CASE *** Received: 9 bytes
09-16 09:14:35.344: I/DeviceActivity(17610): *** CASE *** Received: 9 bytes
09-16 09:14:35.344: I/DeviceActivity(17610): *** CASE *** Received: 7 bytes
09-16 09:14:35.344: I/DeviceActivity(17610): *** subString *** from: Pd01T0130Pd01T0130Pd01T013

到底是怎么回事? :)

编辑2

在发送数据之间增加了10ms的延迟:

void send_data(){
  mySerial.write(start);
  delay(10);
  mySerial.write(speed);
  delay(10);
  mySerial.write(prs1);
  delay(10);
  mySerial.write(prs2);
  delay(10);
  mySerial.write(prs3);
  delay(10);
  mySerial.write(prs4);
  delay(10);
  mySerial.write(torque);
}

我可以看到数据损坏也发生在android ...我会拉我的头发!!!

09-16 14:06:51.364: I/DeviceActivity(29651): *** CASE *** Received: #S, 2 bytes
09-16 14:06:51.404: I/DeviceActivity(29651): *** CASE *** Received: 1050, 4 bytes
09-16 14:06:51.404: I/DeviceActivity(29651): *** CASE *** Received: Pa05, 4 bytes
09-16 14:06:51.404: I/DeviceActivity(29651): *** CASE *** Received: Pb, 2 bytes
09-16 14:06:51.404: I/DeviceActivity(29651): *** CASE *** Received: 09, 2 bytes
09-16 14:06:51.424: I/DeviceActivity(29651): *** CASE *** Received: Pc10, 4 bytes
09-16 14:06:51.444: I/DeviceActivity(29651): *** CASE *** Received: Pd01, 4 bytes
09-16 14:06:51.454: I/DeviceActivity(29651): *** CASE *** Received: T0, 2 bytes
09-16 14:06:51.454: I/DeviceActivity(29651): *** CASE *** Received: 13, 2 bytes
09-16 14:06:51.454: I/DeviceActivity(29651): *** subString *** from: #SPa05Pb05Pb09Pc10Pd011313

有时会获得克隆数据......

09-19 10:29:58.184: I/DeviceActivity(9277): *** Received ***
09-19 10:29:58.184: I/DeviceActivity(9277): *** CASE *** ", 1 bytes
09-19 10:29:58.184: I/DeviceActivity(9277): *** Started ***
09-19 10:29:58.184: I/DeviceActivity(9277): *** Finished ***
09-19 10:29:58.184: I/DeviceActivity(9277): *** Received ***
09-19 10:29:58.184: I/DeviceActivity(9277): *** CASE *** "code": ", 9 bytes
09-19 10:29:58.194: I/DeviceActivity(9277): *** Started ***
09-19 10:29:58.194: I/DeviceActivity(9277): *** Finished ***
09-19 10:29:58.194: I/DeviceActivity(9277): *** Received ***
09-19 10:29:58.194: I/DeviceActivity(9277): *** CASE *** "code": " , 10 bytes
09-19 10:29:58.194: I/DeviceActivity(9277): *** Started ***
09-19 10:29:58.194: I/DeviceActivity(9277): *** Finished ***
09-19 10:29:58.194: I/DeviceActivity(9277): *** Received ***
09-19 10:29:58.194: I/DeviceActivity(9277): *** CASE *** "code": ", 9 bytes
09-19 10:29:58.194: I/DeviceActivity(9277): *** Started ***
09-19 10:29:58.204: I/DeviceActivity(9277): *** Finished ***
09-19 10:29:58.214: I/DeviceActivity(9277): *** Received ***
09-19 10:29:58.214: I/DeviceActivity(9277): *** CASE *** DZ"}, 4 bytes
09-19 10:29:58.214: I/DeviceActivity(9277): *** Started ***
09-19 10:29:58.214: I/DeviceActivity(9277): *** Parsing JSON ***""code": ""code": " "code": "DZ"}

2 个答案:

答案 0 :(得分:1)

你可以像这样从Arduino发送它作为JSON对象

{
    "speedStart":10,
    "speedEnd":10,
    ...
}

您可以在arduino中创建一些帮助方法来构建JSON:

Serial.print("{");
printIntParameter("speedStart", 10);
Serial.print(",");
printIntParameter("speedEnd", 10);
Serial.print("}");

void printIntParameter(char* name, int value) {
    Serial.print("\""); Serial.print(name); Serial.print("\"");
    Serial.print(":");
    Serial.print(value);
}

在Android中,当你获得{并在}停止然后使用https://code.google.com/p/google-gson/

将此JSON从String解析为对象时开始缓冲JSON

答案 1 :(得分:1)

您必须选择是否要高效或易于阅读。

我的意思是如果你必须发送485 Nm的扭矩,你可以发送

  1. 二进制表示(0x01,0xE5,即2个字节)
  2. Ascii表示('4','8','5',即3个字节)
  3. 第一种方法更有效;第二个更容易看到,例如,串行监视器。

    在这两种情况下,我建议您使用固定长度的消息。使用特殊字符通知微控制器传输开始,然后按顺序发送所有数据(并且每个令牌必须是固定的长度)。因此,微控制器将知道消息何时结束。

    对于“固定长度令牌”,我的意思是如果你发送一个字符串表示,你必须在左边插入'0'(填充),否则你将失去其他元素的位置。

    在二进制表示中,您会遇到问题,因为“特殊字符”也可能位于数据包的中间;所以你必须处理它。

    只是带有字符串表示的数据包示例:

    Speed - 270 rpm
    Pressure 5 bar 9 bar 10 bar 1 bar
    Torque - 13 Nm
    Packet: #S0270Pa05Pb09Pc10Pd01T013
    

    这里我使用#作为“数据包开始”字符,并添加了S,Pa,Pb,Pc,Pd和T作为附加字符,只是为了在串行监视器上看到它们(它们没用)。更重要的是:我使用4个字符速度(0-3500表示最多有4个字符),每个压力2个字符(因为最高值为10,所以2位数)和3个扭矩。 / p>

    只有一个个人建议:避免使用像json或xml这样复杂的东西或其他类似的东西;微控制器不是PC,它们的资源有限;如果你可以做些什么来让他们用固定的数据(例如整数而不是浮点数)来推卸它们,那么它们的效果会好得多。

    顺便说一下:当然你可以得到一条拆分信息。它在网络或发送数据时很常见。但是..如果你有一个固定长度的字符串,你只需要等待正确的字符数 - 在我给你看的例子中有26个;如果你没有收到它们,你只需稍等一点......