使用串行端口将Arduino中的整数发送到Java程序,并将两字节数组转换为Java中的整数

时间:2011-12-02 15:48:24

标签: java arduino

我想将Arduino中的整数值发送到Java应用程序。为此,我使用的是串口。在Arduino的处理程序中,我将以下内容打印到串口:

Serial.print(accel, DEC)

accel是一个签名的int。在我的Java代码中,我正在实现SerialPortEventListener,我正在从输入流输入中读取一个字节数组。

public synchronized void serialEvent(SerialPortEvent oEvent) {
    if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
        try {
            int available = input.available();
            byte[] chunk = new byte[available];
            input.read(chunk);
            System.out.println (new String(chunk));
        } catch (Exception e) {
            System.err.println(e.toString());
        }
    }
}

我需要将这个字节数组转换为整数,但我不知道如何做到这一点。 Arduino教程 Lesson 4 - Serial communication and playing with data 表示Arduino以两个字节(16位)存储签名的整数。我已经尝试将两个字节的数据读入一个数组块,然后使用以下代码将这两个字节解码为整数。

public synchronized void serialEvent(SerialPortEvent oEvent) {
    if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
        try {
            int available = input.available();
            int n = 2;
            byte[] chunk = new byte[n];
            input.read(chunk);
            int value = 0;
            value |= chunk[0] & 0xFF;
            value <<= 8;
            value |= chunk[1] & 0xFF;
            System.out.println(value);
         } catch (Exception e) {
             System.err.println(e.toString());
         }
    } 
}

这应打印出在-512和-516之间波动的整数流,但事实并非如此。代码打印出以下内容。

2949173
3211317
851978
2949173
3211317
851978
2949173
3211319

如何解码从Arduino通过串口到整数的字节?

4 个答案:

答案 0 :(得分:0)

您可以使用ByteBuffer将字节转换为int,您的代码将如下所示:

ByteBuffer bb = ByteBuffer.wrap(chunk);
System.out.println(bb.getInt());

答案 1 :(得分:0)

编辑:我应该已经识别出ascii数字: - )

为什么不:制定面向行的协议;使用java BufferedReader和.readLine()。 使用Integer.valueOf()解析字符串。请注意,换行符用作 框架角色。

大多数GPS GPS设备和各种非常重要的设备如何使用。 以任何方式都不是最佳的,但是你去......

答案 2 :(得分:0)

事实证明,Arduino上的Serial.print()函数将值转换为字符串并将字符串发送到串行端口,这就是我的位移不起作用的原因。一种解决方案是将我的java代码中的值作为字符串收集,然后将字符串转换为int。

但是,要避免将值从字符串转换为int的步骤,可以使用serial.write()函数将int发送到串行端口。为此,在Arduino草图中,定义int和相同大小的字节数组的并集。然后创建union的实例,设置整数,并将Serial.write()创建为匹配的字节数组。收集Java程序中的字节数组并进行一点移位以获得整数。

我的Arduino草图编码如下:

union{
  int i;
  byte b[2];
}u;
u.i = accel;
Serial.write(u.b, 2);

我读取字节数组并将其转换为int的java代码如下所示:

int n = 2;
byte[] chunk = new byte[n];
input.read(chunk);
short value = 0;
// get 2 bytes, unsigned 0..255
int low = chunk[0] & 0xff;
int high = chunk[1] & 0xff;
value =  (short) (high << 8 | low) ;
System.out.println(value);

我仍在寻找一种从Arduino到java代码中获取浮点数或双精度的方法。我知道我可以通过将union中的int替换为double或float,设置double或float,以及Serial.write()匹配的字节数组来编写float或double。我的问题来自Java方面。一旦我收集了字节数组,我就没有找到一种方法来正确地将数据移位到float或double。这里有什么帮助吗?

答案 3 :(得分:0)

我的问题是相似的。我使用Arduino Serial.write发送了一组已知的int值(2个字节/ int)。 Arduino串行监视器正确解释了这些值。但是,java程序弄错了所有数字(零除外)。显然字节顺序是相反的。我希望字节顺序也是arduino输出的其他数据类型的问题。 jSerialComm用于读取串行端口。这是Java代码:

// declarations
byte[] byter = new byte[16];
ByteBuffer bufr = ByteBuffer.wrap(byter);
short[] shortr = new short[8];

// code
comPort.readBytes(byter, 16);
for(int i=0; i<8; i++){
    shortr[i] = Short.reverseBytes(bufr.getShort(2*i));
}