JAVA的jSerialComm类库和串口协议通信案例
前言
本文旨在介绍JAVA的jSerialComm类库和串口协议通信案例。
依赖
<!--jSerialComm-->
<dependency>
<groupId>com.fazecast</groupId>
<artifactId>jSerialComm</artifactId>
<version>2.6.2</version>
</dependency>
SerialPortManager
@Slf4j
@Component
public class SerialPortManager {
// 查找所有可用端口
public static List<String> findPorts() {
// 获得当前所有可用串口
SerialPort[] serialPorts = SerialPort.getCommPorts();
List<String> portNameList = new ArrayList<>();
// 将可用串口名添加到List并返回该List
for (SerialPort serialPort : serialPorts) {
portNameList.add(serialPort.getSystemPortName());
}
// 去重
portNameList = portNameList.stream().distinct().collect(Collectors.toList());
return portNameList;
}
/**
* 打开串口
*
* @param portName 端口名称
* @param baudRate 波特率
* @return 串口对象
*/
public static SerialPort openPort(String portName, Integer baudRate) {
SerialPort serialPort = SerialPort.getCommPort(portName);
if (baudRate != null) {
serialPort.setBaudRate(baudRate);
}
// 开启串口
if (!serialPort.isOpen()) {
serialPort.openPort(1000);
} else {
return serialPort;
}
// 设置一下串口的波特率等参数
// 数据位:8
// 停止位:1
// 校验位:None
serialPort.setFlowControl(SerialPort.FLOW_CONTROL_DISABLED);
serialPort.setComPortParameters(Optional.ofNullable(baudRate).orElse(9600), 8, SerialPort.ONE_STOP_BIT, SerialPort.NO_PARITY);
serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_BLOCKING | SerialPort.TIMEOUT_WRITE_BLOCKING, 1000, 1000);
return serialPort;
}
/**
* 关闭串口
*
* @param serialPort 待关闭的串口对象
*/
public static void closePort(SerialPort serialPort) {
if (serialPort != null && serialPort.isOpen()) {
serialPort.closePort();
}
}
/**
* 往串口发送数据
*
* @param serialPort 串口对象
* @param content 待发送数据
*/
public static void sendToPort(SerialPort serialPort, byte[] content) {
if (!serialPort.isOpen()) {
return;
}
serialPort.writeBytes(content, content.length);
}
/**
* 从串口读取数据
*
* @param serialPort 当前已建立连接的SerialPort对象
* @return 读取到的数据
*/
public static byte[] readFromPort(SerialPort serialPort) {
byte[] resultData = null;
try {
if (!serialPort.isOpen()) {
return null;
}
int i = 0;
while (serialPort.bytesAvailable() > 0 && i++ < 5) Thread.sleep(20);
byte[] readBuffer = new byte[serialPort.bytesAvailable()];
int numRead = serialPort.readBytes(readBuffer, readBuffer.length);
if (numRead > 0) {
resultData = readBuffer;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return resultData;
}
/**
* 添加监听器
*
* @param serialPort 串口对象
* @param listener 串口存在有效数据监听
*/
public static void addListener(SerialPort serialPort, DataAvailableListener listener) {
try {
// 给串口添加监听器
serialPort.addDataListener(new SerialPortListener(listener));
} catch (Exception e) {
e.printStackTrace();
}
}
}
SerialPortListener
/**
* 串口监听
*/
@Slf4j
@Component
public class SerialPortListener implements SerialPortDataListener {
private DataAvailableListener mDataAvailableListener;
public SerialPortListener() {
}
public SerialPortListener(DataAvailableListener mDataAvailableListener) {
this.mDataAvailableListener = mDataAvailableListener;
}
@Override
public int getListeningEvents() {
// 必须是return这个才会开启串口工具的监听
return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
}
public void serialEvent(SerialPortEvent serialPortEvent) {
if (mDataAvailableListener != null) {
mDataAvailableListener.dataAvailable();
}
}
}
DataAvailableListener
/**
* 数据监听
*/
public interface DataAvailableListener {
/**
* 存在有效数据
*/
void dataAvailable();
}
串口监听器SerialStarter
@Component
@Slf4j
public class SerialStarter {
/**
* 静态串口对象:类加载时打开一次,全局共用
*/
private static final SerialPort serialPort;
static {
serialPort = SerialPortManager.openPort("COM2", 115200);
if (serialPort.isOpen()) {
log.info("serial串口已打开");
} else {
log.error("serial串口打开失败");
}
}
@PostConstruct
public void addListener() {
if (!serialPort.isOpen()) {
return;
}
// 给当前串口设置监听器
SerialPortManager.addListener(serialPort, new DataAvailableListener() {
@Override
public void dataAvailable() {
// 监听到的串口返回数据
byte[] back = SerialPortManager.readFromPort(serialPort);
if (back == null) {
return;
}
String backStr = new String(back, StandardCharsets.UTF_8);
log.info("串口返回数据,{}", backStr);
}
});
}
/**
* 发送数据
*
* @param message 消息
*/
public static void sendData(String message) {
if (serialPort == null || !serialPort.isOpen()) {
throw new RuntimeException("serial串口未打开");
}
byte[] content = message.getBytes();
SerialPortManager.sendToPort(serialPort, content);
}
}
测试
工具
- vspd

java项目是springboot工程,即启动项目。


- sscom


测试过程
- 从站到主站

-
主站到从站
@RestController @RequestMapping("/serial") public class SendMessageController { @PostMapping("/send") public void sendMessage(@RequestParam String message) { SerialStarter.sendData(message); } }发送http请求。
![7]()


浙公网安备 33010602011771号