Browse Source

串口优化

master
HSZ_HeSongZhen 3 weeks ago
parent
commit
f28d345885
  1. 6
      src/main/java/org/mgc/common/MotorAxis.java
  2. 127
      src/main/java/org/mgc/serial_comm/SerialComm.java

6
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 };

127
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<byte[]> 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;
}
}
}
Loading…
Cancel
Save