Java串口通信——RXTX


1.前期准備

  a.配置 RXTX

    1)下載 RXTX 包並解壓,網址:http://fizzed.com/oss/rxtx-for-java

    2)拷貝動態庫到對應的jdk目錄下

      ·Windows平台

        拷貝  rxtxSerial.dll ---> <JAVA_HOME>\jre\bin
        拷貝  rxtxParallel.dll ---> <JAVA_HOME>\jre\bin

      ·Linux平台

        拷貝  librxtxSerial.so ---> <JAVA_HOME>/jre/lib/i386/
        拷貝  librxtxParallel.so ---> <JAVA_HOME>/jre/lib/i386/

 

    3)在工程根目錄下創建 lib 文件夾(與src平級),將 RXTXcomm.jar 放入該文件夾中

    4)在 pom.xml 中引入本地 jar 包依賴

  <dependencies>

    ......

    <dependency>
      <groupId>gnu.io</groupId>
      <artifactId>RXTXcomm</artifactId>
      <scope>system</scope>
      <systemPath>${project.basedir}/lib/RXTXcomm.jar</systemPath>
    </dependency>
  </dependencies>

 

  b.安裝虛擬串口驅動:vspd (收費,有破解版)

  c.安裝串口調試工具:Serial Port Utility (免費)

 

 

2.使用

  a.新建串口VO類

public class SerialVo {

    /**
     * 串口名稱(COM0、COM1、COM2等等)
     */
    private String serialPortName;
    /**
     * 波特率
     * 默認:115200
     */
    private int baudRate;
    /**
     * 數據位 默認8位
     * 可以設置的值:SerialPort.DATABITS_5、SerialPort.DATABITS_6、SerialPort.DATABITS_7、SerialPort.DATABITS_8
     * 默認:SerialPort.DATABITS_8
     */
    private int dataBits;
    /**
     * 停止位
     * 可以設置的值:SerialPort.STOPBITS_1、SerialPort.STOPBITS_2、SerialPort.STOPBITS_1_5
     * 默認:SerialPort.STOPBITS_1
     */
    private int stopBits;
    /**
     * 校驗位
     * 可以設置的值:SerialPort.PARITY_NONE、SerialPort.PARITY_ODD、SerialPort.PARITY_EVEN、SerialPort.PARITY_MARK、SerialPort.PARITY_SPACE
     * 默認:SerialPort.PARITY_NONE
     */
    private int parity;

    public SerialVo(String serialPortName) {
        this.serialPortName = serialPortName;
        this.baudRate = 115200;
        this.dataBits = SerialPort.DATABITS_8;
        this.stopBits = SerialPort.STOPBITS_1;
        this.parity = SerialPort.PARITY_NONE;
    }

    public SerialVo(String serialPortName, int baudRate) {
        this.serialPortName = serialPortName;
        this.baudRate = baudRate;
        this.dataBits = SerialPort.DATABITS_8;
        this.stopBits = SerialPort.STOPBITS_1;
        this.parity = SerialPort.PARITY_NONE;
    }

    public String getSerialPortName() {
        return serialPortName;
    }

    public void setSerialPortName(String serialPortName) {
        this.serialPortName = serialPortName;
    }

    public int getBaudRate() {
        return baudRate;
    }

    public void setBaudRate(int baudRate) {
        this.baudRate = baudRate;
    }

    public int getDataBits() {
        return dataBits;
    }

    public void setDataBits(int dataBits) {
        this.dataBits = dataBits;
    }

    public int getStopBits() {
        return stopBits;
    }

    public void setStopBits(int stopBits) {
        this.stopBits = stopBits;
    }

    public int getParity() {
        return parity;
    }

    public void setParity(int parity) {
        this.parity = parity;
    }
}

 

  b.新建串口工具類

public class SerialUtil {

