近期开发过程中遇到需要读取底层传感器串口数据的问题,也是从无到有的一个过程,爬了不少帖子在这里记录一下,也给后来的朋友们一点小小的帮助吧。
下载链接在文末
官方包:
1998年SUN发布的串口通信API:comm2.0.jar(Windows环境下)和comm3.0.jar(Linux/Solaris环境下);IBM发布的串口通信API;
但是sun已经停止了对commAPI的更新,现在使用的更多的是RXTX的jar包,下载链接百度RXTX官网就是
除了jar包以外,相信新出的台式电脑和笔记本电脑已经没有com接口了吧,在做测试之前我们选择虚拟两个串口出来,这里需要用到软件:vspdpro
后面我会整理出开发所需要的所有的软件,供大家下载的.
软件安装好以后,直接添加虚拟对就好了,选择你需要虚拟出的端口即可:
使用Eclipse工具,新建一个maven工程,添加pom依赖,代替手工导入RXTX.jar
org.rxtx
rxtx
2.1.7
读取所有可用串口,并打印
这里我使用的端口是8和12大家可以灵活处理
package com.shenlan.demo485;
import java.util.Enumeration;
import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.UnsupportedCommOperationException;
public class RxtxDemo2 {
public static void main(String[] args) {
//定义表示端口的变量
CommPortIdentifier portIdentifier = null;
//定义记录每一个变量的枚举
Enumeration portIdentifiers = CommPortIdentifier.getPortIdentifiers();
//输出所有端口
System.out.println("输出所有端口");
while (portIdentifiers.hasMoreElements()) {
portIdentifier = (CommPortIdentifier) portIdentifiers.nextElement();
System.out.println("串口:"+ portIdentifier.getName());
}
//获取两个端口
CommPortIdentifier com8 = null;
CommPortIdentifier com12 = null;
try {
com8 = CommPortIdentifier.getPortIdentifier("COM8");
com12 = CommPortIdentifier.getPortIdentifier("COM12");
} catch (NoSuchPortException e) {
// TODO: handle exception
e.printStackTrace();
}
//打开两个端口
SerialPort serialCom8 = null;
SerialPort serialCom12 = null;
try {
serialCom8=(SerialPort) com8.open("RxtxDemo2",1000);
serialCom12=(SerialPort) com12.open("RxtxDemo2",1000);
} catch (PortInUseException e) {
// TODO: handle exception
e.printStackTrace();
}
//设置端口参数
try {
serialCom8.setSerialPortParams(9600, //波特率
SerialPort.DATABITS_8, //数据位 8
SerialPort.STOPBITS_1,//停止位1
SerialPort.PARITY_NONE);//奇偶位
serialCom12.setSerialPortParams(9600, //波特率
SerialPort.DATABITS_8, //数据位 8
SerialPort.STOPBITS_1,//停止位1
SerialPort.PARITY_NONE);//奇偶位
} catch (UnsupportedCommOperationException e) {
// TODO: handle exception
e.printStackTrace();
//关闭端口8和12
serialCom8.close();
serialCom12.close();
}
}
}
完成对端口的打开和输出之后,我们还需要完成端口与端口之间的收发信息
这里需要用到一个软件,叫做端口调试助手,同样我也会打包上传的
这里通过轮询的方式监听COM15端口,与之相连的串口是COM8
package com.shenlan.demo485;
import java.io.IOException;
import java.io.InputStream;
import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
public class Listener {
/**
* 通过轮询模式监听串口COM15
* 当串口COM8传来数据的时候读取数据
*/
public static void main(String[] args) {
CommPortIdentifier com15 = null;//定义需要接收数据的端口(未打开)
SerialPort serialCom15 = null;//打开的端口
InputStream inputStream = null;//端口输入流
System.out.println("开始监听端口COM15收到的数据");
try {
//获取并打开串口com15
com15 =CommPortIdentifier.getPortIdentifier("COM15");
serialCom15 = (SerialPort) com15.open("Com15Listener", 1000);
//System.out.println(serialCom15);
//获取串口的输入流对象
inputStream = serialCom15.getInputStream();
//从串口读出数据
//定义用于缓存读入数据的数组
byte []cache = new byte[1024];
//记录已经到达串口COM15且未被读取的数据的字节(Byte)数
int availableBytes = 0;
//通过无限循环的方式来扫描COM15,检查是否有数据到达端口,间隔20ms
while (true) {
//获取串口15收到的字节数
availableBytes = inputStream.available();
//如果可用字节数大于0则开始转换并获取数据
while (availableBytes>0) {
//从串口的输入流对象中读入数据并将数据存放到缓存数组中
inputStream.read(cache);
//将获取到的数据进行转码并输出
for (int i = 0; i < cache.length&&i<availableBytes; i++) {
System.out.print((char)cache[i]);
}
System.out.println();
availableBytes = inputStream.available();
}
//线程睡眠20ms
Thread.sleep(20);
}
}catch(InterruptedException e){
e.printStackTrace();
}catch (NoSuchPortException e) {
//找不到串口的情况下抛出该异常
e.printStackTrace();
} catch (PortInUseException e) {
//如果因为端口被占用而导致打开失败,则抛出该异常
e.printStackTrace();
} catch (IOException e) {
//如果获取输出流失败,则抛出该异常
e.printStackTrace();
}
}
}
此时通过串口调试助手向COM15发送消息
选择com8-com15以后点击开始,然后单击发送
COM15收到的消息被监听
至此监听端口类书写完成
接下来完后端口对端口的发送:
COM15发送到COM8
package com.shenlan.demo485;
import java.io.IOException;
import java.io.OutputStream;
import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
public class Write {
/**
* 是向COM8发送数据
*/
public static void main(String[] args) {
//定义变量
CommPortIdentifier com8 = null;
SerialPort serialCom8 = null;
try {
//获取com8端口
com8 = CommPortIdentifier.getPortIdentifier("COM8");
//打开com8端口
serialCom8 = (SerialPort) com8.open("Com8Writer",1000);
//写入数据
//获取串口输出流对象
OutputStream outputStream = serialCom8.getOutputStream();
//通过串口的输出流向串口写数据
byte hello[] = new byte[] {'H','e','l','l','o',' ','W','o','r','l','d','!'};
outputStream.write(hello);
/*
* 使用输出流往串口写数据的时候必须将数据转换为byte数组格式或int格式,
* 当另一个串口接收到数据之后再根据双方约定的规则,对数据进行解码
*/
//关闭输出流
outputStream.flush();
serialCom8.close();
//关闭串口
} catch (NoSuchPortException e) {
//找不到串口的情况下抛出该异常 exception
e.printStackTrace();
}catch (PortInUseException e) {
//如果因为端口被占用而导致打开失败,则抛出该异常
e.printStackTrace();
}catch (IOException e) {
//如果获取输出流失败,则抛出该异常
e.printStackTrace();
}
}
}
这里采用的是byte数组发送helloworld到端口,运行java类,可以在串口调试助手收到消息
注意:这里调试的时候需要把端口更改为COM15-COM8,这样就能收到消息了.
简单的调试就到这里,稍后我上传源码和文件供大家下载,包括jar包和串口调试助手和虚拟串口的vspdpro
链接:百度网盘
链接:https://pan.baidu.com/s/1ogoSCmWoHDn7gnu8cK45Zw
提取码:4b93
复制这段内容后打开百度网盘手机App,操作更方便哦
源码:
https://download.csdn.net/download/weixin_43616450/11906730