Java串口通信--------基于RXTX (附带资源地址)
最近帮老师做了一个小项目,一个牧场公司想用传感器收集一些环境信息,记录到数据库里去,然后加以分析查看。这里面和传感器通信用到了串口通信,我也是接触了一下,把用到的东西分享出来。
准备工作:
RXTX:封装了Java对串口操作的类库,具体的话大家自己百度一下吧。 资源地址:http://pan.baidu.com/s/1nuLZex7 密码 m358
VSPD(Virtual Serial Port Driver):可以建立两个虚拟的串口,我们用这两个虚拟串口模拟测试。 资源地址:http://pan.baidu.com/s/1dEQtfPn 密码 nhnc
串口调试助手:可以模拟两个串口之间的通信,作为我们的测试环境。 资源地址 :http://pan.baidu.com/s/1hs0eNxM 密码 009k
下载RXTX资源,解压压缩包,里面应该有三个文件,两个dll文件,一个jar文件,三个文件都拷贝到你项目的lib目录,build path。然后在你项目的configure build path里面 找到Native library location,edit 把目录定位到你存放之前那两个dll文件的文件夹,也就是lib文件夹。 ok,如下图,准备工作完毕。

具体代码:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.Properties;
import java.util.TooManyListenersException; import org.springframework.beans.factory.annotation.Autowired; import com.dodo.detection.service.Services; import gnu.io.CommPortIdentifier;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener; public class ReadSerialPort implements Runnable, SerialPortEventListener { private String appName = "dodo传感器测试";
private int timeout = 2000;//open 端口时的等待时间
private int threadTime = 0;
private String sport;
private CommPortIdentifier commPort;
private SerialPort serialPort;
private InputStream inputStream;
private OutputStream outputStream; private Services service; @Autowired
public void setService(Services service) {
this.service = service;
}
/**
* @方法名称 :listPort
* @功能描述 :列出所有可用的串口
* @返回值类型 :void
*/
@SuppressWarnings("rawtypes")
public void listPort(){
CommPortIdentifier cpid;
Enumeration en = CommPortIdentifier.getPortIdentifiers(); System.out.println("now to list all Port of this PC:" +en); while(en.hasMoreElements()){
cpid = (CommPortIdentifier)en.nextElement();
if(cpid.getPortType() == CommPortIdentifier.PORT_SERIAL){
System.out.println(cpid.getName() + ", " + cpid.getCurrentOwner());
}
}
} public ReadSerialPort() {
} /**
* @方法名称 :selectPort
* @功能描述 :选择一个端口,比如:COM1
* @返回值类型 :void
* @param portName
*/
@SuppressWarnings("rawtypes")
public void selectPort(String portName){ this.commPort = null;
CommPortIdentifier cpid;
Enumeration en = CommPortIdentifier.getPortIdentifiers(); while(en.hasMoreElements()){
cpid = (CommPortIdentifier)en.nextElement();
if(cpid.getPortType() == CommPortIdentifier.PORT_SERIAL
&& cpid.getName().equals(portName)){
this.commPort = cpid;
break;
}
} openPort();
} /**
* @方法名称 :openPort
* @功能描述 :打开SerialPort
* @返回值类型 :void
*/
private void openPort(){
if(commPort == null)
log(String.format("无法找到名字为'%1$s'的串口!", commPort.getName()));
else{
log("端口选择成功,当前端口:"+commPort.getName()+",现在实例化 SerialPort:"); try{
serialPort = (SerialPort)commPort.open(appName, timeout);
log("实例 SerialPort 成功!");
}catch(PortInUseException e){
throw new RuntimeException(String.format("端口'%1$s'正在使用中!",
commPort.getName()));
}
}
} /**
* @方法名称 :checkPort
* @功能描述 :检查端口是否正确连接
* @返回值类型 :void
*/
private void checkPort(){
if(commPort == null)
throw new RuntimeException("没有选择端口,请使用 " +
"selectPort(String portName) 方法选择端口"); if(serialPort == null){
throw new RuntimeException("SerialPort 对象无效!");
}
} /**
* @方法名称 :write
* @功能描述 :向端口发送数据,请在调用此方法前 先选择端口,并确定SerialPort正常打开!
* @返回值类型 :void
* @param message
*/
public void write(String message) {
checkPort(); try{
outputStream = new BufferedOutputStream(serialPort.getOutputStream());
}catch(IOException e){
throw new RuntimeException("获取端口的OutputStream出错:"+e.getMessage());
} try{
outputStream.write(message.getBytes());
log("信息发送成功!");
}catch(IOException e){
throw new RuntimeException("向端口发送信息时出错:"+e.getMessage());
}finally{
try{
outputStream.close();
}catch(Exception e){
}
}
} /**
* @方法名称 :startRead
* @功能描述 :开始监听从端口中接收的数据
* @返回值类型 :void
* @param time 监听程序的存活时间,单位为秒,0 则是一直监听
*/
public void startRead(int time){
checkPort(); try{
inputStream = new BufferedInputStream(serialPort.getInputStream());
}catch(IOException e){
throw new RuntimeException("获取端口的InputStream出错:"+e.getMessage());
} try{
serialPort.addEventListener(this);
}catch(TooManyListenersException e){
throw new RuntimeException(e.getMessage());
} serialPort.notifyOnDataAvailable(true); log(String.format("开始监听来自'%1$s'的数据--------------", commPort.getName()));
if(time > 0){
this.threadTime = time*1000;
Thread t = new Thread(this);
t.start();
log(String.format("监听程序将在%1$d秒后关闭。。。。", threadTime));
}
}
public void startRead(){
checkPort(); try{
inputStream = new BufferedInputStream(serialPort.getInputStream());
}catch(IOException e){
throw new RuntimeException("获取端口的InputStream出错:"+e.getMessage());
} try{
serialPort.addEventListener(this);
}catch(TooManyListenersException e){
throw new RuntimeException(e.getMessage());
} serialPort.notifyOnDataAvailable(true); log(String.format("开始监听来自'%1$s'的数据--------------", commPort.getName())); } /**
* @方法名称 :close
* @功能描述 :关闭 SerialPort
* @返回值类型 :void
*/
public void close(){
serialPort.close();
serialPort = null;
commPort = null;
} public void log(String msg){
System.out.println(appName+" --> "+msg);
} /**
* 数据接收的监听处理函数
*/
@Override
public void serialEvent(SerialPortEvent arg0) {
switch(arg0.getEventType()){
case SerialPortEvent.BI:/*Break interrupt,通讯中断*/
case SerialPortEvent.OE:/*Overrun error,溢位错误*/
case SerialPortEvent.FE:/*Framing error,传帧错误*/
case SerialPortEvent.PE:/*Parity error,校验错误*/
case SerialPortEvent.CD:/*Carrier detect,载波检测*/
case SerialPortEvent.CTS:/*Clear to send,清除发送*/
case SerialPortEvent.DSR:/*Data set ready,数据设备就绪*/
case SerialPortEvent.RI:/*Ring indicator,响铃指示*/
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:/*Output buffer is empty,输出缓冲区清空*/
break;
case SerialPortEvent.DATA_AVAILABLE:/*Data available at the serial port,端口有可用数据。读到缓冲数组,输出到终端*/
byte[] readBuffer = new byte[1024];
String readStr="";
String s2 = "";
try { while (inputStream.available() > 0) {
inputStream.read(readBuffer);
readStr += new String(readBuffer).trim();
} s2 = new String(readBuffer).trim(); log("接收到端口返回数据(长度为"+readStr.length()+"):"+readStr);
log(s2);
service.addRecord(s2); } catch (IOException e) {
e.printStackTrace();
}
}
} @Override
public void run() {
try{
Thread.sleep(threadTime);
serialPort.close();
log(String.format("端口''监听关闭了!", commPort.getName()));
}catch(Exception e){
e.printStackTrace();
}
} public String getSport() {
return sport;
} public void setSport(String sport) {
this.sport = sport;
}
}
注:我里面的那个sport属性是spring注入进来的,大家测试的时候可以写死 比如“COM1”,然后里面的service都不需要的。有问题请留言。
测试过程:
public static void main(String[] args) {  
        ReadSerialPortsp = new ReadSerialPort();  
        sp.listPort();  
        sp.selectPort("COM1");
        sp.write("123456");
        sp.write("hello");
        sp.startRead(120);
    }  
