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 ...
随机推荐
- 2019 房多多java面试笔试题 (含面试题解析)
本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.房多多等公司offer,岗位是Java后端开发,因为发展原因最终选择去了房多多,入职一年时间了,也成为了面试官 ...
- Python进阶----数据库引擎(InnoDB),表的创建,mysql的数据类型,mysql表的约束
Python进阶----数据库引擎(InnoDB),表的创建,mysql的数据类型,mysql表的约束 一丶MySQL的存储引擎 什么是存储引擎: MySQL中的数据用各种不同的技术存储在文件( ...
- SpringBoot 传入JSON对象参数
1.请求参数格式必须是正确的JSON. 2.在入参中使用注解@RequestBody,用于接收JSON参数,使其自动转对象 3.关于lombok在此产生的一点小坑,@Builder对@RequestB ...
- Unity Physicals Rigidbody with multiple colliders
Rigidbody with multiple colliders adding colliders changes the center of mass and rotation behaviour ...
- JavaScript笔记02_对象
目录 1. 函数 1. 函数创建 2. 函数的参数 2. return.break.continue 3. 立即执行函数 4. 对象 5. 枚举对象中的属性 6. 声明提前 1.变量的声明提前 2. ...
- HTTPS安全通信过程
前言:本文是的第三篇文章.第一篇文章<常见加密算法特点及适用场景>,介绍了常见加密算法及其适用的场景,对加密算法做一个总体的概述.第二篇文章<非对称加密算法-RSA算法&g ...
- Zabbix Documentation 4.0
Zabbix Documentation 4.0 1 Create user account For all of the Zabbix daemon processes, an unprivileg ...
- springmvc手动获取bean
@Service @Lazy(false) public class SpringContextHolder implements ApplicationContextAware, Disposabl ...
- 剑指Offer(二十):包含min函数的栈
剑指Offer(二十):包含min函数的栈 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/ba ...
- python dijkstra 最短路算法示意代码
def dijkstra(graph, from_node, to_node): q, seen = [(0, from_node, [])], set() while q: cost, node, ...