java串口通讯
1、环境配置
java串口通讯需要依赖两个dll文件 rxtxParallel.dll、rxtxSerial.dll,已经第三方sdk(RXTXcomm.jar);
博客下载:https://files-cdn.cnblogs.com/files/blogs/666773/rxtx-win-x64.rar
官网下载:http://fizzed.com/oss/rxtx-for-java
两个dll文件需要粘贴到jdk安装目录下 jdk/jre/bin/
当前第三方sdk也可通过pom.xml引入
org.rxtx rxtx 2.1.7
java:java1.8
1.8
springboot:2.5.6
org.springframework.boot
spring-boot-starter-parent
2.5.6
pom.xml如下所示:
org.springframework.boot spring-boot-starter-web org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test org.rxtx rxtx 2.1.7 io.springfox springfox-swagger2 2.9.2 io.springfox springfox-swagger-ui 2.9.2
SerialPortManager.java
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 SerialPortManager { //查找所有可用端口 public static ArrayListfindPorts() { // 获得当前所有可用串口 Enumeration portList = CommPortIdentifier.getPortIdentifiers(); ArrayList portNameList = new ArrayList (); // 将可用串口名添加到List并返回该List while (portList.hasMoreElements()) { String portName = portList.nextElement().getName(); portNameList.add(portName); } return portNameList; } /** * 打开串口 * * @param portName 端口名称 * @param baudRate 波特率 * @return 串口对象 * @throws PortInUseException 串口已被占用 */ public static SerialPort openPort(String portName, int baudRate) throws PortInUseException { try { // 通过端口名识别端口 CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName); // 打开端口,并给端口名字和一个timeout(打开操作的超时时间) CommPort commPort = portIdentifier.open(portName, 2000); // 判断是不是串口 if (commPort instanceof SerialPort) { SerialPort serialPort = (SerialPort) commPort; try { // 设置一下串口的波特率等参数 // 数据位:8 // 停止位:1 // 校验位:None serialPort.setSerialPortParams(baudRate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); } catch (UnsupportedCommOperationException e) { e.printStackTrace(); } return serialPort; } } catch (NoSuchPortException e1) { e1.printStackTrace(); } return null; } /** * 关闭串口 * @param serialPort 待关闭的串口对象 */ public static void closePort(SerialPort serialPort) { if (serialPort != null) { serialPort.close(); } } /** * 往串口发送数据 * @param serialPort 串口对象 * @param content 待发送数据 */ public static void sendToPort(SerialPort serialPort, byte[] content) { OutputStream out = null; try { out = serialPort.getOutputStream(); out.write(content); out.flush(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (out != null) { out.close(); out = null; } } catch (IOException e) { e.printStackTrace(); } } } /** * 从串口读取数据 * @param serialPort 当前已建立连接的SerialPort对象 * @return 读取到的数据 */ public static byte[] readFromPort(SerialPort serialPort) { InputStream in = null; byte[] bytes = {}; try { in = serialPort.getInputStream(); // 缓冲区大小为一个字节 byte[] readBuffer = new byte[1]; int bytesNum = in.read(readBuffer); while (bytesNum > 0) { bytes = AgreementUtil.concat(bytes, readBuffer); bytesNum = in.read(readBuffer); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (in != null) { in.close(); in = null; } } catch (IOException e) { e.printStackTrace(); } } return bytes; } /** * 添加监听器 * @param serialPort 串口对象 * @param listener 串口存在有效数据监听 */ public static void addListener(SerialPort serialPort, DataAvailableListener listener) { try { // 给串口添加监听器 serialPort.addEventListener(new SerialPortListener(listener)); // 设置当有数据到达时唤醒监听接收线程 serialPort.notifyOnDataAvailable(true); // 设置当通信中断时唤醒中断线程 serialPort.notifyOnBreakInterrupt(true); } catch (TooManyListenersException e) { e.printStackTrace(); } } /** * 串口监听 */ public static class SerialPortListener implements SerialPortEventListener { private DataAvailableListener mDataAvailableListener; public SerialPortListener(DataAvailableListener mDataAvailableListener) { this.mDataAvailableListener = mDataAvailableListener; } public void serialEvent(SerialPortEvent serialPortEvent) { switch (serialPortEvent.getEventType()) { case SerialPortEvent.DATA_AVAILABLE: // 1.串口存在有效数据 if (mDataAvailableListener != null) { mDataAvailableListener.dataAvailable(); } break; case SerialPortEvent.OUTPUT_BUFFER_EMPTY: // 2.输出缓冲区已清空 break; case SerialPortEvent.CTS: // 3.清除待发送数据 break; case SerialPortEvent.DSR: // 4.待发送数据准备好了 break; case SerialPortEvent.RI: // 5.振铃指示 break; case SerialPortEvent.CD: // 6.载波检测 break; case SerialPortEvent.OE: // 7.溢位(溢出)错误 break; case SerialPortEvent.PE: // 8.奇偶校验错误 break; case SerialPortEvent.FE: // 9.帧错误 break; case SerialPortEvent.BI: // 10.通讯中断 log.error("与串口设备通讯中断"); break; default: break; } } } /** * 串口存在有效数据监听 */ public interface DataAvailableListener { /** * 串口存在有效数据 */ void dataAvailable(); } }
调用示例
/** * @throws PortInUseException 串口已经被占用 */ public static void main(String[] args) throws PortInUseException { //获取可用串口列表 ArrayListports = SerialPortManager.findPorts(); //当前使用第一个串口,通常串口名称由用户自行控制 String portName = ports.get(0); //波特率,当前使用115200 int baudRate = 115200; //打开串口,返回一个串口对象 SerialPort serialPort = SerialPortManager.openPort(portName, baudRate); //给当前串口对象设置监听器 SerialPortManager.addListener(serialPort, new SerialPortManager.DataAvailableListener() { @Override public void dataAvailable() { //当前监听器监听到的串口返回数据 back byte[] back = SerialPortManager.readFromPort(serialPort); //数据监听完之后,关闭串口 SerialPortManager.closePort(serialPort); } }); //当前向串口发送的数据(模拟假数据) byte[] content = new byte[10]; //向当前串口发送数据 SerialPortManager.sendToPort(serialPort,content); }
参考:https://blog.csdn.net/kong_gu_you_lan/article/details/80589859#commentBox