RXTX串口通信 java

最近项目需要往串口里写消息  翻了翻资料 整理下

 windows系统下:

1.需要文件 rxtxSerial.dll ,RXTXcomm.jar

2.dll文件放入到JDK安装路径下的bin文件夹

  例:C:\Program Files\Java\jdk1.7.0_17\jre\bin

  最好在jre里面也放一份

  例:C:\Program Files\Java\jre7\bin

 RXTXcomm.jar:——>导入到项目中 ——>添加引用——>右键项目——>Build Path——>Configure Build Path——>Libraries——>找到RXTXcomm.jar展开——>双击Native library location:(None)——>单击External Folder——>指向放入rxtxSerial.dll的bin文件夹

  例:C:/Program Files/Java/jre7/bin

3.java代码

SerialReader 类
import gnu.io.*;

import java.io.*; 
import java.util.*;  

@SuppressWarnings("rawtypes")
public class SerialReader extends Observable implements Runnable,SerialPortEventListener{
    static CommPortIdentifier portId;
    int delayRead = 100;
    int numBytes; // buffer中的实际数据字节数
    private static byte[] readBuffer = new byte[1024]; //缓存串口读入的数据
    static Enumeration portList;
    InputStream inputStream;
    OutputStream outputStream;
    static SerialPort serialPort;
    HashMap serialParams;
    Thread readThread;//端口是否打开了
    boolean isOpen = false;
    // 端口读入数据事件触发后,等待n毫秒后再读取,以便让数据一次性读完
    public static final String PARAMS_DELAY = "delay read"; // 延时等待端口数据准备的时间
    public static final String PARAMS_TIMEOUT = "timeout"; // 超时时间
    public static final String PARAMS_PORT = "port name"; // 端口名称
    public static final String PARAMS_DATABITS = "data bits"; // 数据位
    public static final String PARAMS_STOPBITS = "stop bits"; // 停止位
    public static final String PARAMS_PARITY = "parity"; // 奇偶校验
    public static final String PARAMS_RATE = "rate"; // 波特率

    public boolean isOpen(){
        return isOpen;
    }
    /**
     * 初始化端口操作的参数.
     * @throws SerialPortException 
     * 
     * @see
     */
    public SerialReader(){
        isOpen = false;
    }

    public void open(HashMap params){ 
        serialParams = params;
        if(isOpen){
            close();
        }
        try{
            // 参数初始化
            int timeout = Integer.parseInt( serialParams.get( PARAMS_TIMEOUT )
                .toString() );
            int rate = Integer.parseInt( serialParams.get( PARAMS_RATE )
                .toString() );
            int dataBits = Integer.parseInt( serialParams.get( PARAMS_DATABITS )
                .toString() );
            int stopBits = Integer.parseInt( serialParams.get( PARAMS_STOPBITS )
                .toString() );
            int parity = Integer.parseInt( serialParams.get( PARAMS_PARITY )
                .toString() );
            delayRead = Integer.parseInt( serialParams.get( PARAMS_DELAY )
                .toString() );
            String port = serialParams.get( PARAMS_PORT ).toString();
            // 打开端口
            portId = CommPortIdentifier.getPortIdentifier( port );
            serialPort = ( SerialPort ) portId.open( "SerialReader", timeout );
            inputStream = serialPort.getInputStream();
            serialPort.addEventListener( this );
            serialPort.notifyOnDataAvailable( true );
            serialPort.setSerialPortParams( rate, dataBits, stopBits, parity );
            
            isOpen = true;
        }
        catch ( PortInUseException e ){
           System.out.println("端口"+serialParams.get( PARAMS_PORT ).toString()+"已经被占用"+e);
        }
        catch ( TooManyListenersException e ){
           System.out.println("端口"+serialParams.get( PARAMS_PORT ).toString()+"监听者过多"+e);
        }
        catch ( UnsupportedCommOperationException e ){
           System.out.println("端口操作命令不支持"+e);
        }
        catch ( NoSuchPortException e ){
          System.out.println("端口"+serialParams.get( PARAMS_PORT ).toString()+"不存在"+e);
        }
        catch ( IOException e ){
           System.out.println("打开端口"+serialParams.get( PARAMS_PORT ).toString()+"失败"+e);
        }
        serialParams.clear();
        Thread readThread = new Thread( this );
        readThread.start();
    }

     
    public void run(){
        try{
            Thread.sleep(50);
        }
        catch ( InterruptedException e ){
            e.printStackTrace();
        }
    } 
    public void start(){
         try {  
          outputStream = serialPort.getOutputStream();
            } 
       catch (IOException e) {
           e.printStackTrace();
       }
       try{ 
           readThread = new Thread(this);
         readThread.start();
       } 
       catch (Exception e) {  
           e.printStackTrace();
       }
   }  //start() end


   public void run(String message) {
       try { 
           Thread.sleep(4); 
           } 
        catch (InterruptedException e) { 
            e.printStackTrace();
        } 
        try {
            if(message!=null&&message.length()!=0)
            {      
               System.out.println("发送数据:"+message);
               outputStream.write(message.getBytes()); //往串口发送数据,是双向通讯的。
            }
       } catch (IOException e) {
           e.printStackTrace();
       }
   } 
    

