ardino和android串行通信后字节到int的转换

Byte to int conversion after serial communication between ardino and android

我正在我的 Android phone 和我的 Arduino 之间传输 0 到 10000 之间的正整数。 由于串行发送字节数组,我必须将发送的字节数组转换回整数。

但我尝试的所有方法都抛出

java.nio.BufferUnderflowException

或returns一个错误的值(我的Arduino发送150,我得到-106)!

我用 ByteBuffer 试过了:

@Override
public void onNewData(final byte[] data) {
   runOnUiThread(new Runnable() {
        @Override
        public void run() {
            editText.append("Read: " + ByteBuffer.allocate(4).put(data).getInt());
        }
    });
}

并且我尝试了较小的值 255(我之前提到的 150):

@Override
public void onNewData(final byte[] data) {
   runOnUiThread(new Runnable() {
        @Override
        public void run() {
            editText.append("Read: " + new Byte(data[0]).intValue());
        }
    });
}

Arduino 发送以下内容:

uint16_t iSend = 150;

void loop() {
  Serial.write(iSend);

  delay(1000);
}

我的 android phone 内容如下:

D/SerialInputOutputManager: Read data len=1
D/UsbRequestJNI: init
D/UsbRequestJNI: close
D/UsbRequestJNI: init
I/System.out: 0x00000000 96

有没有人解决过类似的问题? 提前致谢!

Serial.write(iSend); - 根据 documentation 此方法接受一个字节,因此调用此方法只会发送一个字节。很明显,这是从数据数组的长度发生的。 (data len=1).

然后您尝试从字节缓冲区读取一个整数,这需要 4 个字节,但 data 输入只会提供一个字节。

简而言之,您输入的唯一有效调用是 ByteBuffer.wrap(data).get()

最后关于(my Arduino sends 150, I get -106)!,这个数字在arduino上存储为uint16_t。这是一个无符号数,而 java 只处理有符号数。这意味着该字节在到达 java 端时被解释为带符号字节。 0x96 在解释为有符号字节时是 -106

要解释 java 中的无符号字节,您可以使用以下代码将其强制转换为短整数:

short readAsUnsigned(byte b) {
    short tmp = (short) b;
    if (tmp < 0) {
        tmp += 256;
    }
    return tmp;
}

打印 readAsUnsigned(ByteBuffer.wrap(data).get()) 然后应该打印 150

(my Arduino sends 150, I get -106)!

这是预期的行为。 Java 不支持无符号字节。 -106 是一个有符号字节,对应于无符号的 150。正常的追索是这样的:

byte b = 0x96; // b has decimal value -106
int x = b & 0xff; // x now has int value 150.

现在您可以将 x 操作为正值。