由于项目之前用的串口工具RXTX只支持到jdk1.8 然后项目目前用到的jdk是13的 所以在网上找了一下 找到了这个 jSerialComm 目前使用是支持13及1.8的 没做其它jdk版本测试
引入jar包,github地址:http://fazecast.github.io/jSerialComm/
<!--http://fazecast.github.io/jSerialComm/-->
<!--串口连接工具-->
<dependency>
<groupId>com.fazecast</groupId>
<artifactId>jSerialComm</artifactId>
<version>[2.0.0,3.0.0)</version>
</dependency>
连接工具api文档地址:com.fazecast.jSerialComm (jSerialComm 2.9.0 API)
串口操作:
package com.jinfu.core;
import com.fazecast.jSerialComm.SerialPort;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Slf4j
public class SerialPortManager {
//查找所有可用端口
public static List<String> findPorts() {
// 获得当前所有可用串口
SerialPort[] serialPorts = SerialPort.getCommPorts();
List<String> portNameList = new ArrayList<String>();
// 将可用串口名添加到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(baudRate, 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[] reslutData = 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) {
reslutData = readBuffer;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return reslutData;
}
/**
* 添加监听器
* @param serialPort 串口对象
* @param listener 串口存在有效数据监听
*/
public static void addListener(SerialPort serialPort, DataAvailableListener listener) {
try {
// 给串口添加监听器
serialPort.addDataListener(new SerialPortListener(listener));
} catch (Exception e) {
e.printStackTrace();
}
}
}
当前串口工具是自带一个监听的方法SerialPortDataListener
目前是写了一个回调来监听串口工具的监听方法 这样做 是为了混淆 混淆后 串口工具自带的监听方法无法被其它地方调用
监听:
import com.fazecast.jSerialComm.SerialPort;
import com.fazecast.jSerialComm.SerialPortDataListener;
import com.fazecast.jSerialComm.SerialPortEvent;
import lombok.extern.slf4j.Slf4j;
/**
* 串口监听
*/
@Slf4j
public class SerialPortListener implements SerialPortDataListener {
private DataAvailableListener mDataAvailableListener;
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();
}
}
}
/**
* 串口存在有效数据监听
*/
public interface DataAvailableListener {
/**
* 串口存在有效数据
*/
void dataAvailable();
}
调用示例:
/**
* @throws PortInUseException 串口已经被占用
*/
public static void main(String[] args) throws PortInUseException {//打开串口,返回一个串口对象 参数:串口号 波特率
SerialPort serialPort = SerialPortManager.openPort("COM1", 10000);
//给当前串口对象设置监听器
SerialPortManager.addListener(serialPort, new DataAvailableListener() {
@Override
public void dataAvailable() {
//当前监听器监听到的串口返回数据 back
byte[] back = SerialPortManager.readFromPort(serialPort);
}
});
//当前向串口发送的数据(模拟假数据)
byte[] content = new byte[10];
//向当前串口发送数据
SerialPortManager.sendToPort(serialPort,content);
}
当前项目只针对一个设备 所以监听也是做的针对一个串口对象
目前有个小问题 当串口已经开启后 在去开启串口会提示串口开启失败 同时之前开启的串口无法再次开启除非关闭后才能再次开启 目前做的一个小处理就是在开启的时候先将当前连接上串口关闭 然后再重新开启