使用java基于RXTX实现串口通信

由于项目成本的要求,公司准备更改方案,源使用TCP/IP的通不适合新的解决方案,所以开始i研究串口通信,浏览网上许多文章,自己实现了一下简单无界面版的串口通信。

1.RXTX配置和下载

Java串口通信依赖的jar包RXTXcomm.jar
下载地址:http://download.csdn.net/detail/kong_gu_you_lan/9611334

内含32位与64位版本
使用方法:
拷贝 RXTXcomm.jar 到 JAVA_HOME\jre\lib\ext目录中;
拷贝 rxtxSerial.dll 到 JAVA_HOME\jre\bin目录中;
拷贝 rxtxParallel.dll 到 JAVA_HOME\jre\bin目录中;
JAVA_HOME为jdk安装路径

2.实例代码

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Date;
import java.util.Enumeration;
import java.util.TooManyListenersException;

import gnu.io.CommPortIdentifier;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import gnu.io.UnsupportedCommOperationException;

public class WS implements SerialPortEventListener {
    // 检测系统中可用的通讯端口类
    private CommPortIdentifier portId;
    // 枚举类型
    private Enumeration portList;

    // RS232串口
    private SerialPort serialPort;

    // 输入输出流
    private InputStream inputStream;
    private OutputStream outputStream;

    // 保存串口返回信息
    private String test = "";

    // 单例创建
    private static WS uniqueInstance = new WS();

    // 初始化串口
    @SuppressWarnings("unchecked")
    public void init() {
        // 获取系统中所有的通讯端口
        portList = CommPortIdentifier.getPortIdentifiers();
        // 循环通讯端口
        while (portList.hasMoreElements()) {
            portId = portList.nextElement();
            // 判断是否是串口
            if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
                    // 打开串口
                    try {
                        //直接使用获取到的串口名,建立通信,并延时
                        serialPort = (SerialPort) portId.open(portId.getName(), 2000);
                        System.out.println("获取到串口对象"+portId.getName());
                        // 设置串口监听
                        serialPort.addEventListener(this);
                        // 设置串口数据时间有效(可监听)
                        serialPort.notifyOnDataAvailable(true);
                        // 设置串口通讯参数
                        // 波特率,数据位,停止位和校验方式
                        // 波特率9600,这里波特率应该设置为可选或者手动输入的模式,有待改进,偶校验
                        serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8,//
                                SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
                        try {
                            Thread.sleep(500);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        test = "";
                        outputStream = serialPort.getOutputStream();

                    } catch (PortInUseException e) {
                        e.printStackTrace();
                    } catch (TooManyListenersException e) {
                        e.printStackTrace();
                    } catch (UnsupportedCommOperationException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }
            }
        }

    // 实现接口SerialPortEventListener中的方法 读取从串口中接收的数据
    @Override
    public void serialEvent(SerialPortEvent event) {
        switch (event.getEventType()) {
        //一下为可选的时间,可用可不用
        /*case SerialPortEvent.BI:    //通讯中断
        case SerialPortEvent.OE:    //溢位错误
        case SerialPortEvent.FE:    //帧错误
        case SerialPortEvent.PE:    //奇偶校验错误
        case SerialPortEvent.CD:    //载波检测
        case SerialPortEvent.CTS:    //清除发送
        case SerialPortEvent.DSR:    //数据设备准备好
        case SerialPortEvent.RI:    //响铃侦测*/
        case SerialPortEvent.OUTPUT_BUFFER_EMPTY:    //输出缓冲区已清空
            break;
        case SerialPortEvent.DATA_AVAILABLE:    //有数据到达
            readComm();
            break;
        default:
            break;
        }
    }

    // 读取串口返回信息
    public void readComm() {
        byte[] bytes = new byte[1024];
        float weight=0;
        float w_pi=0;
        float w_mao=0;
        byte[] weight_pi=new byte[1024];
        byte[] weight_mao=new byte[1024];
        try {
            InputStream inputweight=serialPort.getInputStream();  //从串口输入流中读取数据
            BufferedReader buff=new BufferedReader(new InputStreamReader(inputweight,"UTF-8"));  
            // 设备数据读取后的处理方法,可删除
            int len = 0;
            while ((len = inputweight.read(bytes)) != 0) {
                int num2=0;
                for(int num1=4;num1<=9;num1++)
                {
                    weight_mao[num2]=bytes[num1];
                    num2++;
                }
                int num3=0;
                w_mao=Float.parseFloat(new String(weight_mao, "UTF-8"));
                
                for(int num1=10;num1<=15;num1++)
                {
                    weight_pi[num3]=bytes[num1];
                    num3++;
                }
                w_pi=Float.parseFloat(new String(weight_pi, "UTF-8"));
                try{
                    weight=w_mao-w_pi;
                }catch(NumberFormatException e){
                     e.printStackTrace();
                }
                System.out.println("weight="+weight);
                
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 关闭串口
    public void closeSerialPort() {
        if (serialPort != null) {
            serialPort.notifyOnDataAvailable(false);
            serialPort.removeEventListener();
            if (inputStream != null) {
                try {
                    inputStream.close();
                    inputStream = null;
                }
                catch (IOException e) {}
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                    outputStream = null;
                }
                catch (IOException e) {}
            }
            serialPort.close();
            serialPort = null;
        }
    }

    public static void main(String[] args) {
        WS sp = new WS();
        sp.init();
        sp.readComm();
        sp.closeSerialPort();
    }
}

读取数据后回合实际数据不符合,更改了延时时间,发现准确率变高,所以初步认为是时延的问题,以后还需测试。

数据不准,有跳变,会在以后的生产产生问题,所以要完全排除。

你可能感兴趣的:(java开发)