Java利用Rxtx进行串口通讯
最近在做传感器数据采集的工作,底层是基于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进行串口通讯的更多相关文章
- ProtocolBuffers (二) android与PC,C#与Java 利用protobuf 进行无障碍通讯【Socket】
protobuf 是什么? Protocol buffers是一种编码方法构造的一种有效而可扩展的格式的数据. 谷歌使用其内部几乎RPC协议和文件格式的所有协议缓冲区. 参考文档 http://c ...
- 基于RXTX的串口通讯 windows64位系统可用
项目地址 http://download.csdn.net/detail/xqshishen/7739539
- java web下串口通讯
最近在做java串口通讯,主要是用个人电脑通过串口从RS485读取数据,并通过crc循环冗余校验,把接收正确的数据解析,插入数据库mysql,并用SSH技术把数据库数据以表格以及图表形式显示 ...
- 简单的Java串口通讯应答示例
java串口通讯第一次使用,找的资料都比较麻烦,一时没有理出头绪,自己在示例的基础上整理了一个简单的应答示例,比较简陋,但演示了java串口通讯的基本过程. package com.garfield. ...
- Android串口通讯
今天在整一个项目,需要利用串口通讯在网上看了好多人的帖子才稍微整出了一点头绪. 首先串口代码就是利用谷歌自己的api,将java代码放在java/android_serialport_api目录下,如 ...
- 用SPCOMM 在 Delphi中实现串口通讯 转
用Delphi 实现串口通讯,常用的几种方法为:使用控件如MSCOMM和SPCOMM,使用API函数或者在Delphi 中调用其它串口通讯程序.利用API编写串口通信程序较为复杂,需要掌握大量通信 ...
- 教程-Delphi MSComm 实时串口通讯
Delphi MSComm 实时串口通讯 MSComm控件具有丰富的与串口通信密切相关的属性,提供了对串口进行的多种操作,进而使串行通信变得十分简便.MSComm的控件属性较多,常用的属性如下:1) ...
- STM32F10x 学习笔记6(USART实现串口通讯 2)
这次讲讲利用串口收发中断来进行串口通讯.STM32 上为每个串口分配了一个中断.也就是说无论是发送完成还是收到数据或是数据溢出都产生同一个中断.程序需在中断处理函数中读取状态寄存器(USART_SR) ...
- 使用Xamarin实现串口通讯
前几天我写了年度总结,然后有人说让我教一下他Xamarin串口通讯怎么做,其实跟java没有多大区别. 记得我刚开始接到公司这个项目的时候很懵逼,我去看了别的安卓串口工具,都不行我当时是RS232串口 ...
随机推荐
- C++11中int,float,double与string的转化
在C++11中可以使用std::to_string()函数将数值转换为string格式,十分方便. 以下部分来选自cplusplus.com. std::to_string string to_str ...
- 如何写angularJS模块
angularJS中提供模块的概念,供我们把代码封装在模块单元中,使用模块能给我们带来的好处 保持全局命名空间的清洁 易于在不同应用间复用代码 demo.html <!doctype html& ...
- css 日常
去掉input边框 outline:none; 不让用户选择文本 user-select: none; 手机网页点击输入框的瞬间会出现灰色背景 解决方案: -webkit-tap-high ...
- python -- 函数传参
一.参数传入规则 可变参数允许传入0个或任意个参数,在函数调用时自动组装成一个tuple: 关键字参数允许传入0个或任意个参数,在函数调用时自动组装成一个dict: 1. 传入可变参数: def ca ...
- 如何搭建MVC3与配置models层
1.1 新建项目 第一步:打开Vs2010界面,点击左上角文件,点击新建,选择项目 1.1(图1) 第二步:点击网站Web类型,选择ASP.net MVC3 Web应用程序,在名称中输入项目名称(解决 ...
- 关于cmd的东西
为了督促自己,就从简单的开始学起,希望用博客来纪念我的成长 1)输入 CMD 回车.进入DOS提示符状态下.输入cd\ 回车 表示进入 c:\> 也到了C盘根目录下 2)d: 回车 是进入D盘当 ...
- Html Meta 标签详解
http://www.dreamdu.com/xhtml/tag_meta/
- CSS中定位position
毋庸置疑的是,pisition是css中是最重要的属性之一. 一共有四种定位方式,static.relative.absolute.fixed. 默认的定位方式static 页面中所有的元素默认都是s ...
- Windows8.1 preview硬盘安装(图解)
本人小本系统是win7 32位的,想要装win8 64位 ,想直接镜像安装不可能,因为位数不同.U盘只有2G ,显然也放不下3.6G的win8系统.借助NT6 HDD Installer,可以在本地硬 ...
- Delphi TcxtreeList控件说明 转
Delphi TcxtreeList控件说明 树.cxTreeList 属性: Align:布局,靠左,靠右,居中等 AlignWithMargins:带边框的布局 Anchors:停靠 (akT ...