在 java 中从串行端口读取时获取垃圾值

Getting Garbage value while reading from serial port in java

我正在使用 jSerialComm 包从串口读取数据。我正在获取以下数据

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

以下是我的代码。

public static void main(String[] args) {
    SerialPort serialPort = SerialPort.getCommPort("/dev/ttyUSB0");
    if(serialPort.openPort())
    {
        System.out.println("Port Opened Successfully...");
    }
    else
    {
        System.out.println("Unable to open port....");
        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("Read "+numRead+ " bytes." + readBuffer);
                System.out.println(data);
            }
        }
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
    serialPort.closePort();
    System.out.println("done...");
}

你没有解释协议,但我建议查一下。大概这些是控制字符或像评论一样暗示二进制数据。您从没有编码的字节缓冲区创建一个字符串,因此这也取决于您的环境/JVM 的默认编码。

尝试按照您的项目使用的协议中指定的方式处理第一个和最后两个字节。它也可能与 jSerialComm 不删除串行信号有关,例如握手、EOT 等。

如果您要对协议进行逆向工程,也可以尝试使用其他库(例如 RxTx)来查看字节是否保持不变。

要安全地检查字节,例如使用 BigInteger 来打印出十六进制字符串:

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

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

我建议使用作者示例中的 snippet,它对我来说效果很好:

// Get a new instance of SerialPort by opening a port.
SerialPort port = SerialPort.open("COM2");

// 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 :为清楚起见从原始代码中删除

使用此代码块,它将 运行 完美;

    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);

        }
    });