java下的串口通信-RXTX

关于java实现的串口通信,使用的是开源项目RXTX,之前sun公司也有JCL项目,不过已经很久没有更新了,RXTX项目地址:点击打开,但是两个项目的API用法是一样的,只是导入的包不一样而已。简单的入门可以参照官方的wiki

对应你的开发环境(Linux、window、Mac)下载对应的文件(下载地址),这里说下具体的安装方法,官方给的有点啰嗦,在Eclipse下使用,下载后里面的文件:

RXTXcomm.jar包放到你项目的lib文件夹下,Java Builder Path---->Add to builder path,然后对应系统环境选择文件:

将两个文件直接拷贝到项目的根目录下:

问题1

注意,我安装的时候出现了“VM warning: You have loaded library /****/***/***/librxtxSerial.so which might have disabled stack guard. The VM will try to fix the stack guard now.
It‘s highly recommended that you fix the library with ‘execstack -c <libfile>‘, or link it with ‘-z noexecstack‘.”

google很久没有解决办法,所以按照给出的提示信息,sudo apt-get install execstack,安装了execstack后,在librxtxSerial所在的文件夹,打开终端,按照提少的要求execstack -c librxtxSerial.so即可解决。

问题2

找不到设备,这是权限问题,你应该在终端下用sudo命令启动Eclipse

关于使用:

建议你参考这两篇博客:使用comm在java程序中管理本地端口Java串口通讯,两篇讲的是一些基础知识依据API的基本用法,当然如果你依据很熟悉,那么你可以直接写写代码运行下,比如扫描当前的设备端口:

   public static void listPorts()
    {
        java.util.Enumeration<CommPortIdentifier> portEnum = CommPortIdentifier.getPortIdentifiers();
        while ( portEnum.hasMoreElements() )
        {
            CommPortIdentifier portIdentifier = portEnum.nextElement();
            System.out.println(portIdentifier.getName()  +  " - " +  getPortTypeName(portIdentifier.getPortType()) );
        }
    }

   public static String getPortTypeName ( int portType )
    {
        switch ( portType )
        {
            case CommPortIdentifier.PORT_I2C:
                return "I2C";
            case CommPortIdentifier.PORT_PARALLEL:
                return "Parallel";
            case CommPortIdentifier.PORT_RAW:
                return "Raw";
            case CommPortIdentifier.PORT_RS485:
                return "RS485";
            case CommPortIdentifier.PORT_SERIAL:
                return "Serial";
            default:
                return "unknown type";
        }
    }

串口通信,有两种方式,两篇博客说的很详细了,你也可以参考wiki的例子了解其通信流程,我仿照官方写的例子,部分有改动,SerialRXTX.java:

package nir.desktop.demo;

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

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.HashSet;

public class SerialRXTX {
    /**
     * This code snippet shows how to retrieve the available comms ports on your
     * computer. A CommPort is available if it is not being used by another
     * application.
     */
    public static void listAvailablePorts() {
        HashSet<CommPortIdentifier> portSet = getAvailableSerialPorts();
        String[] serialPort = new String[portSet.size()];
        int i = 0;
        for (CommPortIdentifier comm : portSet) {
            serialPort[i] = comm.getName();
            System.out.println(serialPort[i]);
            i++;
        }
    }

    public static String getPortTypeName(int portType) {
        switch (portType) {
        case CommPortIdentifier.PORT_I2C:
            return "I2C";
        case CommPortIdentifier.PORT_PARALLEL:
            return "Parallel";
        case CommPortIdentifier.PORT_RAW:
            return "Raw";
        case CommPortIdentifier.PORT_RS485:
            return "RS485";
        case CommPortIdentifier.PORT_SERIAL:
            return "Serial";
        default:
            return "unknown type";
        }
    }

