RPi 3 Android Things UART 双向通信使应用程序崩溃
RPi 3 Android Things UART bidirectional communication crashes app
我正在通过 UART 在 RPi 3 运行 Android 之间进行通信 和一个 Arduino.
按下 RPi 应用程序上的按钮后,一条命令将发送到 Arduino。那里没有问题。 Arduino 每 2 秒发送一个信息包。
在我按下一个将数据发送到 Arduino 的按钮之前,这一切都完美无缺。 Arduino 收到按钮命令,但 Android 应用程序崩溃。我什至可以在应用程序崩溃之前按两次按钮,并且 Arduino 成功接收到两次按下。问题似乎是 Arduino 在按下按钮后发送下一个数据包。
如果我断开 RPi UART RX 按钮不会导致崩溃。换句话说,只要没有传入数据,应用程序就可以正常工作,反之亦然。我无法理解错误:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: za.co.leafbox.boxcontrol, PID: 8817
java.lang.NumberFormatException: For input string: "pump"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)
at sun.misc.FloatingDecimal.parseFloat(FloatingDecimal.java:122)
at java.lang.Float.parseFloat(Float.java:452)
at za.co.leafbox.boxcontrol.MainActivity.readUartBuffer(MainActivity.java:284)
at za.co.leafbox.boxcontrol.MainActivity.onUartDeviceDataAvailable(MainActivity.java:234)
at com.google.android.things.pio.UartDeviceImpl$UartDeviceCallbackDispatch.dispatchInterruptEvent(UartDeviceImpl.java:250)
at com.google.android.things.pio.CallbackDispatch.onFileDescriptorEvents(CallbackDispatch.java:149)
at android.os.MessageQueue.dispatchEvents(MessageQueue.java:284)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:325)
at android.os.Looper.loop(Looper.java:142)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
收到的数据示例:
I/MainActivity: [45, 49, 46, 48, 48, 32, 49, 56, 46, 53, 48, 32, 54, 53, 46, 49, 48, 32, 45, 48, 46, 48, 56, 32, 48, 46, 48, 48, 32, 49, 54, 46, 51, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
OnClick
函数:
public void pumpToggle(View view){
try{
if (((ToggleButton) view).isChecked()) {
byte[] buffer = {'g', 'g', '\n'};
writeUartData(aNano, buffer);
}
else{
byte[] buffer = {'g', 's', '\n'};
writeUartData(aNano, buffer);
}
} catch (IOException e) {
Log.e(TAG, "Data not Sent", e);
}
}
UART回调:
private UartDeviceCallback mUartCallback = new UartDeviceCallback() {
@Override
public boolean onUartDeviceDataAvailable(UartDevice uart) {
// Read available data from the UART device
Log.i(TAG, "onUartDeviceDataAvailable");
try {
readUartBuffer(uart);
} catch (IOException e) {
Log.w(TAG, "Unable to access UART device", e);
}
// Continue listening for more interrupts
return true;
}
private void readUartBuffer(UartDevice uart) throws IOException {
// Maximum amount of data to read at one time
Log.i(TAG, "readUartBuffer");
final int maxCount = 64;
byte[] buffer = new byte[maxCount];
byte[] convertBuf = new byte[20];
boolean dataCompleteFlag = false;
uart.read(buffer, maxCount);
if (!dataCompleteFlag) {
for (int i = 0; i < maxCount; i++) {
if (buffer[i] == 36) {
dataCompleteFlag = true;
measureCount++;
dataCount = 0;
}
else if(dataCount > maxCount) {
dataCount = 0;
}
else if(buffer[i] != 0) {
finalDataBuffer[dataCount] = buffer[i];
dataCount++;
}
}
}
if (dataCompleteFlag) {
Log.i(TAG, Arrays.toString(finalDataBuffer));
int index = 0;
int offSet;
while (index < maxCount && finalDataBuffer[index] != 32) {
convertBuf[index] = finalDataBuffer[index];
index++;
}
index++;
offSet = index;
tankLevelString = new String(convertBuf);
Float tankFloat = parseFloat(tankLevelString);
tankLevelString += "cm";
while (index < maxCount && finalDataBuffer[index] != 32) {
convertBuf[index - offSet] = finalDataBuffer[index];
index++;
}
index++;
offSet = index;
airTempString = new String(convertBuf);
airTempString += "\u00b0C";
while (index < maxCount && finalDataBuffer[index] != 32) {
convertBuf[index - offSet] = finalDataBuffer[index];
index++;
}
index++;
offSet = index;
humidityString = new String(convertBuf);
humidityString += "%";
while (index < maxCount && finalDataBuffer[index] != 32) {
convertBuf[index - offSet] = finalDataBuffer[index];
index++;
}
index++;
offSet = index;
ecString = new String(convertBuf);
while (index < maxCount && finalDataBuffer[index] != 32) {
convertBuf[index - offSet] = finalDataBuffer[index];
index++;
}
index++;
offSet = index;
phString = new String(convertBuf);
while (index < maxCount && finalDataBuffer[index] != 0) {
convertBuf[index - offSet] = finalDataBuffer[index];
index++;
}
waterTempString = new String(convertBuf);
TextView airTemp = findViewById(R.id.airTemp);
airTemp.setText(airTempString);
TextView humidity = findViewById(R.id.humidity);
humidity.setText(humidityString);
TextView tankLevel1 = findViewById(R.id.tankLevel1);
tankLevel1.setText(tankLevelString);
TextView ec = findViewById(R.id.ec);
ec.setText(ecString);
TextView ph = findViewById(R.id.ph);
ph.setText(phString);
TextView wt = findViewById(R.id.waterTemp);
wt.setText(waterTempString);
}
}
@Override
public void onUartDeviceError(UartDevice uart, int error) {
Log.w(TAG, uart + ": Error event " + error);
}
};
parseFloat (tankLevelString) is the line you get the NumberFormatException 上。显然,tankLevelString
,也就是"pump",是无法解析成float
的。我建议调查是什么原因造成的。
我正在通过 UART 在 RPi 3 运行 Android 之间进行通信 和一个 Arduino.
按下 RPi 应用程序上的按钮后,一条命令将发送到 Arduino。那里没有问题。 Arduino 每 2 秒发送一个信息包。
在我按下一个将数据发送到 Arduino 的按钮之前,这一切都完美无缺。 Arduino 收到按钮命令,但 Android 应用程序崩溃。我什至可以在应用程序崩溃之前按两次按钮,并且 Arduino 成功接收到两次按下。问题似乎是 Arduino 在按下按钮后发送下一个数据包。
如果我断开 RPi UART RX 按钮不会导致崩溃。换句话说,只要没有传入数据,应用程序就可以正常工作,反之亦然。我无法理解错误:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: za.co.leafbox.boxcontrol, PID: 8817
java.lang.NumberFormatException: For input string: "pump"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)
at sun.misc.FloatingDecimal.parseFloat(FloatingDecimal.java:122)
at java.lang.Float.parseFloat(Float.java:452)
at za.co.leafbox.boxcontrol.MainActivity.readUartBuffer(MainActivity.java:284)
at za.co.leafbox.boxcontrol.MainActivity.onUartDeviceDataAvailable(MainActivity.java:234)
at com.google.android.things.pio.UartDeviceImpl$UartDeviceCallbackDispatch.dispatchInterruptEvent(UartDeviceImpl.java:250)
at com.google.android.things.pio.CallbackDispatch.onFileDescriptorEvents(CallbackDispatch.java:149)
at android.os.MessageQueue.dispatchEvents(MessageQueue.java:284)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:325)
at android.os.Looper.loop(Looper.java:142)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
收到的数据示例:
I/MainActivity: [45, 49, 46, 48, 48, 32, 49, 56, 46, 53, 48, 32, 54, 53, 46, 49, 48, 32, 45, 48, 46, 48, 56, 32, 48, 46, 48, 48, 32, 49, 54, 46, 51, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
OnClick
函数:
public void pumpToggle(View view){
try{
if (((ToggleButton) view).isChecked()) {
byte[] buffer = {'g', 'g', '\n'};
writeUartData(aNano, buffer);
}
else{
byte[] buffer = {'g', 's', '\n'};
writeUartData(aNano, buffer);
}
} catch (IOException e) {
Log.e(TAG, "Data not Sent", e);
}
}
UART回调:
private UartDeviceCallback mUartCallback = new UartDeviceCallback() {
@Override
public boolean onUartDeviceDataAvailable(UartDevice uart) {
// Read available data from the UART device
Log.i(TAG, "onUartDeviceDataAvailable");
try {
readUartBuffer(uart);
} catch (IOException e) {
Log.w(TAG, "Unable to access UART device", e);
}
// Continue listening for more interrupts
return true;
}
private void readUartBuffer(UartDevice uart) throws IOException {
// Maximum amount of data to read at one time
Log.i(TAG, "readUartBuffer");
final int maxCount = 64;
byte[] buffer = new byte[maxCount];
byte[] convertBuf = new byte[20];
boolean dataCompleteFlag = false;
uart.read(buffer, maxCount);
if (!dataCompleteFlag) {
for (int i = 0; i < maxCount; i++) {
if (buffer[i] == 36) {
dataCompleteFlag = true;
measureCount++;
dataCount = 0;
}
else if(dataCount > maxCount) {
dataCount = 0;
}
else if(buffer[i] != 0) {
finalDataBuffer[dataCount] = buffer[i];
dataCount++;
}
}
}
if (dataCompleteFlag) {
Log.i(TAG, Arrays.toString(finalDataBuffer));
int index = 0;
int offSet;
while (index < maxCount && finalDataBuffer[index] != 32) {
convertBuf[index] = finalDataBuffer[index];
index++;
}
index++;
offSet = index;
tankLevelString = new String(convertBuf);
Float tankFloat = parseFloat(tankLevelString);
tankLevelString += "cm";
while (index < maxCount && finalDataBuffer[index] != 32) {
convertBuf[index - offSet] = finalDataBuffer[index];
index++;
}
index++;
offSet = index;
airTempString = new String(convertBuf);
airTempString += "\u00b0C";
while (index < maxCount && finalDataBuffer[index] != 32) {
convertBuf[index - offSet] = finalDataBuffer[index];
index++;
}
index++;
offSet = index;
humidityString = new String(convertBuf);
humidityString += "%";
while (index < maxCount && finalDataBuffer[index] != 32) {
convertBuf[index - offSet] = finalDataBuffer[index];
index++;
}
index++;
offSet = index;
ecString = new String(convertBuf);
while (index < maxCount && finalDataBuffer[index] != 32) {
convertBuf[index - offSet] = finalDataBuffer[index];
index++;
}
index++;
offSet = index;
phString = new String(convertBuf);
while (index < maxCount && finalDataBuffer[index] != 0) {
convertBuf[index - offSet] = finalDataBuffer[index];
index++;
}
waterTempString = new String(convertBuf);
TextView airTemp = findViewById(R.id.airTemp);
airTemp.setText(airTempString);
TextView humidity = findViewById(R.id.humidity);
humidity.setText(humidityString);
TextView tankLevel1 = findViewById(R.id.tankLevel1);
tankLevel1.setText(tankLevelString);
TextView ec = findViewById(R.id.ec);
ec.setText(ecString);
TextView ph = findViewById(R.id.ph);
ph.setText(phString);
TextView wt = findViewById(R.id.waterTemp);
wt.setText(waterTempString);
}
}
@Override
public void onUartDeviceError(UartDevice uart, int error) {
Log.w(TAG, uart + ": Error event " + error);
}
};
parseFloat (tankLevelString) is the line you get the NumberFormatException 上。显然,tankLevelString
,也就是"pump",是无法解析成float
的。我建议调查是什么原因造成的。