From f28d345885bd0af1e60cae1ce837d61f59480fee Mon Sep 17 00:00:00 2001 From: HSZ_HeSongZhen <210202959@qq.com> Date: Sat, 12 Jul 2025 21:24:49 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=B2=E5=8F=A3=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/org/mgc/common/MotorAxis.java | 6 +- src/main/java/org/mgc/serial_comm/SerialComm.java | 127 +++++++++++++++------- 2 files changed, 93 insertions(+), 40 deletions(-) diff --git a/src/main/java/org/mgc/common/MotorAxis.java b/src/main/java/org/mgc/common/MotorAxis.java index c081bee..fa895cb 100644 --- a/src/main/java/org/mgc/common/MotorAxis.java +++ b/src/main/java/org/mgc/common/MotorAxis.java @@ -25,10 +25,12 @@ public enum MotorAxis { // 每毫米对应的圈数 // private static final double[] REVOLUTIONS_PER_MM = {0.5, 0.2, 0.2}; - private static final double[] REVOLUTIONS_PER_MM = {0.2, 0.2, 0.16666666666666666667}; +// private static final double[] REVOLUTIONS_PER_MM = {0.2, 0.2, 0.16666666666666666667}; + private static final double[] REVOLUTIONS_PER_MM = {0.2, 0.2, 0.5}; // 距离限制(mm) - private static final int[] POSITION_LIMITS = {200, 150, 100}; +// private static final int[] POSITION_LIMITS = {200, 150, 100}; + private static final int[] POSITION_LIMITS = {350, 200, 100}; // 转速限制(r/min) private static final int[] SPEED_LIMITS = { 9000, 9000, 9000 }; diff --git a/src/main/java/org/mgc/serial_comm/SerialComm.java b/src/main/java/org/mgc/serial_comm/SerialComm.java index 7781d17..6349eb1 100644 --- a/src/main/java/org/mgc/serial_comm/SerialComm.java +++ b/src/main/java/org/mgc/serial_comm/SerialComm.java @@ -1,11 +1,15 @@ package org.mgc.serial_comm; import com.fazecast.jSerialComm.SerialPort; +import com.fazecast.jSerialComm.SerialPortDataListener; +import com.fazecast.jSerialComm.SerialPortEvent; import lombok.extern.slf4j.Slf4j; import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.io.ByteArrayOutputStream; @Slf4j public class SerialComm { @@ -18,6 +22,8 @@ public class SerialComm { private final SerialPort serialPort; + private final BlockingQueue responseQueue = new LinkedBlockingQueue<>(); + public SerialComm(String portName, int baudRate, int dataBits, int stopBits, int parity) { this.portName = portName; this.baudRate = baudRate; @@ -33,23 +39,67 @@ public class SerialComm { } public void open() throws Exception { - if (!serialPort.openPort()) { - log.warn("Could not open serial port {}", serialPort.getSystemPortName()); - throw new IOException("Failed to open serial port: " + serialPort.getSystemPortName()); + if (serialPort.openPort()) { + log.info("Opened serial port: {} open Success ", serialPort.getSystemPortName()); + + clearSerialPortBuffer(); + + // 新增:临时缓冲区 + ByteArrayOutputStream tempBuffer = new ByteArrayOutputStream(); + + SerialPortDataListener dataListener = new SerialPortDataListener() { + @Override + public int getListeningEvents() { + return SerialPort.LISTENING_EVENT_DATA_RECEIVED; + } + + @Override + public void serialEvent(SerialPortEvent event) { + if (event.getEventType() == SerialPort.LISTENING_EVENT_DATA_RECEIVED) { + byte[] newData = event.getReceivedData(); + if (newData != null && newData.length > 0) { + synchronized (tempBuffer) { + try { + tempBuffer.write(newData); + } catch (Exception e) { + log.error("Error writing to tempBuffer", e); + } + // 延时 1ms + try { + Thread.sleep(5); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + log.error("Sleep interrupted", e); + } + // 只有缓冲区为空时才入队 + if (serialPort.bytesAvailable() == 0) { + byte[] frame = tempBuffer.toByteArray(); + if (frame.length > 0) { + responseQueue.add(frame); + } + tempBuffer.reset(); + } + } + } + } + } + }; + serialPort.addDataListener(dataListener); } else{ - log.info("Opened serial port: " + serialPort.getSystemPortName()); + log.warn("Could not open serial port {}", serialPort.getSystemPortName()); + throw new IOException("Failed to open serial port: " + serialPort.getSystemPortName()); } } - void setReadTimeOut(int readTimeOut) { - serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, readTimeOut, 0); - } - public void close() throws Exception { + // 清空缓存数据 + responseQueue.clear(); if (serialPort != null) { + // 移除监听 + serialPort.removeDataListener(); serialPort.closePort(); - log.info("Closed serial port: {}", serialPort.getSystemPortName()); + log.info("Closed serial port: {} Suc", serialPort.getSystemPortName()); } else { @@ -59,15 +109,16 @@ public class SerialComm { byte[] sendBlockAutoRetry(byte[] send_data, int timeout) { + clearSerialPortBuffer(); for(int i = 0; i < retry_times; i++) { - byte[] data = sendBlocked(send_data, timeout); - if(data.length != 0) - { - // 成功 - return data; - } - log.warn("sendBlockAutoRetry failed for {} times", retry_times); + byte[] data = sendBlocked(send_data, timeout); + if(data != null && data.length != 0) + { + // 成功 + return data; + } + log.warn("sendBlockAutoRetry failed for {} times", i); } // 三次超时失败视为 断联 立即进行重启 try { @@ -83,9 +134,8 @@ public class SerialComm { synchronized public byte[] sendBlocked(byte[] send_data, int timeout) { - setReadTimeOut(timeout); // 指定超时时间,通过串口配置超时时间 writeBytes(send_data); - return readBytes(); + return readBytes(timeout); } public int writeBytes(byte[] data) @@ -95,29 +145,30 @@ public class SerialComm { return num; } - public byte[] readBytes() + // 读取时间 + public byte[] readBytes(int timeout) { - int numRead = 0; - byte[] readBuffer = new byte[1024]; try { - Thread.sleep(100); - } catch (InterruptedException e) { - log.info("thread interrupted while waiting for read bytes {}", e.getMessage()); - } - if (serialPort.bytesAvailable() > 0) - { - numRead = serialPort.readBytes(readBuffer, readBuffer.length); - if(numRead > 0) - { - byte[] data = new byte[numRead]; - System.arraycopy(readBuffer, 0, data, 0, numRead); - return data; - } - } + return responseQueue.poll(timeout, TimeUnit.MILLISECONDS); + } catch (InterruptedException ignored) + {} log.info("Read bytes failed"); return new byte[0]; } + private void clearSerialPortBuffer() { + try { + int availableBytes = serialPort.bytesAvailable(); + if (availableBytes > 0) { + byte[] buffer = new byte[availableBytes]; + serialPort.readBytes(buffer, availableBytes); + log.info("Cleared {} bytes of residual data from the serial port.", availableBytes); + } + } catch (Exception e) { + log.error("Error clearing serial port buffer: ", e); + } + } + public int getBaudRate() { return this.baudRate; } @@ -133,4 +184,4 @@ public class SerialComm { public int getDataBits() { return this.dataBits; } -} +} \ No newline at end of file