1.准备工作
RXTXcomm.jar 放入 {JAVA_HOME}/jre/lib/ext
rxtxserial.dll 放入 {JAVA_HOME}/jre/bin
2.在pom.xml中引用RXTXcomm.jar包
3.串口工具类
import gnu.io.*; import lombok.extern.slf4j.Slf4j; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Enumeration; import java.util.TooManyListenersException; /** * 串口工具类 */ @Slf4j public class SerialPortUtil { private static SerialPortUtil serialPortUtil = null; static { serialPortUtil = new SerialPortUtil(); } private SerialPortUtil(){ } /** * 获取提供服务的SerialTool对象 * @return serialPortUtil */ public static SerialPortUtil getSerialPortUtil(){ if(serialPortUtil == null){ serialPortUtil = new SerialPortUtil(); } return serialPortUtil; } /** * 查找所有可用端口 * @return 可用端口名称列表 */ public ArrayList<String> findPort() { // 获得当前所有可用串口 Enumeration<CommPortIdentifier> portList = CommPortIdentifier.getPortIdentifiers(); ArrayList<String> portNameList = new ArrayList<>(); // 将可用串口名添加到List并返回该List while (portList.hasMoreElements()) { String portName = portList.nextElement().getName(); portNameList.add(portName); } return portNameList; } /** * 打开串口 * @param portName 端口名称 * @param baudrate 波特率 9600 * @param databits 数据位 8 * @param parity 校验位(奇偶位) NONE :0 * @param stopbits 停止位 1 * @return 串口对象 */ public SerialPort openPort(String portName, int baudrate, int databits, int parity, int stopbits) { try { // 通过端口名识别端口 CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName); // 打开端口,并给端口名字和一个timeout(打开操作的超时时间) CommPort commPort = portIdentifier.open(portName, 5000); // 判断是不是串口 if (commPort instanceof SerialPort) { SerialPort serialPort = (SerialPort) commPort; // 设置一下串口的波特率等参数 serialPort.setSerialPortParams(baudrate, databits, stopbits, parity); log.info("打开串口 " + portName + " 成功 !"); return serialPort; } else { log.error("不是串口"); } } catch (NoSuchPortException e1) { log.error("没有找到端口"); e1.printStackTrace(); } catch (PortInUseException e2) { log.error("端口被占用"); e2.printStackTrace(); } catch (UnsupportedCommOperationException e) { e.printStackTrace(); } return null; } /** * 关闭串口 * @param serialPort 待关闭的串口对象 */ public void closePort(SerialPort serialPort) { if (serialPort != null) { serialPort.close(); } } /** * 往串口发送数据 * @param serialPort 串口对象 */ public void sendToPort(SerialPort serialPort, byte[] bytes) { OutputStream out = null; try { out = serialPort.getOutputStream(); out.write(bytes); out.flush(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (out != null) { out.close(); } } catch (IOException e) { e.printStackTrace(); } } } /** * 从串口读取数据 * @param serialPort 当前已建立连接的SerialPort对象 * @return 读取到的数据 */ public byte[] readFromPort(SerialPort serialPort) { InputStream in = null; byte[] bytes = null; try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } try { in = serialPort.getInputStream(); // 获取buffer里的数据长度 int bufferlength = in.available(); while (bufferlength != 0) { // 初始化byte数组为buffer中数据的长度 bytes = new byte[bufferlength]; in.read(bytes); bufferlength = in.available(); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (in != null) { in.close(); } } catch (IOException e) { e.printStackTrace(); } } return bytes; } /** * 添加监听器 * @param port 串口对象 * @param listener 串口监听器 */ public void addListener(SerialPort port, SerialPortEventListener listener) { try { // 给串口添加监听器 port.addEventListener(listener); // 设置当有数据到达时唤醒监听接收线程 port.notifyOnDataAvailable(true); // 设置当通信中断时唤醒中断线程 port.notifyOnBreakInterrupt(true); } catch (TooManyListenersException e) { log.error("太多监听器"); e.printStackTrace(); } } /** * 删除监听器 * * @param port 串口对象 * @param listener 串口监听器 */ public void removeListener(SerialPort port, SerialPortEventListener listener) { // 删除串口监听器 port.removeEventListener(); } /** * 设置串口的Listener * * @param serialPort * @param listener */ public static void setListenerToSerialPort(SerialPort serialPort, SerialPortEventListener listener) { try { // 给串口添加事件监听 serialPort.addEventListener(listener); } catch (TooManyListenersException e) { e.printStackTrace(); } // 串口有数据监听 serialPort.notifyOnDataAvailable(true); // 中断事件监听 serialPort.notifyOnBreakInterrupt(true); } }
4.串口对象类 功能:有打开串口、给串口发送信息、关闭串口
import gnu.io.SerialPort; import lombok.Data; import lombok.extern.slf4j.Slf4j; /** * COM02口 控制 */ @Data @Slf4j public class COM02 { private static String name ="COM2";//串口名称 public static SerialPort serialPort1 = null; //串口会话 //打开串口 public static SerialPort openCOMPort() { SerialPortUtil serialPortUtil =SerialPortUtil.getSerialPortUtil(); SerialPort serialPort = serialPortUtil.openPort(name, 115200, 8, 0, 1);//串口名称 波特率(硬件波特率) SerialPortListener listener = new SerialPortListener(); listener.setSerialPort(serialPort); serialPort1=serialPort; // listener.setSerialPort(serialPort1); serialPortUtil.addListener(serialPort1,listener); return serialPort1; } // 发送指令 public static void send(byte[] code){ SerialPortUtil serialPortUtil = SerialPortUtil.getSerialPortUtil(); if(serialPort1 != null){ serialPortUtil.sendToPort(serialPort1,code); } else { log.info("发送失败"); } } /** * 关闭串口 * @param */ public static void closePort() { if (serialPort1 != null) { serialPort1.close(); } } }
5.创建串口监听器(串口有信息都会在这里接收)
/** * 监听器 */ @Slf4j @Data public class SerialPortListener implements SerialPortEventListener {private SerialPort serialPort = null;@Override public void serialEvent(SerialPortEvent serialPortEventswitch (serialPortEvent.getEventType()){ // 1.串口存在有效数据 case SerialPortEvent.DATA_AVAILABLE: byte[] bytes = SerialPortUtil.getSerialPortUtil().readFromPort(serialPort); log.info("===========start==========="); log.info("COM2接收的"); log.info(new Date() + "【读到的字符】:-----" + Arrays.toString(bytes)); log.info(new Date() + "【字节数组转字符串】:-----" + ModBusUtils.zifString(bytes)); log.info("【字节数组转16进制字符串】:"+ Hex.encodeHexString(bytes)); log.info("===========end==========="); break; // 2.输出缓冲区已清空 case SerialPortEvent.OUTPUT_BUFFER_EMPTY: log.error("输出缓冲区已清空"); break; // 3.清除待发送数据 case SerialPortEvent.CTS: log.error("清除待发送数据"); break; // 4.待发送数据准备好了 case SerialPortEvent.DSR: log.error("待发送数据准备好了"); break; // 10.通讯中断 case SerialPortEvent.BI: log.error("与串口设备通讯中断"); break; default: break;}
}
}