    /**
     * 獲得系統可用的端口名稱列表(COM0、COM1、COM2等等)
     */
    public static List<String> getSerialPortList() {
        List<String> systemPorts = new ArrayList<>();
        //獲得系統可用的端口
        Enumeration<CommPortIdentifier> portList = CommPortIdentifier.getPortIdentifiers();
        while (portList.hasMoreElements()) {
            String portName = portList.nextElement().getName();//獲得端口的名字
            systemPorts.add(portName);
        }
        return systemPorts;
    }


    /**
     * 打開串口
     */
    public static SerialPort openSerialPort(SerialVo serialVo, int timeout) throws Exception {
        //通過端口名稱得到端口
        CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(serialVo.getSerialPortName());
        //打開端口,(自定義名字,打開超時時間)
        CommPort commPort = portIdentifier.open(serialVo.getSerialPortName(), timeout);
        //判斷是不是串口
        if (commPort instanceof SerialPort) {
            SerialPort serialPort = (SerialPort) commPort;
            //設置串口參數(波特率,數據位8,停止位1,校驗位無)
            serialPort.setSerialPortParams(serialVo.getBaudRate(), serialVo.getDataBits(), serialVo.getStopBits(), serialVo.getParity());
            System.out.println("開啟串口成功,串口名稱:" + serialVo.getSerialPortName());
            return serialPort;
        } else {
            //是其他類型的端口
            throw new NoSuchPortException();
        }
    }


    /**
     * 關閉串口
     */
    public static void closeSerialPort(SerialPort serialPort) {
        if (serialPort != null) {
            serialPort.close();
            System.out.println("關閉了串口:" + serialPort.getName());
        }
    }


    /**
     * 向串口發送數據
     */
    public static void sendData(SerialPort serialPort, byte[] data) {
        OutputStream os = null;
        try {
            //獲得串口的輸出流
            os = serialPort.getOutputStream();
            os.write(data);
            os.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 從串口讀取數據
     */
    public static byte[] readData(SerialPort serialPort) {
        InputStream is = null;
        byte[] bytes = null;
        try {
            //獲得串口的輸入流
            is = serialPort.getInputStream();
            //獲得數據長度
            int bufflenth = is.available();
            while (bufflenth != 0) {
                //初始化byte數組
                bytes = new byte[bufflenth];
                is.read(bytes);
                bufflenth = is.available();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return bytes;
    }


    /**
     * 給串口設置監聽
     */
    public static void setListenerToSerialPort(SerialPort serialPort, SerialPortEventListener listener) throws Exception {
        //給串口添加事件監聽
        serialPort.addEventListener(listener);
        //串口有數據監聽
        serialPort.notifyOnDataAvailable(true);
        //中斷事件監聽
        serialPort.notifyOnBreakInterrupt(true);
    }

}

 

 

3.調試

  a.新建測試類

public class App {

    //防止被GC回收
    private static SerialVo serialVo;

    public static void main( String[] args ) {
        //獲得系統可用的端口名稱
        List<String> portList = SerialUtil.getSerialPortList();
        System.out.println(portList);

        try {
            serialVo = new SerialVo("COM2");
            final SerialPort serialPort = SerialUtil.openSerialPort(serialVo, 115200);
            //啟動一個線程每2s向串口發送數據,發送1000次hello
            new Thread(() -> {
                int i = 1;
                while (i < 1000) {
                    String s = "hello " + i++;
                    byte[] bytes = s.getBytes();
                    SerialUtil.sendData(serialPort, bytes);//發送數據
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
            //設置串口的listener
            SerialUtil.setListenerToSerialPort(serialPort, event -> {
                //數據通知
                if (event.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
                    byte[] bytes = SerialUtil.readData(serialPort);
                    System.out.println("收到的數據長度:" + bytes.length);
                    System.out.println("收到的數據:" + new String(bytes));
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

  b.使用 vspd 添加兩個虛擬串口 COM2 和 COM3

 

 

   c.使用 Serial Port Utility 測試串口的收發

 

 

  d.注意:vspd 添加的虛擬串口為 COM2 和 COM3,Java代碼中連接的是 COM2,則 Serial Port Utility 需連接 COM3。 

 

 

4.參考文章

  https://www.jianshu.com/p/7c03ad8a6139


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM