串行中的字符串数据无法解析为JSON

时间:2018-03-08 05:59:33

标签: android json arduino serial-port

我正在构建一个可以在车辆ECU,Arduino和Android设备之间进行通信的设备。最终目标是从汽车获取信息到用户的手机。

我目前有以下Arduino代码,它通过OBD-II端口收集车辆数据,并通过串口发送为JSON:

#include <Wire.h>
#include <OBD.h>

COBDI2C obd;

char vin[64];
int distance;
int velocity;
int runtime;

String json;

void setup() {
  Serial.begin(9600);
  obd.begin();
  while(!obd.init());
}

void loop() {
  obd.getVIN(vin, sizeof(vin));
  delay(100);
  obd.readPID(PID_DISTANCE, distance);
  delay(100);
  obd.readPID(PID_SPEED, velocity);
  delay(100);
  obd.readPID(PID_RUNTIME, runtime);
  delay(100);

  json = "{\"vin\":\"";
  json.concat(vin);
  json.concat("\",\"distance\":\"");
  json.concat(distance);
  json.concat("\",\"speed\":\"");
  json.concat(velocity);
  json.concat("\",\"runtime\":\"");
  json.concat(runtime);
  json.concat("\"}");

  Serial.print(json);
  delay(5000);
}

这将通过USB连接将一个字符串(例如"{\"vin\":\"3VWJM71K89M02\",\"distance\": \"19478\",\"speed\":\"0\",\"runtime\":\"216\"}")打印到Android设备。当USB活动发生时,我有一个在Android设备上调用的方法:

public void onReceivedData(byte[] result) {
     String dataStr;
     try {
         dataStr = new String(result, "UTF-8");
         dataStr = dataStr.replaceAll("[\\n\\r\\s]+", "");
     } catch (UnsupportedEncodingException e) {
         e.printStackTrace();
     }
     try {
         driveData = new JSONObject(dataStr);
         updateVehicle(driveData);
     } catch(JSONException e) {
         e.printStackTrace();
     }
}

由于某种原因,生成的字节数组可以转换为没有错误的字符串,但奇怪地填充了随机换行符和空格,这就是为什么我使用replaceAll()来删除它们。当我尝试从字符串创建JSONObject时(使用org.json库),我收到错误。但是,当我将原始字符串附加到textView时,我得到的东西似乎是非常有效的JSON:

{"vin":"3VWJM71K89M02","distance":"19478","speed":"0","runtime":"216"}

接下来,我尝试使用之前在Arduino上构建的确切字符串构建JSONObject,例如:

 try {
     driveData = new JSONObject("{\"vin\":\"3VWJM71K89M02\",\"distance\": \"19478\",\"speed\":\"0\",\"runtime\":\"216\"}");
     updateVehicle(driveData);
 } catch(JSONException e) {
     e.printStackTrace();
 } 

这让我没有任何错误。那么我错误的是,通过USB发送的原始数据不如到达的实际数据有效吗?

更新 根据要求,我有一些来自Android设备的错误代码。不幸的是,它似乎是一个连锁反应,所以我提供了一些第一个:

org.json.JSONException: Unterminated string at character 4 of {"vi
org.json.JSONException: End of character input at character 0 of
org.json.JSONException: Value n" of typejava.lang.String cannot be converted to JSONObject
org.json.JSONException: End of character input at character 0 of
org.json.JSONException: Unterminated string at character 7 of "3VMJM7
org.json.JSONException: ...

1 个答案:

答案 0 :(得分:0)

正如评论中提到的gre_gor,接收USB数据的事件并未在一次调用中从Arduino捕获整个消息。我发现如果你保留所有USB数据的运行字符串并检查每个调用的JSON语法字符串,你最终会得到一个有效的JSON对象。然后只需重置字符串并继续听。 所以,我的新代码看起来像: public String usbStr =&#34;&#34 ;; public JSONObject driveData; ... public void onReceivedData(byte [] result){      String dataStr;      尝试{          dataStr = new String(结果,&#34; UTF-8&#34;);          dataStr = dataStr.replaceAll(&#34; [\\ n \\ r \\ s] +&#34;,&#34;&#34;);          usbStr = usbStr.concat(dataStr);      } catch(UnsupportedEncodingException e){          e.printStackTrace();      }      尝试{          driveData = new JSONObject(dataStr);          usbStr =&#34;&#34 ;;          updateVehicle(driveData);      } catch(JSONException e){          e.printStackTrace();      } }