    public void close(){ 
        if (isOpen){
            try{
                serialPort.notifyOnDataAvailable(false);
                serialPort.removeEventListener();
                inputStream.close();
                serialPort.close();
                isOpen = false;
            } catch (IOException ex){
                ex.printStackTrace();
                System.out.println("关闭串口失败");
            }
        }
    }
    
    public void serialEvent( SerialPortEvent event ){
        try{
            Thread.sleep( delayRead );
        }
        catch ( InterruptedException e ){
            e.printStackTrace();
        }
        switch ( event.getEventType() ){
            case SerialPortEvent.BI: // 10
            case SerialPortEvent.OE: // 7
            case SerialPortEvent.FE: // 9
            case SerialPortEvent.PE: // 8
            case SerialPortEvent.CD: // 6
            case SerialPortEvent.CTS: // 3
            case SerialPortEvent.DSR: // 4
            case SerialPortEvent.RI: // 5
            case SerialPortEvent.OUTPUT_BUFFER_EMPTY: // 2
                break;
            case SerialPortEvent.DATA_AVAILABLE: // 1
                try{
                    // 多次读取,将所有数据读入
                     while (inputStream.available() > 0) {
                     numBytes = inputStream.read(readBuffer);
                     }
                     
                     //打印接收到的字节数据的ASCII码
                     for(int i=0;i<numBytes;i++){
                        // System.out.println("msg[" + numBytes + "]: [" +readBuffer[i] + "]:"+(char)readBuffer[i]);
                     }
//                    numBytes = inputStream.read( readBuffer );
                    changeMessage( readBuffer, numBytes );
                }
                catch ( IOException e ){
                    e.printStackTrace();
                }
                break;
        }
    }

    // 通过observer pattern将收到的数据发送给observer
    // 将buffer中的空字节删除后再发送更新消息,通知观察者
    public void changeMessage( byte[] message, int length ){
        setChanged();
        byte[] temp = new byte[length];
        System.arraycopy( message, 0, temp, 0, length );
        notifyObservers( temp );
    }
    
    public void openSerialPort(String message){
        HashMap<String, Comparable> params = new HashMap<String, Comparable>();  
        String port="COM1";
        String rate = "9600";
        String dataBit = ""+SerialPort.DATABITS_8;
        String stopBit = ""+SerialPort.STOPBITS_1;
        int parityInt = SerialPort.PARITY_NONE; 
        params.put( SerialReader.PARAMS_PORT, port ); // 端口名称
        params.put( SerialReader.PARAMS_RATE, rate ); // 波特率
        params.put( SerialReader.PARAMS_DATABITS,dataBit  ); // 数据位
        params.put( SerialReader.PARAMS_STOPBITS, stopBit ); // 停止位
        params.put( SerialReader.PARAMS_PARITY, parityInt ); // 无奇偶校验
        params.put( SerialReader.PARAMS_TIMEOUT, 100 ); // 设备超时时间 1秒
        params.put( SerialReader.PARAMS_DELAY, 100 ); // 端口数据准备时间 1秒
        try {
            open(params);//打开串口
            //LoginFrame cf=new LoginFrame();
            //addObserver(cf);
            //也可以像上面一个通过LoginFrame来绑定串口的通讯输出.
            if(message!=null&&message.length()!=0)
             {
                String str="";
                for(int i=0;i<10;i++)
                {
                    str+=message;
                }
                 start(); 
                 run(str);  
             } 
        } catch (Exception e) { 
            e.printStackTrace();
        }
    }
}

SerialInit 类

import gnu.io.SerialPort;

import java.util.*;

@SuppressWarnings("rawtypes")
public class SerialInit implements Observer{ 
     
    public SerialReader sr=new SerialReader(); 
    public void test(){    
        openSerialPort(""); //打开串口
    } 
    public void update(Observable o, Object arg){    
        String mt=new String((byte[])arg);  
        System.out.println("接收数据:"+mt); //串口数据 
    } 
    /**
     * 打开串口
     * @param String message
     */
    public void openSerialPort(String message){ 
        HashMap<String, Comparable> params = new HashMap<String, Comparable>();  
        String port="COM1";
        String rate = "9600";
        String dataBit = ""+SerialPort.DATABITS_8;
        String stopBit = ""+SerialPort.STOPBITS_1;
        int parityInt = SerialPort.PARITY_NONE; 
        params.put( SerialReader.PARAMS_PORT, port ); // 端口名称
        params.put( SerialReader.PARAMS_RATE, rate ); // 波特率
        params.put( SerialReader.PARAMS_DATABITS,dataBit  ); // 数据位
        params.put( SerialReader.PARAMS_STOPBITS, stopBit ); // 停止位
        params.put( SerialReader.PARAMS_PARITY, parityInt ); // 无奇偶校验
        params.put( SerialReader.PARAMS_TIMEOUT,100 ); // 设备超时时间 1秒
        params.put( SerialReader.PARAMS_DELAY, 100 ); // 端口数据准备时间 1秒
        try {
            sr.open(params);
            sr.addObserver(this);
            sr.start();
            sr.run();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
} 
 

测试类

public class Main {
    public static void main(String[] args) {
        SerialInit te=new SerialInit();
        te.test();
        te.sr.run("hello word!\n");
        te.sr.run("你好!");
    }
}

 

posted @ 2016-03-22 15:22  落花成殇  阅读(1161)  评论(2编辑  收藏  举报