    /**
     * @return A HashSet containing the CommPortIdentifier for all serial ports
     *         that are not currently being used.
     */
    public static HashSet<CommPortIdentifier> getAvailableSerialPorts() {
        HashSet<CommPortIdentifier> h = new HashSet<CommPortIdentifier>();
        @SuppressWarnings("rawtypes")
        Enumeration thePorts = CommPortIdentifier.getPortIdentifiers();// 可以找到系统的所有的串口,每个串口对应一个CommPortldentifier
        while (thePorts.hasMoreElements()) {
            CommPortIdentifier com = (CommPortIdentifier) thePorts
                    .nextElement();
            switch (com.getPortType()) {
            case CommPortIdentifier.PORT_SERIAL:// type of the port is serial
                try {
                    CommPort thePort = com.open("CommUtil", 50);// open the serialPort
                    thePort.close();
                    h.add(com);
                } catch (PortInUseException e) {
                    System.out.println("Port, " + com.getName()
                            + ", is in use.");
                } catch (Exception e) {
                    System.err.println("Failed to open port " + com.getName());
                    e.printStackTrace();
                }
            }
        }
        return h;
    }

    public static SerialPort connect(String portName) throws Exception {
        SerialPort serialPort = null;
        CommPortIdentifier portIdentifier = CommPortIdentifier
                .getPortIdentifier(portName);// initializes of port operation
        if (portIdentifier.isCurrentlyOwned()) {
            System.out.println("Error: Port is currently in use");
        } else {
            CommPort commPort = portIdentifier.open(portName, 2000);// the delay
                                                                    // time of
                                                                    // opening
                                                                    // port
            if (commPort instanceof SerialPort) {
                serialPort = (SerialPort) commPort;
                serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8,
                        SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);// serial
                                                                        // communication
                                                                        // parameters
                                                                        // setting
                InputStream inputStream = serialPort.getInputStream();
                // OutputStream outputStream = serialPort.getOutputStream();
                // (new Thread(new SerialWriter(outputStream))).start();
                serialPort.addEventListener(new SerialReader(inputStream));
                serialPort.notifyOnDataAvailable(true);
            }
        }
        return serialPort;

    }

    /**
     * not necessary to send command in new thread, but the serialPort only has
     * one instance
     *
     * @param serialPort
     * @param string
     */
    public static void sendMessage(SerialPort serialPort, String string) {
        try {
            OutputStream outputStream = serialPort.getOutputStream();
            (new Thread(new SerialWriter(outputStream, string))).start();// send
                                                                            // command
                                                                            // in
                                                                            // the
                                                                            // new
                                                                            // thread
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * Handles the input coming from the serial port. A new line character is
     * treated as the end of a block in this example.
     */
    public static class SerialReader implements SerialPortEventListener {
        private InputStream in;

        public SerialReader(InputStream in) {
            this.in = in;
        }

        public void serialEvent(SerialPortEvent arg0) {
            byte[] buffer = new byte[1024];
            try {
                Thread.sleep(500);// the thread need to sleep for completed
                                    // receive the data
                if (in.available() > 0) {
                    in.read(buffer);
                }
                System.out.println(new String(buffer));
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }

    /** */
    public static class SerialWriter implements Runnable {
        OutputStream out;
        String commandString;

        public SerialWriter(OutputStream out, String commandString) {
            this.out = out;
            this.commandString = commandString;
        }

        public void run() {
            while (true) {
                try {
                    Thread.sleep(3000);// an interval of 3 seconds to sending
                                        // data
                    out.write(commandString.getBytes());
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (InterruptedException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        listAvailablePorts();
        try {
            sendMessage(connect("/dev/ttyUSB0"), "P");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

返回的数据:

在监听返回数据的时候,出现的问题是返回的数据不连续,比如:

P

H:05.36

解决的方法是在接受的地方让线程休眠一下,即可解决

Thread.sleep(500);
时间: 2024-10-29 19:09:45

java下的串口通信-RXTX的相关文章

使用Java实现简单串口通信

最近一门课要求编写一个上位机串口通信工具,我基于Java编写了一个带有图形界面的简单串口通信工具,下面详述一下过程,供大家参考 ^_^ 一: 首先,你需要下载一个额外的支持Java串口通信操作的jar包,由于java.comm比较老了,而且不支持64位系统,这里推荐Rxtx这个jar包(32位/64位均支持). 官方下载地址:http://fizzed.com/oss/rxtx-for-java (注:可能需要FQ才能下载) 不能FQ的童鞋,可以在这里下载: http://files.cnblo

Java实现RS485串口通信,发送和接收数据进行解析

最近项目有一个空气检测仪,需要得到空气检测仪的实时数据,保存到数据库当中.根据了解得到,硬件是通过rs485进行串口通讯的,需要发送16进制命令给仪器,然后通过轮询来得到数据. 需要先要下载RXTX的jar包,win64位下载地址:http://pan.baidu.com/s/1o6zLmTc):将解压后的rxtxParallel.dll和rxtxSerial.dll两个文件放在%JAVA_HOME%/jre/bin目录下,这样该包才能被正常的加载和调用. 代码如下: package com.g

Mac下的串口通信

最近在工作中遇到有关Mac下串口通信的问题,一开始直接用以前同事写的framework,基本通信没问题,但是一打开串口,CPU的占用率就直接飙到100%,而且读信息的时候很难判断“\r”换行符,于是打算自己重写串口类. 到网上搜索资料,“Mac+串口”,无果,大部分都转往Linux串口方向.虽然很多人都说mac系统跟linux差不多,但是对于小白,概念还是比较模糊的,无从下手. 无意间找到一篇文章:mac下串口通讯工具的编写 看了一下注释,觉着作者写的类不错,于是乎跑到Github,幸运地找到了

java可用与串口通信的一些库

java原生对串口的支持只有javax.comm,javax.comm比较老了,而且不支持64位系统,我在看jlibmodbus(一个java实现的modbus协议栈)的时候发现了几个可供使用的java操作串口的扩展类库. 1.RXTX 官网:http://fizzed.com/oss/rxtx-for-java 2.jSerialComm 官网:https://fazecast.github.io/jSerialComm/ 3.purejavacomm github:https://githu

linux下的串口通信

 /************声明:本人只是见到这篇文章对我帮助很大才转载的,但是这个完整的程序里面本来有语法错误的,现在让我改过来了************/ 今天的主角àUART0串口.因此对他的一切操作都和文件的操作一样(涉及到了open,read,write,close等文件的基本操作). 一.Linux下的串口编程又那几部分组成 1.    打开串口 2.    串口初始化 3.    读串口或写串口 4.    关闭串口 二.串口的打开 既然串口在linux中被看作了文件,那么在对文件

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_

java 串口通信 rxtx的使用

1.到官网下载压缩文件,以rxtx-2.2pre2为例 http://fizzed.com/oss/rxtx-for-java 2.解压缩后得到文件,将RXTXcomm.jar添加到自己的java工程库里,1.右键->2.buildpath->3.config Build Path->4.libraries->5.add jars. 3.将win32文件夹下的rxtxSerial.dll文件拷贝到C:\WINDOWS\system32.

Linux下串口通信工具minicom

minicom是linux下的串口通信工具,类似于Windows下的超级终端. 一般在yum源中可以直接安装 minicom -s可以设置minicom的速率,流控之类. 如上图:A是你的设备名.如在台式机上用console接串口则一般为/dev/ttyS0, 如果笔记本上使用USB-串口转换则为/dev/ttyUSB0之类. Linux下一般均默认安装了USB-串口的驱动 将配置保存为默认(Save setup as dfl),下次输入minicom则可以启动 注意:非正常关闭minicom,

Linux与Windows串口通信

串口是常用的计算机与外部串行设备之间的数据传输通道,由于串行通信方便易行,所以应用广泛.现在国际上不断有串口新技术及新规格推出,结合社会各方面需要,串口通信发展的空间庞大.串口通讯技术因其自身的优势和特性,及计算机技术的广泛应用深入到生活和生产的各个领域,世界上数以亿计的通讯设备都以串口通讯的方式.在进行着数据的传输.在一个应用系统中,同时使用Windows和Linux操作系统,合理地分配资源,各取所长,是实现系统高性能的有效途径.为了使两个不同操作系统能协同工作,实现资源和数据共享,需要在两者