打开VSPD ,虚拟两个串口,我这里虚拟的是COM1 和COM2

然后打开串口助手,找到COM2进行监听:如图

然后运行程序,相互传输数据即可。
Java串口通信--------基于RXTX (附带资源地址)的更多相关文章
- java串口通信丢包
		
java串口通信丢包问题 前段时间公司要求做一个java应用和pos串口通信的工具,调试好了好久每次都是只能接收到一包数据后续的数据都丢失了. 经过修改读写的流的缓存大小亲测都正常代码如下: seri ...
 - Java串口通信 RXTX 解决过程
		
背景介绍: 由于第一次用Java与硬件通信,网上查了许多资料,在这进行整理,便于以后学习.本人串口测试是USB串口设备连接电脑,在设备管理器中找到端口名称(也可以通过一些虚拟串口工具模拟). 下面主要 ...
 - Java 串口通信
		
在Windows系统下,用Java开发串口通信相关的程序时,需要用到几个文件. (1)win32com.dll 要放在jdk\jre\bin目录下. (2)comm.jar 和javax.comm.p ...
 - java 串口通信 代码
		
下面是我自己实现的串口接收的类,串口发送比较简单,就直接发送就可以了.下面的这个类可以直接使用. package com.boomdts.weather_monitor.util; import ja ...
 - Java串口通信具体解释
		
