在使用Java从串口读取数据时获得了垃圾值

huangapple go评论70阅读模式
英文:

Getting Garbage value while reading from serial port in java

问题

我正在使用`jSerialComm`包从串口读取数据我得到了以下数据

[![enter image description here][1]][1]

总共收到了22个字节但我也收到了这三个垃圾字节可读的数据是正确的但这些垃圾字符是怎么回事呢

以下是我的代码

```java
public static void main(String[] args) {
    SerialPort serialPort = SerialPort.getCommPort("/dev/ttyUSB0");
    if(serialPort.openPort())
    {
        System.out.println("端口成功打开...");
    }
    else
    {
        System.out.println("无法打开端口....");
        return;
    }
    serialPort.setComPortParameters(1200, 8, 1, 0);
    try
    {
        while(true)
        {
            while(serialPort.bytesAvailable() != 0)
            {
                Thread.sleep(1000);
                byte[] readBuffer = new byte[serialPort.bytesAvailable()];
                int numRead = serialPort.readBytes(readBuffer, readBuffer.length);
                String data = new String(readBuffer);
                System.out.println("读取了"+numRead+ "字节。" + readBuffer);
                System.out.println(data);
            }
        }
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
    serialPort.closePort();
    System.out.println("完成...");
}

<details>
<summary>英文:</summary>
I am reading data from serialport using `jSerialComm` package. I am getting following data
[![enter image description here][1]][1]
A total of 22 bytes are being received and I am getting these three garbage bytes too. The readable data is correct but what these garbage characters are happening?
Following is my code.
```java
public static void main(String[] args) {
SerialPort serialPort = SerialPort.getCommPort(&quot;/dev/ttyUSB0&quot;);
if(serialPort.openPort())
{
System.out.println(&quot;Port Opened Successfully...&quot;);
}
else
{
System.out.println(&quot;Unable to open port....&quot;);
return;
}
serialPort.setComPortParameters(1200, 8, 1, 0);
try
{
while(true)
{
while(serialPort.bytesAvailable() != 0)
{
Thread.sleep(1000);
byte[] readBuffer = new byte[serialPort.bytesAvailable()];
int numRead = serialPort.readBytes(readBuffer, readBuffer.length);
String data = new String(readBuffer);
System.out.println(&quot;Read &quot;+numRead+ &quot; bytes.&quot; + readBuffer);
System.out.println(data);
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
serialPort.closePort();
System.out.println(&quot;done...&quot;);
}

答案1

得分: 1

SerialPort.readBytes似乎不是线程安全的,因此在字符接收过程中调用时会产生“垃圾”数据。

我建议使用作者示例中的代码片段,这对我而言效果很好:

// 通过打开端口获取SerialPort的新实例。
SerialPort port = SerialPort.open("COM2");
// 配置连接
port.setTimeout(100);
port.setConfig(BaudRate.B115200, Parity.NONE, StopBits.ONE, DataBits.B8);
// 你可以选择使用Java NIO通道或经典的输入/输出流来读取和写入数据。
//DEL SerialChannel channel = port.getChannel();
InputStream istream = port.getInputStream();
// 使用流读取一些数据
byte[] byteBuffer = new byte[4096];
// 如果没有可用字节,将在100毫秒后超时,返回0。
int n = istream.read(byteBuffer);
// *** 使用n个字节的byteBuffer ***
//DEL ...
port.close();

//DEL:为了清晰起见,从原始代码中删除

英文:

SerialPort.readBytes seems to be not thread safe, thus yielding "garbage" when called during character reception.

I suggest to use the snippet from the author's example which worked fine for me:

// Get a new instance of SerialPort by opening a port.
SerialPort port = SerialPort.open(&quot;COM2&quot;);
// Configure the connection
port.setTimeout(100);
port.setConfig(BaudRate.B115200, Parity.NONE, StopBits.ONE, DataBits.B8);
// You have the choice, you can either use the Java NIO channels
// or classic Input/Ouput streams to read and write data.
//DEL SerialChannel channel = port.getChannel();
InputStream istream = port.getInputStream();
// Read some data using a stream
byte[] byteBuffer = new byte[4096];
// Will timeout after 100ms, returning 0 if no bytes were available.
int n = istream.read(byteBuffer);
// *** Use n bytes of byteBuffer ***
//DEL ...
port.close();

//DEL : removed from the original code for clarity

答案2

得分: 0

你没有解释这个协议,但我建议你查阅一下。很可能这些是控制字符,或者像评论中提到的是二进制数据。你从字节缓冲区创建了一个字符串,但没有指定编码,所以这也取决于你的环境/ JVM 的默认编码。

尝试根据你的项目使用的协议规范来处理前两个字节和最后两个字节。这也可能与 jSerialComm 没有移除串行信号有关,例如握手、EOT 等。

如果你是在逆向工程协议,也可以尝试使用另一个库,比如 RxTx,看看字节是否保持不变。

为了安全地检查这些字节,你可以使用 BigInteger 将其打印成十六进制字符串,例如:

BigInteger bigInteger = new BigInteger(1, bytes);
System.out.printf("%0" + (bytes.length << 1) + "x", bigInteger);
英文:

You did not explain the protocol but I suggest to look it up. Presumably these are control characters or like a comment suggests binary data. You create a String from a byte buffer without an encoding so this also depends on your environment/ JVM's default encoding.

Try treating the first and the last two bytes as specified in the protocol in use for your project. It might also be related to jSerialComm not removing serial signalling, e.g. handshake, EOT and such.

If you're reverse-engineering the protocol instead maybe also try another library like RxTx to see if the bytes stay the same.

To inspect the bytes safely use for example BigInteger to print out a Hex-String instead:

BigInteger bigInteger = new BigInteger(1, bytes);
System.out.printf(&quot;%0&quot; + (bytes.length &lt;&lt; 1) + &quot;x&quot;, bigInteger);

答案3

得分: 0

使用这段代码块,它将完美运行:

serialPort.addDataListener(new SerialPortDataListener() {
    @Override
    public int getListeningEvents() {
        return SerialPort.LISTENING_EVENT_DATA_RECEIVED;
    }

    @Override
    public void serialEvent(SerialPortEvent serialPortEvent) {
        if (serialPortEvent.getEventType() != SerialPort.LISTENING_EVENT_DATA_RECEIVED) {
            return;
        }
        byte[] newData = serialPortEvent.getReceivedData();
        String data = new String(newData);
        System.out.println(data);
    }
});
英文:

Use this code block and it will run perfectly;

    serialPort.addDataListener(new SerialPortDataListener() {
@Override
public int getListeningEvents() {
return SerialPort.LISTENING_EVENT_DATA_RECEIVED;
}
@Override
public void serialEvent(SerialPortEvent serialPortEvent) {
if (serialPortEvent.getEventType() != SerialPort.LISTENING_EVENT_DATA_RECEIVED) {
return;
}
byte[] newData = serialPortEvent.getReceivedData();
String data = new String(newData);
System.out.println(data);
}
});

huangapple
  • 本文由 发表于 2020年7月26日 09:21:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/63095197.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定