最近在做传感器数据采集的工作,底层是基于Zigbee的无线传感网络,所有数据采集到Zigbee协调器上然后通知上位机数据采集完成,上位机通过USB转串口去读取数据就可以了。那么问题来了,如何进行串口通讯呢?老板说你用Java写个程序好了嘛,用Java写串口程序也是醉了。实验室也没别人写了,所以就让我写了。当我听到要让我用Java写串口通讯程序的时候我本来是拒绝的,然后。。。就没有然后了。。就只能写了。

网上看了一下,最后用了一个开源的Java串口通讯库RXTX做串口通讯,下面记录一下RXTX的使用方法。

环境配置

RXTX做串口通讯,有一个jar包(RXTXcomm.jar)和一个rxtxSerial.dll(Windows环境下)或者librxtxSerial.so(Linux环境下),因为开发是在Windows上,但是工作是在Linux上,所以两个都用到了。

Windows环境下

文档里是这么写的

Copy rxtxSerial.dll ---> <JAVA_HOME>\jre\bin

但是这个做了之后并不能用,会有一些很奇怪的问题,不知道是不是我的Java环境配置有问题还是怎么了,我是把dll文件copy到了C:\Windows\System32,然后一切正常,一直很奇怪,为什么要cp到<JAVA_HOME>\jre\bin呢?求解答!

Linux环境下

Copy librxtxSerial.so ---> <JAVA_HOME>/jre/lib/i386/

or

Copy librxtxSerial.so ---> <JAVA_HOME>/jre/lib/x86_64/

这个按照文档没问题。

小问题

我用的是rxtx-2.2pre2版本的,文档里有写运行时会报版本不匹配的WARNING,实际使用中的确也是这样的,不过目前还没有别的问题,不影响使用。

常用方法

1.查找端口


