package chuankou;
|
|
import com.fazecast.jSerialComm.SerialPort;
|
import java.util.function.Consumer;
|
import java.io.ByteArrayOutputStream;
|
import java.io.InputStream;
|
import java.io.OutputStream;
|
import publicway.SerialProtocolParser; // 添加导入
|
import xitongshezhi.SystemDebugDialog;
|
|
public class SerialPortService {
|
|
private SerialPort port;
|
private volatile boolean capturing = false;
|
private volatile boolean paused = true;
|
private Thread readerThread;
|
private Consumer<byte[]> responseConsumer;
|
|
// 优化:重用缓冲区,减少内存分配
|
private byte[] readBuffer = new byte[200];
|
private ByteArrayOutputStream buffer = new ByteArrayOutputStream(1024);
|
private Consumer<byte[]> dataReceivedCallback;
|
|
// 新增:协议解析器引用
|
private SerialProtocolParser protocolParser = new SerialProtocolParser();
|
|
// 新增:数据条数计数器
|
public static int receivedDataCount = 0;
|
|
// 其他现有方法保持不变...
|
|
/**
|
* 获取串口接收的数据条数
|
* 当条数超过1万时自动从1开始重新计数
|
* @return 数据条数字符串
|
*/
|
public static String getReceivedDataCount() {
|
receivedDataCount++;
|
if (receivedDataCount > 10000) {
|
receivedDataCount = 1;
|
}
|
return String.valueOf(receivedDataCount);
|
}
|
|
public static void setReceivedDataCount(int receivedDataCount) {
|
SerialPortService.receivedDataCount = receivedDataCount;
|
}
|
|
/**
|
* 获取协议解析器实例
|
*/
|
public SerialProtocolParser getProtocolParser() {
|
return protocolParser;
|
}
|
|
/**
|
* 重置数据条数计数器
|
*/
|
public void resetReceivedDataCount() {
|
receivedDataCount = 0;
|
}
|
|
// 以下为原有代码,保持不变...
|
public InputStream getInputStream() {
|
if (port != null && port.isOpen()) {
|
return port.getInputStream();
|
}
|
return null;
|
}
|
|
public OutputStream getOutputStream() {
|
if (port != null && port.isOpen()) {
|
return port.getOutputStream();
|
}
|
return null;
|
}
|
|
public void setComPortTimeouts(int timeoutMode, int readTimeout, int writeTimeout) {
|
if (port != null && port.isOpen()) {
|
port.setComPortTimeouts(timeoutMode, readTimeout, writeTimeout);
|
}
|
}
|
|
/**
|
* 设置协议解析器
|
*/
|
public void setProtocolParser(SerialProtocolParser parser) {
|
this.protocolParser = parser;
|
}
|
|
/**
|
* 启用调试输出,将接收到的数据打印到控制台
|
*/
|
public void enableDebugOutput() {
|
System.out.println("串口调试输出已启用 - 开始监听串口数据...");
|
}
|
|
/**
|
* 获取当前调试状态
|
*/
|
public boolean isDebugEnabled() {
|
return capturing;
|
}
|
|
public void startCapture() {
|
if (dataReceivedCallback != null) {
|
startCapture(dataReceivedCallback);
|
} else {
|
System.err.println("No data received callback set. Please call startCapture(Consumer<byte[]> onReceived) first.");
|
}
|
}
|
|
/**
|
* 打开串口
|
*/
|
public boolean open(String portName, int baud) {
|
if (port != null && port.isOpen()) {
|
return true;
|
}
|
|
port = SerialPort.getCommPort(portName);
|
port.setComPortParameters(baud, 8, 1, SerialPort.NO_PARITY);
|
port.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 1, 0);
|
protocolParser.start();
|
return port.openPort();
|
}
|
|
public void setResponseConsumer(Consumer<byte[]> consumer) {
|
this.responseConsumer = consumer;
|
}
|
|
/**
|
* 关闭串口
|
*/
|
public void close() {
|
stopCapture();
|
if (port != null && port.isOpen()) {
|
port.closePort();
|
}
|
port = null;
|
}
|
|
/**
|
* 启动数据接收线程
|
*/
|
public void startCapture(Consumer<byte[]> onReceived) {
|
this.dataReceivedCallback = onReceived;
|
if (capturing || port == null || !port.isOpen()) return;
|
capturing = true;
|
paused = false;
|
|
readerThread = new Thread(() -> {
|
buffer.reset();
|
long lastReceivedTime = 0;
|
|
while (capturing && port.isOpen()) {
|
long currentTime = System.currentTimeMillis();
|
|
if (buffer.size() > 0 && (currentTime - lastReceivedTime) >= 20) {
|
byte[] data = buffer.toByteArray();
|
SystemDebugDialog.appendHexData(data);
|
|
// 新增:将数据传递给协议解析器
|
if (protocolParser != null) {
|
protocolParser.receiveData(data);
|
}
|
|
if (!paused) {
|
onReceived.accept(data);
|
if (responseConsumer != null) {
|
responseConsumer.accept(data);
|
}
|
}
|
buffer.reset();
|
}
|
|
int len = port.readBytes(readBuffer, readBuffer.length);
|
currentTime = System.currentTimeMillis();
|
|
if (len > 0) {
|
buffer.write(readBuffer, 0, len);
|
lastReceivedTime = currentTime;
|
}
|
|
if (len <= 0 && buffer.size() == 0) {
|
try { Thread.sleep(1); } catch (InterruptedException ignore) {}
|
}
|
}
|
|
if (buffer.size() > 0) {
|
byte[] data = buffer.toByteArray();
|
SystemDebugDialog.appendHexData(data);
|
|
// 新增:将数据传递给协议解析器
|
if (protocolParser != null) {
|
protocolParser.receiveData(data);
|
}
|
|
if (!paused) {
|
onReceived.accept(data);
|
if (responseConsumer != null) {
|
responseConsumer.accept(data);
|
}
|
}
|
}
|
});
|
readerThread.setDaemon(true);
|
readerThread.start();
|
}
|
|
/**
|
* 停止数据接收线程
|
*/
|
public void stopCapture() {
|
capturing = false;
|
if (readerThread != null) {
|
try { readerThread.join(500); } catch (InterruptedException ignore) {}
|
readerThread = null;
|
}
|
}
|
|
public void setPaused(boolean paused) {
|
this.paused = paused;
|
}
|
|
public boolean isPaused() {
|
return paused;
|
}
|
|
public boolean isOpen() {
|
return port != null && port.isOpen();
|
}
|
|
/**
|
* 发送数据
|
*/
|
public boolean send(byte[] data) {
|
if (!isOpen()) {
|
return false;
|
}
|
return port != null && port.isOpen() && port.writeBytes(data, data.length) > 0;
|
}
|
}
|