java基于RXTXcomm的串口程序

准备工作

  • 首先下载官方提供的jar包和.dll文件,dll文件有两个,一个是rxtxSerial,一个是rxtxParallel,分别表示串口和并口。
  • 因为我开发串口,所以把rxtxSerial.dll放到了jdk1.8.0_171/jre/bin和jre1.8.0_171/bin目录下,官方说两个都放,我没有去验证只放其中一个有没有差别。直接按照官方的直接放了。
  • 接下来将jar包放入工程目录下的lib文件夹,并引用。

PS:在程序开发之前,强烈建议用测试工具测试设备是否已经可用。

程序包括的部分

  • 初始化对象以及设置监听的函数 init()
  • 监听消息的函数 serialEvent()(该函数来自实现的接口SerialPortEventListener)
  • 消息发送函数 send()
  • 消息接收的函数 receive()
  • 关闭函数 close()
  • 因为消息是16进制字符串,所以还有16进制字符串转byte数组以及byte数组转字符串函数
    (这两个函数随便网上copy的,不是我自己写的,只修改了一句)

程序参数

  • PORT_NAME = “COM3”,这个参数的参数值看的是设备连接上后的设备管理器端口部分查看端口
  • BIT_RATE = 9600;
    DATA_BITS = SerialPort.DATABITS_8;
    STOP_BIT = SerialPort.STOPBITS_1;
    PARITY_BIT = SerialPort.PARITY_NONE;
    这四个参数分别表示设备的比特率,数据位,停止位,和校验位,在设备使用说明上提供了。
  • serialPort,这个参数用来设置串口的参数
  • InputStream in;OutputStream out;这两个参数分别用来读写数据

代码部分

init函数,init函数部分基本参照官网代码,只是稍作修改。
整个过程

  • 根据端口名称获取端口对象
  • 判断对象是否被占用
  • 判断端口类型,其中1代表串口,如果是串口就打开串口,设置设备参数,设置输入输出流,以及设置数据监听
public void init(){
        try {
            CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(PORT_NAME);
            if (portIdentifier.isCurrentlyOwned()){
                System.out.println("Error: Port is currently in use");
            }else if(portIdentifier.getPortType()==1){
                serialPort = (SerialPort) portIdentifier.open(PORT_NAME,1000);
                serialPort.setSerialPortParams(BIT_RATE,DATA_BITS,STOP_BIT,PARITY_BIT);

                in = serialPort.getInputStream();
                out = serialPort.getOutputStream();

                serialPort.addEventListener(this);
                serialPort.notifyOnDataAvailable(true);
            }else{
                System.out.println("Error: Only serial ports are handled by this example.");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

serialEvent函数,大概就是用来监听事件,他包括很多事件,但是我只判断一个,是否有是可用数据,如果存在可用数据就接收。

public void serialEvent(SerialPortEvent event) {
        switch (event.getEventType()){
            case SerialPortEvent.DATA_AVAILABLE:
                receive();
                break;
        }
    }

receive函数,用来接收收到的数据,这里比较好理解,通过上面初始化的输入流,将获取到的数据存入byte数组,并且将其转成字符串返回。

public String receive(){
        byte[] buffer = new byte[128];
        int data;
        String result = null;
        try{
            int len = 0;
            while ( ( data = in.read()) > -1 ){
                buffer[len++] = (byte) data;
            }
            byte[] copyValue = new byte[len];
            System.arraycopy(buffer,0,copyValue,0,len);
            result = ByteArrayToString(copyValue);
        }catch ( IOException e ){
            e.printStackTrace();
        }
        return result;
    }

send函数,send函数将要发送的16进制字符串消息转换成byte数组发送,并且让线程休眠1秒。

public void send(String message){
        try {
            byte[] bytes = hexStrToByteArray(message);
            out.write(bytes);
            Thread.sleep(1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

官网还有其他地方的收发数据都用到了线程,但是在写的过程中发现并没有使用线程的必要,所以我去掉了线程这个部分。如果发送的数据不是类似我的16进制字符串,完全可以去掉那两个转换代码,所以看情况适当修改。但是我对于这个代码,还是感觉没有很完美,没啥信心。希望有大佬能看看顺便指正一下。

整个代码

/**
 * @author:ms.y
 * @create 2019/1/24-8:48
 */
public class CommUtil implements SerialPortEventListener{

    private static final String PORT_NAME = "COM3";
    private static final int BIT_RATE = 9600;
    public static final int DATA_BITS = SerialPort.DATABITS_8;
    public static final int STOP_BIT = SerialPort.STOPBITS_1;
    public static final int PARITY_BIT = SerialPort.PARITY_NONE;

    private static SerialPort serialPort;
    private static InputStream in;
    private static OutputStream out;
    private static CommUtil commUtil;

    private CommUtil(){}

    public static CommUtil getInstance(){
        if(commUtil==null){
            commUtil = new CommUtil();
            commUtil.init();
        }
        return commUtil;
    }

    public void init(){
        try {
            CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(PORT_NAME);
            if (portIdentifier.isCurrentlyOwned()){
                System.out.println("Error: Port is currently in use");
            }else if(portIdentifier.getPortType()==1){
                serialPort = (SerialPort) portIdentifier.open(PORT_NAME,1000);
                serialPort.setSerialPortParams(BIT_RATE,DATA_BITS,STOP_BIT,PARITY_BIT);

                in = serialPort.getInputStream();
                out = serialPort.getOutputStream();

                serialPort.addEventListener(this);
                serialPort.notifyOnDataAvailable(true);
            }else{
                System.out.println("Error: Only serial ports are handled by this example.");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void send(String message){
        try {
            byte[] bytes = hexStrToByteArray(message);
            out.write(bytes);
            Thread.sleep(1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void serialEvent(SerialPortEvent event) {
        switch (event.getEventType()){
            case SerialPortEvent.DATA_AVAILABLE:
                receive();
                break;
        }
    }

    public String receive(){
        byte[] buffer = new byte[128];
        int data;
        String result = null;
        try{
            int len = 0;
            while ( ( data = in.read()) > -1 ){
                buffer[len++] = (byte) data;
            }
            byte[] copyValue = new byte[len];
            System.arraycopy(buffer,0,copyValue,0,len);
            result = ByteArrayToString(copyValue);
        }catch ( IOException e ){
            e.printStackTrace();
        }
        return result;
    }

    public void close(){
        try {
            in.close();
            out.close();
            serialPort.notifyOnDataAvailable(false);
            serialPort.removeEventListener();
            serialPort.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //16进制转byte数组
    public byte[] hexStrToByteArray(String str) {
        if (str == null) {
            return null;
        }
        if (str.length() == 0) {
            return new byte[0];
        }
        byte[] byteArray = new byte[str.length() / 2];
        for (int i = 0; i < byteArray.length; i++) {
            String subStr = str.substring(2 * i, 2 * i + 2);
            byteArray[i] = ((byte) Integer.parseInt(subStr, 16));
        }
        return byteArray;
    }

    public String ByteArrayToString(byte[] by) {
        String str = "";
        for (int i = 0; i < by.length; i++) {
            String hex = Integer.toHexString(by[i] & 0xFF);
            if (hex.length() == 1) {
                hex = "0" + hex;
            }
            str += hex.toUpperCase();
        }
        return str;
    }

    public static void main ( String[] args ){
        CommUtil commUtil = CommUtil.getInstance();
        commUtil.send("8101060108080302FF");
        commUtil.send("8101060108080301FF");
    }
}

你可能感兴趣的:(实验)