序言 说到开源,恐怕非常少有人不挑大指称赞.学生通过开源码学到了知识,程序猿通过开源类库获得了别人的成功经验及可以按时完毕手头的project,商家通过开源软件赚到了钱……,总之是皆大欢喜.然而开源软 ...
 - Java串口通信详细解释
		
前言 说到开源.恐怕非常少有人不挑大指称赞. 学生通过开源码学到了知识,程序猿通过开源类库获得了别人的成功经验及可以按时完毕手头的project,商家通过开源软件赚到了钱……,总之是皆大欢喜. 然而开 ...
 - 【Java】基于RXTX的Java串口通信
		
本篇内容参考转载自https://blog.csdn.net/kong_gu_you_lan/article/details/80589859 环境搭建 下载地址:http://fizzed.com/ ...
 - java 串口通信实现流程
		
1.下载64位rxtx for java 链接:http://fizzed.com/oss/rxtx-for-java 2.下载下来的包解压后按照说明放到JAVA_HOME即JAVA的安装路径下面去 ...
 - Java 串口通信 Ubuntu
		
说一下我的操作过程吧 在Windows上先用阿猫串口网络调试助手,进行调试: 在网上找Java代码,我选择的是RXTXcomm,网上代码很多,基本都一样. 在Windows电脑上把rxtx压缩包中的r ...
 
随机推荐
- IDEA和Eclipse启动优化
			
昨天对比了下IDEA和Eclipse的启动速度,发现IDEA启动真的是好慢啊!!! 电脑配置:8G win7 IDEA启动配置 -Xms1024m -Xmx1024m -Xmn500m -XX:Met ...
 - pandas-10 pd.pivot_table()透视表功能
			
pandas-10 pd.pivot_table()透视表功能 和excel一样,pandas也有一个透视表的功能,具体demo如下: import numpy as np import pandas ...
 - redhat7.2下VNC没法显示图像
			
1,Symptom /root/.vnc/HR-ECC-PRD-02:1.log内容有信息如下: VNCSconnST: Server default pixel fromat depth 24 (3 ...
 - go调度: 第二部分-go调度器
			
前言 这个博客是三部分中提供go调度器的语义和机制的部分. 博客三部分的顺序: 1) go调度: 第一部分-操作系统调度 2) go调度: 第二部分-go调度器 3) go调度: 第三部分-并发 介绍 ...
 - linux档案和目录的管理
			
资料来自鸟哥的linux私房菜,记录下来供自己平常使用参考 一:目录和路径: cd:change direcoty,变换目录的意思,就是从一个目录变到另一个目录,然后可以用绝对路径去变换目录,也可以用 ...
 - Linux命令——basename、dirname
			
简介 这2个命令多用于shell脚本 用法 basename filename_will_full_path dirname filename_will_full_path 对于但后缀的情况,base ...
 - Python并发编程-queue
			
Python并发编程-queue 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Queue # !/usr/bin/env python # _*_conding:utf-8_ ...
 - PAT甲级1003题解——Dijkstra
			
解题步骤: 1.初始化:设置mat[][]存放点之间的距离,vis[]存放点的选取情况,people[]存放初始时每个城市的人数,man[]存放到达每个城市的救援队的最多的人数,num[]存放到达每个 ...
 - 洛谷 P2722 总分题解
			
题目描述 我们可以从几个种类中选取竞赛的题目,这里的一个"种类"是指一个竞赛题目的集合,解决集合中的题目需要相同多的时间并且能得到相同的分数.你的任务是写一个程序来告诉USACO的 ...
 - python测试开发django-rest-framework-63.基于函数的视图(@api_view())
			
前言 上一篇讲了基于类的视图,在REST framework中,你也可以使用常规的基于函数的视图.它提供了一组简单的装饰器,用来包装你的视图函数, 以确保视图函数会收到Request(而不是Djang ...