使用jSerialComm的Java串口通信对特定设备出现数据损坏问题
Java串口通信(jSerialComm)与特定设备通信时数据损坏问题
设备配置参数
Port: COM3 BaudRate: 2400 Parity: EVEN Databits: 7 Stopbits: 1
问题背景
- Java程序基于jSerialComm库实现串口通信,与多数设备通信正常,但和某特定设备通信时接收数据损坏
- 同设备用C#原生串口实现通信时,可正常接收数据
- 已尝试调整Java程序的波特率和奇偶校验设置,问题未解决
Java程序代码与日志
连接设备代码
SerialPort[] serialPorts = SerialPort.getCommPorts(); for (SerialPort port : serialPorts) { if (DEVICE_PORT.equals(port.getSystemPortName())) { bolFound = true; serialPort = port; try { log.info("Opening port '" + DEVICE_PORT + "'..."); log.info("Connecting to device '" + DEVICE_NAME + "'..."); serialPort.setComPortParameters(DEVICE_RATE, DEVICE_DATABITS, DEVICE_STOPBITS, DEVICE_PARITY); serialPort.addDataListener(this); serialPort.openPort(); ...........
数据监听代码
@Override public int getListeningEvents() { return SerialPort.LISTENING_EVENT_DATA_AVAILABLE; } @Override public void serialEvent(SerialPortEvent event) { switch (event.getEventType()) { case SerialPort.LISTENING_EVENT_DATA_AVAILABLE: readComm(); break; default: log.info("XXX default"); break; } } public void readComm() { log.info(AppConfig.getInstance().getProperty(AppConfig.KEY_TEST_PORT, String.class) + " Reading Comm..."); byte[] readBuffer = new byte[1024]; try { inputStream = serialPort.getInputStream(); int len = 0; while ((len = inputStream.read(readBuffer)) != -1) { log.info("Real Time Response:" + new String(readBuffer, 0, len)); value += new String(readBuffer, 0, len); break; } log.info("value:" + value); if (isDataReady) { // process data value = ""; //reset data } } catch (IOException e) { intNumberOfFailure++; } }
Java程序日志
2023-11-09 10:38:58.165 INFO 21320 [Thread-117 thread] h.h.c.v.l.BaseListener : Trying to init Test Listener (COM5)... 2023-11-09 10:38:58.350 INFO 21320 [Thread-117 thread] h.h.c.v.l.BaseListener : Opening port 'COM5'... 2023-11-09 10:38:58.350 INFO 21320 [Thread-117 thread] h.h.c.v.l.BaseListener : Connecting to device 'Testing'... 2023-11-09 10:38:58.350 INFO 21320 [Thread-117 thread] h.h.c.v.l.BaseListener : Opening port 'COM5' Success 2023-11-09 10:38:58.350 INFO 21320 [Thread-117 thread] h.h.c.v.l.BaseListener : Connecting to device 'Testing' Success 2023-11-09 10:38:59.211 INFO 21320 [Thread-120 thread] h.h.c.v.l.TestListener : COM5 Reading Comm... 2023-11-09 10:38:59.215 INFO 21320 [Thread-120 thread] h.h.c.v.l.TestListener : Real Time Response:[ 2023-11-09 10:38:59.217 INFO 21320 [Thread-120 thread] h.h.c.v.l.TestListener : value:[ 2023-11-09 10:38:59.219 INFO 21320 [Thread-120 thread] h.h.c.v.l.TestListener : COM5 Reading Comm... 2023-11-09 10:38:59.221 INFO 21320 [Thread-120 thread] h.h.c.v.l.TestListener : Real Time Response:l 2023-11-09 10:38:59.222 INFO 21320 [Thread-120 thread] h.h.c.v.l.TestListener : value:[ l 2023-11-09 10:38:59.225 INFO 21320 [Thread-120 thread] h.h.c.v.l.TestListener : COM5 Reading Comm... 2023-11-09 10:38:59.227 INFO 21320 [Thread-120 thread] h.h.c.v.l.TestListener : Real Time Response:@ 1 2023-11-09 10:38:59.229 INFO 21320 [Thread-120 thread] h.h.c.v.l.TestListener : value:[ l@ 1 2023-11-09 10:39:00.215 INFO 21320 [Thread-120 thread] h.h.c.v.l.TestListener : COM5 Reading Comm... 2023-11-09 10:39:00.215 INFO 21320 [Thread-120 thread] h.h.c.v.l.TestListener : Real Time Response:{=Um% 2023-11-09 10:39:00.226 INFO 21320 [Thread-120 thread] h.h.c.v.l.TestListener : value:[ l@ 1{=Um% 2023-11-09 10:39:00.230 INFO 21320 [Thread-120 thread] h.h.c.v.l.TestListener : COM5 Reading Comm... 2023-11-09 10:39:00.232 INFO 21320 [Thread-120 thread] h.h.c.v.l.TestListener : Real Time Response:l 2023-11-09 10:39:00.232 INFO 21320 [Thread-120 thread] h.h.c.v.l.TestListener : value:[ l@ 1{=Um%l 2023-11-09 10:39:00.236 INFO 21320 [Thread-120 thread] h.h.c.v.l.TestListener : COM5 Reading Comm... 2023-11-09 10:39:00.237 INFO 21320 [Thread-120 thread] h.h.c.v.l.TestListener : Real Time Response: ,a 2023-11-09 10:39:00.238 INFO 21320 [Thread-120 thread] h.h.c.v.l.TestListener : value:[ l@ 1{=Um%l ,a 2023-11-09 10:39:00.241 INFO 21320 [Thread-120 thread] h.h.c.v.l.TestListener : COM5 Reading Comm... 2023-11-09 10:39:00.242 INFO 21320 [Thread-120 thread] h.h.c.v.l.TestListener : Real Time Response: 2023-11-09 10:39:00.243 INFO 21320 [Thread-120 thread] h.h.c.v.l.TestListener : value:[ l@ 1{=Um%l ,a 2023-11-09 10:39:01.202 INFO 21320 [Thread-120 thread] h.h.c.v.l.TestListener : COM5 Reading Comm... 2023-11-09 10:39:01.217 INFO 21320 [Thread-120 thread] h.h.c.v.l.TestListener : Real Time Response: 2023-11-09 10:39:01.217 INFO 21320 [Thread-120 thread] h.h.c.v.l.TestListener : value:[ l@ 1{=Um%l ,a
C#程序代码与日志
连接设备代码
string portName = "COM3"; int baudRate = 2400; Parity parity = Parity.Even; int dataBits = 7; StopBits stopBits = StopBits.One; _serialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits); _serialPort.DataReceived += SerialPort_DataReceived; _serialPort.Open();
数据监听代码
Console.WriteLine("Serial port opened. Press Enter to stop reading."); _logWriter = new StreamWriter("log.txt", true); while (true) { if (_serialPort.BytesToRead > 0) { string data = _serialPort.ReadExisting(); DateTime now = DateTime.Now; string logMessage = $"[{now}] Received data: {data}"; Console.WriteLine(logMessage); _logWriter.WriteLine($"[{now}] Received data: {data}"); _logWriter.Flush(); // Flush the buffer to ensure data is written immediately } }
C#程序日志
[09/11/2023 10:53:09] Received data: US,+000091.50 kg [09/11/2023 10:53:09] Received data: US,+000091.50 kg [09/11/2023 10:53:10] Received data: US,+000091.50 kg [09/11/2023 10:53:10] Received data: US,+000091.50 kg [09/11/2023 10:53:10] Received data: S [09/11/2023 10:53:10] Received data: T,+171.4 cm [09/11/2023 10:53:11] Received data: ST,+000091.50 kg [09/11/2023 10:53:11] Received data: US,+0000 [09/11/2023 10:53:11] Received data: 91.50 kg [09/11/2023 10:53:12] Received data: US,+000091.50 kg [09/11/2023 10:53:12] Received data: US,+000091.50 kg [09/11/2023 10:53:13] Received data: US,+00 [09/11/2023 10:53:13] Received data: 0091.50 kg [09/11/2023 10:53:13] Received data: US,+000091.50 kg
问题分析与解决方案
可能原因
- 串口参数映射错误:jSerialComm的参数常量与设备要求的映射可能存在偏差,比如7数据位、偶校验的常量定义是否正确对应
SerialPort.DATABITS_7和SerialPort.PARITY_EVEN。 - 流控制设置差异:C#原生串口默认可能启用了XON/XOFF流控制,而jSerialComm默认未启用,导致设备发送的数据无法被正确接收。
- 读取逻辑与编码差异:Java代码单次读取后直接break,未读取完缓存数据;且字符串转换未指定ASCII编码(C#默认用ASCII),导致字节转字符串时损坏。
- 端口初始化顺序问题:jSerialComm中参数设置顺序可能影响生效,需确保先配置所有参数再打开端口。
修复步骤
确认参数常量正确性
确保DEVICE_DATABITS为SerialPort.DATABITS_7,DEVICE_PARITY为SerialPort.PARITY_EVEN,DEVICE_STOPBITS为SerialPort.STOPBITS_1。统一编码方式
字符串转换时指定ASCII编码,与C#保持一致:log.info("Real Time Response:" + new String(readBuffer, 0, len, StandardCharsets.US_ASCII)); value += new String(readBuffer, 0, len, StandardCharsets.US_ASCII);优化读取逻辑
读取所有可用字节,复用输入流(不要每次读取都重新获取):// 初始化时获取一次输入流 private InputStream inputStream; // 端口打开成功后初始化 inputStream = serialPort.getInputStream(); public void readComm() { log.info(AppConfig.getInstance().getProperty(AppConfig.KEY_TEST_PORT, String.class) + " Reading Comm..."); byte[] readBuffer = new byte[1024]; try { int available = inputStream.available(); if (available > 0) { int len = inputStream.read(readBuffer, 0, available); if (len > 0) { String received = new String(readBuffer, 0, len, StandardCharsets.US_ASCII); log.info("Real Time Response:" + received); value += received; } } log.info("value:" + value); if (isDataReady) { // process data value = ""; //reset data } } catch (IOException e) { intNumberOfFailure++; } }配置流控制与超时
添加流控制和超时配置,匹配C#默认行为:serialPort.setFlowControl(SerialPort.FLOW_CONTROL_XONXOFF_IN_ENABLED | SerialPort.FLOW_CONTROL_XONXOFF_OUT_ENABLED); serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 100, 0);调整初始化顺序
先配置所有参数再打开端口:serialPort.setComPortParameters(DEVICE_RATE, DEVICE_DATABITS, DEVICE_STOPBITS, DEVICE_PARITY); serialPort.setFlowControl(...); serialPort.setComPortTimeouts(...); serialPort.addDataListener(this); serialPort.openPort();
内容的提问来源于stack exchange,提问作者LEE Hin
相关产品推荐
相关产品推荐