/** * 查找所有可用端口 * * @return 所有端口列表 */ public static final ArrayList<String> findPort() { Enumeration<CommPortIdentifier> portList = CommPortIdentifier.getPortIdentifiers();//获得所有串口 ArrayList<String> portNameList = new ArrayList<>(); //串口名字添加到List并返回 while (portList.hasMoreElements()) { String portName = portList.nextElement().getName(); portNameList.add(portName); } return portNameList; }

2.打开端口


/** * 打开串口 * * @param portName 端口名称 * @param baudrate 波特率 * @return 串口对象 */ public static final SerialPort openPort(String portName, int baudrate) { try { //通过端口名识别端口 CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName); //打开端口,并给端口名字和一个timeout CommPort commPort = portIdentifier.open(portName, 2000); //判断是不是串口 if (commPort instanceof SerialPort) { SerialPort serialPort = (SerialPort) commPort; try { //设置一下串口的波特率等参数 serialPort.setSerialPortParams(baudrate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); } catch (UnsupportedCommOperationException e) { LOGGER.error("Set Serialport Parameters failure", e); } System.out.println("Open " + portName + " sucessfully !"); return serialPort; } else { LOGGER.error("This port is not a serialport"); return null; } } catch (NoSuchPortException | PortInUseException e) { LOGGER.error("There is no " + portName + "or it's occupied!", e); return null; } }

3.发送数据


/** * 发送数据 * * @param serialPort 串口对象 * @param order 命令字节 */ public void sendToPort(SerialPort serialPort, byte[] order) { try { OutputStream out = serialPort.getOutputStream(); out.write(order); out.flush(); out.close(); } catch (IOException e) { LOGGER.error("Send to SerialPort failure", e); } }

4.读取数据


/** * 读取数据 * * @return 字节ArrayList */ public byte[] readFromPort(InputStream inStream) { byte[] bytes = null; try { while (true) { //获取buffer里的数据长度 int bufflenth = inStream.available(); if (0 == bufflenth) { break; } bytes = new byte[bufflenth]; inStream.read(bytes); } } catch (IOException e) { LOGGER.error("Read Data Failure", e); } return bytes; }

监听器

1.实现监听器

继承SerialPortEventListener然后重写serialEvent,然后再各个对应case里面写代码就好啦。


public class TestExample implements SerialPortEventListener { @Override public void serialEvent(SerialPortEvent serialPortEvent) { switch (serialPortEvent.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输出缓冲区已清空 case SerialPortEvent.DATA_AVAILABLE: // 1读到可用数据时激活 } } }

2.给串口添加监听器


/** * 添加监听器 * * @param port 串口对象 * @param listener 串口监听器 */ public static void addListener(SerialPort port, SerialPortEventListener listener) { try { // 给串口添加监听器 port.addEventListener(listener); // 设置当有数据到达时唤醒监听接收线程 port.notifyOnDataAvailable(true); port.notifyOnBreakInterrupt(true); System.out.println("Add listeners to " + port.getName() + " sucessfully !"); } catch (TooManyListenersException e) { LOGGER.error("There is too many listeners !", e); } }

TIP

** 一定记得从串口发指令取数据之后加一个延时,等待底层数据传输完成再去buffer里面取,不然很大可能数据包不完整。 **

Java利用Rxtx进行串口通讯的更多相关文章

  1. ProtocolBuffers (二) android与PC,C#与Java 利用protobuf 进行无障碍通讯【Socket】

    protobuf 是什么?   Protocol buffers是一种编码方法构造的一种有效而可扩展的格式的数据. 谷歌使用其内部几乎RPC协议和文件格式的所有协议缓冲区. 参考文档 http://c ...

  2. 基于RXTX的串口通讯 windows64位系统可用

    项目地址 http://download.csdn.net/detail/xqshishen/7739539

  3. java web下串口通讯

       最近在做java串口通讯,主要是用个人电脑通过串口从RS485读取数据,并通过crc循环冗余校验,把接收正确的数据解析,插入数据库mysql,并用SSH技术把数据库数据以表格以及图表形式显示   ...

  4. 简单的Java串口通讯应答示例

    java串口通讯第一次使用,找的资料都比较麻烦,一时没有理出头绪,自己在示例的基础上整理了一个简单的应答示例,比较简陋,但演示了java串口通讯的基本过程. package com.garfield. ...

  5. Android串口通讯

    今天在整一个项目,需要利用串口通讯在网上看了好多人的帖子才稍微整出了一点头绪. 首先串口代码就是利用谷歌自己的api,将java代码放在java/android_serialport_api目录下,如 ...

  6. 用SPCOMM 在 Delphi中实现串口通讯 转

      用Delphi 实现串口通讯,常用的几种方法为:使用控件如MSCOMM和SPCOMM,使用API函数或者在Delphi 中调用其它串口通讯程序.利用API编写串口通信程序较为复杂,需要掌握大量通信 ...

  7. 教程-Delphi MSComm 实时串口通讯

    Delphi  MSComm 实时串口通讯 MSComm控件具有丰富的与串口通信密切相关的属性,提供了对串口进行的多种操作,进而使串行通信变得十分简便.MSComm的控件属性较多,常用的属性如下:1) ...

  8. STM32F10x 学习笔记6(USART实现串口通讯 2)

    这次讲讲利用串口收发中断来进行串口通讯.STM32 上为每个串口分配了一个中断.也就是说无论是发送完成还是收到数据或是数据溢出都产生同一个中断.程序需在中断处理函数中读取状态寄存器(USART_SR) ...

  9. 使用Xamarin实现串口通讯

    前几天我写了年度总结,然后有人说让我教一下他Xamarin串口通讯怎么做,其实跟java没有多大区别. 记得我刚开始接到公司这个项目的时候很懵逼,我去看了别的安卓串口工具,都不行我当时是RS232串口 ...

随机推荐

  1. js学习笔记之:时间(三)

    今天来学习一个简单的时间应用:时间的倒影,如图所示:   主要知识点: 1  获取系统的时间值:2 建立一个div的倒影 div的倒影主要利用css来控制,函数值为:filter:flipv() 步骤 ...

  2. [HttpClient]简单使用GET请求

    package com.jerry.httpclient; import java.io.IOException; import org.apache.http.HttpEntity; import ...

  3. 原生网络请求:同步请求、异步请求、GET请求、POST请求

    1.同步请求可以从因特网请求数据,一旦发送同步请求,程序将停止用户交互,直至服务器返回数据完成,才可以进行下一步操作, 2.异步请求不会阻塞主线程,而会建立一个新的线程来操作,用户发出异步请求后,依然 ...

  4. java中字符输入输出流在输出结果的结尾多一个乱码字符:'?'

    原因以及解决方法: 核心方法如下: public static void main(String[] args) throws Exception{ // TODO Auto-generated me ...

  5. 哎,就硬盘还不是最掉价的,1999的自配主机,VIRTUALBOX里虚拟机,聊以自慰吧。

    安装时注意的问题,要是不测试MYSQL,则CONFIGURE参数和DISABLE-MYSQL,在编译时有提示的. 然后就是LIBTOOL包过老的问题,以及未安装LIBTOOL包的问题. 最后,是运行命 ...

  6. MyEclipse10 中增加svn插件

    http://www.cnblogs.com/bluesky4485/archive/2012/04/23/2467177.html 确实这种方法可行!向牛人学习!

  7. POJ1789 Truck History(prim)

    题目链接. 分析: 最大的敌人果然不是别人,就是她(英语). 每种代表车型的串,他们的distance就是串中不同字符的个数,要求算出所有串的distance's 最小 sum. AC代码如下: #i ...

  8. Ext tabpanel集成第三方charts(echarts、amcharts等)的问题(报getstyle为null的错误)

    最近在做ext集成charts的功能,主要是使用tabpanel,将charts集成到tab中,随便切换tab选项就会报错崩溃. 之前演示的时候也发现了该问题,由于在tab项中有加载svg文件的操作, ...

  9. Matlab:拟合(2)

    非线性最小二乘拟合: 解法一:用命令lsqcurvefit function f = curvefun(x, tdata) f = x() + x()*exp() * tdata); %其中x() = ...

  10. Tomcat启动时报错:java.net.BindException: Permission denied <null>:80 【转载】

    本文转载自: http://blog.sina.com.cn/s/blog_4550f3ca0101g37l.html   问题起因:做负载均衡时需要将Web工程与Wap工程同时部署在一台Suse服务 ...