最近帮老师做了一个小项目,一个牧场公司想用传感器收集一些环境信息,记录到数据库里去,然后加以分析查看。这里面和传感器通信用到了串口通信,我也是接触了一下,把用到的东西分享出来。

准备工作:

  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 (附带资源地址)的更多相关文章

  1. java串口通信丢包

    java串口通信丢包问题 前段时间公司要求做一个java应用和pos串口通信的工具,调试好了好久每次都是只能接收到一包数据后续的数据都丢失了. 经过修改读写的流的缓存大小亲测都正常代码如下: seri ...

  2. Java串口通信 RXTX 解决过程

    背景介绍: 由于第一次用Java与硬件通信,网上查了许多资料,在这进行整理,便于以后学习.本人串口测试是USB串口设备连接电脑,在设备管理器中找到端口名称(也可以通过一些虚拟串口工具模拟). 下面主要 ...

  3. Java 串口通信

    在Windows系统下,用Java开发串口通信相关的程序时,需要用到几个文件. (1)win32com.dll 要放在jdk\jre\bin目录下. (2)comm.jar 和javax.comm.p ...

  4. java 串口通信 代码

    下面是我自己实现的串口接收的类,串口发送比较简单,就直接发送就可以了.下面的这个类可以直接使用. package com.boomdts.weather_monitor.util; import ja ...

  5. Java串口通信具体解释

    序言 说到开源,恐怕非常少有人不挑大指称赞.学生通过开源码学到了知识,程序猿通过开源类库获得了别人的成功经验及可以按时完毕手头的project,商家通过开源软件赚到了钱……,总之是皆大欢喜.然而开源软 ...

  6. Java串口通信详细解释

    前言 说到开源.恐怕非常少有人不挑大指称赞. 学生通过开源码学到了知识,程序猿通过开源类库获得了别人的成功经验及可以按时完毕手头的project,商家通过开源软件赚到了钱……,总之是皆大欢喜. 然而开 ...

  7. 【Java】基于RXTX的Java串口通信

    本篇内容参考转载自https://blog.csdn.net/kong_gu_you_lan/article/details/80589859 环境搭建 下载地址:http://fizzed.com/ ...

  8. java 串口通信实现流程

    1.下载64位rxtx for java 链接:http://fizzed.com/oss/rxtx-for-java 2.下载下来的包解压后按照说明放到JAVA_HOME即JAVA的安装路径下面去 ...

  9. Java 串口通信 Ubuntu

    说一下我的操作过程吧 在Windows上先用阿猫串口网络调试助手,进行调试: 在网上找Java代码,我选择的是RXTXcomm,网上代码很多,基本都一样. 在Windows电脑上把rxtx压缩包中的r ...

随机推荐

  1. 【面试突击】-Redis常见面试题(一)

    介绍:Redis 是一个开源的使用 ANSI C 语言编写.遵守 BSD 协议.支持网络.可基于内存亦可持久化的日志型.Key-Value 数据库,并提供多种语言的 API的非关系型数据库. 传统数据 ...

  2. JAVA项目之注册

    public class RegisterServlet extends HttpServlet { private UsersService usersService = new UsersServ ...

  3. 英语Petrolaeum原油

    Petrolaeum (英语单词) Petrolaeum是一个英语单词,名词,翻译为石油. 中文名:石油 外文名:petrolaeum,petroleum 目录 1 含义 2 例句 含义 petrol ...

  4. ar 解压一个.a文件报错: xxx.a is a fat file (use libtool(1) or lipo(1) and ar(1) on it)

    Linux  使用终端指令 ar x /Users/apple/Desktop/libWC_LIB_SDKT.a解压一个文件 报错如图所示: 是因为该.a文件包含了多个cpu架构,比如armv7,ar ...

  5. 转:ajax的AntiForgery和Authorize 以及ajax登录例子

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/ashcn2001/article/det ...

  6. MySQL Lock--MySQL INSERT加锁学习

    准备测试数据: ## 开启InnoDB Monitor SET GLOBAL innodb_status_output=ON; SET GLOBAL innodb_status_output_lock ...

  7. 前端cdn库推荐

    后端编程人员,有时作功能调试时会用到jquery.layer等的前端库文件,用得较多的我们可以下载下来放到自己的电脑上,有些偶尔使用一次的类库插件就没必要全都下载下来,毕竟不用的类库多了,自己找到它都 ...

  8. 四、Linux_用户切换

    四.用户切换 # 切换用户的命令为: su username # 从普通用户切换到root用户,还可以使用命令: sudo su

  9. 日常工具集和技巧分享(Linux向)

    好用的软件/终端 命令别名 ip切换 imgcat 终端查看图片 autojump 目录快捷跳转 titan 密码记录工具 tldr man 的简单版,在线查询linux命令示例 ssh 别名/免密码 ...

  10. nginx负载调度算法,后端节点状态