java 串口工具jSerialComm
由于项目之前用的串口工具RXTX只支持到jdk1.8 然后项目目前用到的jdk是13的 所以在网上找了一下 找到了这个 jSerialComm 目前使用是支持13及1.8的 没做其它jdk版本测试
引入jar包,github地址: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); }