目录
1、RXTXcomm.jar:放到你项目目录下面的resource的lib目录下面,还有jre的ext目录下
2、rxtxParallel.dll rxtxSerial.dll:这两个文件放到jdk1.8.0_111\jre\bin
1、vspd(Configure Virtual Serial Port Driver)虚拟串口模拟工具,如果你的电脑上没有串口,这个工具可以帮你模拟串口通信
2、初始化串口,以及监听串口发送过来的数据,然后监听到一条就保存一条到数据库中去
4、如果连接成功控制台就会打印消息,打开串口成功,关闭串口com2
这篇文章主要将串口通信开发,以及在开发中遇到的一些细节问题和大问题,不管是什么问题都是折磨人的,永远忘不了上百度一个问题闹腾一下午的煎熬
RXTXcomm有32位的,也有64位的包,我们大多用到的都是64而且jdk都是1.8版本的,所以开干。。
一、资源下载
链接:https://pan.baidu.com/s/1lvwJR_jMP6WSRCmnHGPiTA
提取码:iwji
1、RXTXcomm.jar:放到你项目目录下面的resource的lib目录下面,还有jre的ext目录下
2、rxtxParallel.dll rxtxSerial.dll:这两个文件放到jdk1.8.0_111\jre\bin
3、这一步非常重要,把rxtxParallel.dll rxtxSerial.dll这两个文件放到jdk的bin目录下面,如果你不放当你后面打包后运行打开串口会报找不到这两个文件的错误,百思不得齐解(困扰了我一个下午)
二、测试环节,需要的测试工具
1、vspd(Configure Virtual Serial Port Driver)虚拟串口模拟工具,如果你的电脑上没有串口,这个工具可以帮你模拟串口通信
下载地址:https://pan.baidu.com/s/1IP0pNIX2jDBeMAX5sSQjpQ 提取码:arjd
这个工具不是破解版的,所以是试用14天,直接解压就能用,当启动程序后直接点add就能新建串口com3和com6,如果实在不知道用就去这个网站看教程吧。
强大的虚拟串口软件 (qq.com)https://mp.weixin.qq.com/s/iQ-Hqd-TtxhJ0CR9llfleg
2、串口测试工具(SerialPortUtility)
下载地址:https://www.alithon.com/downloads
三、代码实现串口通信
1、串口工具类
public class SerialPortUtil {
/**
* 获得系统可用的端口名称列表(COM0、COM1、COM2等等)
*
* @return List<String>可用端口名称列表
*/
@SuppressWarnings("unchecked")
public static List<String> getSerialPortList() {
List<String> systemPorts = new ArrayList<>();
//获得系统可用的端口
Enumeration<CommPortIdentifier> portList = CommPortIdentifier.getPortIdentifiers();
while (portList.hasMoreElements()) {
String portName = portList.nextElement().getName();//获得端口的名字
systemPorts.add(portName);
}
return systemPorts;
}
/**
* 打开串口
*
* @param serialPortName 串口名称
* @return SerialPort 串口对象
* @throws NoSuchPortException 对应串口不存在
* @throws PortInUseException 串口在使用中
* @throws UnsupportedCommOperationException 不支持操作操作
*/
public static SerialPort openSerialPort(String serialPortName)
throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException {
SerialPortParameter parameter = new SerialPortParameter(serialPortName);
return openSerialPort(parameter);
}
/**
* 打开串口
*
* @param serialPortName 串口名称
* @param baudRate 波特率
* @return SerialPort 串口对象
* @throws NoSuchPortException 对应串口不存在
* @throws PortInUseException 串口在使用中
* @throws UnsupportedCommOperationException 不支持操作操作
*/
public static SerialPort openSerialPort(String serialPortName, int baudRate)
throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException {
SerialPortParameter parameter = new SerialPortParameter(serialPortName, baudRate);
return openSerialPort(parameter);
}
/**
* 打开串口
*
* @param serialPortName 串口名称
* @param baudRate 波特率
* @param timeout 串口打开超时时间
* @return SerialPort 串口对象
* @throws NoSuchPortException 对应串口不存在
* @throws PortInUseException 串口在使用中
* @throws UnsupportedCommOperationException 不支持操作操作
*/
public static SerialPort openSerialPort(String serialPortName, int baudRate, int timeout)
throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException {
SerialPortParameter parameter = new SerialPortParameter(serialPortName, baudRate);
return openSerialPort(parameter, timeout);
}
/**
* 打开串口
*
* @param parameter 串口参数
* @return SerialPort 串口对象
* @throws NoSuchPortException 对应串口不存在
* @throws PortInUseException 串口在使用中
* @throws UnsupportedCommOperationException 不支持操作操作
*/
public static SerialPort openSerialPort(SerialPortParameter parameter)
throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException {
return openSerialPort(parameter, 2000);
}
/**
* 打开串口
*
* @param parameter 串口参数
* @param timeout 串口打开超时时间
* @return SerialPort串口对象
* @throws NoSuchPortException 对应串口不存在
* @throws PortInUseException 串口在使用中
* @throws UnsupportedCommOperationException 不支持操作操作
*/
public static SerialPort openSerialPort(SerialPortParameter parameter, int timeout)
throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException {
//通过端口名称得到端口
CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(parameter.getSerialPortName());
//打开端口,(自定义名字,打开超时时间)
CommPort commPort = portIdentifier.open(parameter.getSerialPortName(), timeout);
//判断是不是串口
if (commPort instanceof SerialPort) {
SerialPort serialPort = (SerialPort) commPort;
//设置串口参数(波特率,数据位8,停止位1,校验位无)
serialPort.setSerialPortParams(parameter.getBaudRate(), parameter.getDataBits(), parameter.getStopBits(), parameter.getParity());
System.out.println("开启串口成功,串口名称:" + parameter.getSerialPortName());
return serialPort;
} else {
//是其他类型的端口
throw new NoSuchPortException();
}
}
/**
* 关闭串口
*
* @param serialPort 要关闭的串口对象
*/
public static void closeSerialPort(SerialPort serialPort) {
serialPort.close();
System.out.println("关闭了串口:" + serialPort.getName());
}
/**
* 向串口发送数据
*
* @param serialPort 串口对象
* @param data 发送的数据
*/
public static void sendData(SerialPort serialPort, byte[] data) {
OutputStream os = null;
try {
//获得串口的输出流
os = serialPort.getOutputStream();
os.write(data);
os.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (os != null) {
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 从串口读取数据
*
* @param serialPort 要读取的串口
* @return 读取的数据
*/
public static byte[] readData(SerialPort serialPort) {
InputStream is = null;
byte[] bytes = null;
try {
//获得串口的输入流
is = serialPort.getInputStream();
//获得数据长度
int bufflenth = is.available();
while (bufflenth != 0) {
//初始化byte数组
bytes = new byte[bufflenth];
is.read(bytes);
bufflenth = is.available();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (is != null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return bytes;
}
/**
* 给串口设置监听
*
* @param serialPort serialPort 要读取的串口
* @param listener SerialPortEventListener监听对象
* @throws TooManyListenersException 监听对象太多
*/
public static void setListenerToSerialPort(SerialPort serialPort, SerialPortEventListener listener) throws TooManyListenersException {
//给串口添加事件监听
serialPort.addEventListener(listener);
//串口有数据监听
serialPort.notifyOnDataAvailable(true);
//中断事件监听
serialPort.notifyOnBreakInterrupt(true);
}
}
2、初始化串口,以及监听串口发送过来的数据,然后监听到一条就保存一条到数据库中去
private SerialPort serialPort;
/**
* 初始化串口
*
* @throws IOException
*/
@SuppressWarnings("unchecked")
public void initDriverSerialPort() {
SqlSession session = MybatisUtils.getSession();
SerialPortMapper mapper = session.getMapper(SerialPortMapper.class);
rfid_print.setDisable(false);
try {
//打开串口,然后获取所有串口的一个集合,然后通过获取文本框里面的内容来选择串口
serialPort = SerialPortUtil.openSerialPort(port_comboBox.getValue());
if (serialPort !=null){
new Alert(Alert.AlertType.NONE, "打开端口成功", new ButtonType[]{ButtonType.CLOSE}).show();
}else {
new Alert(Alert.AlertType.NONE, "未找到该端口,打开失败", new ButtonType[]{ButtonType.CLOSE}).show();
}
// 启动一个线程发送10次6463
new Thread(() -> {
String s = "6463";
byte[] bytes = s.getBytes();
SerialPortUtil.sendData(serialPort, bytes);//发送数据
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
//设置串口的listener
SerialPortUtil.setListenerToSerialPort(serialPort, event -> {
//数据通知
if (event.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
byte[] bytes = SerialPortUtil.readData(serialPort);
System.out.println("收到的数据长度:{}" + bytes.length);
String s = new String(bytes);
String[] split = s.split(",");
Serialport1 serialport1=new Serialport1();
serialport1.setCarCode(split[0]);
serialport1.setTime(split[1]);
serialport1.setYup(split[2]);
serialport1.setYdown(split[3]);
serialport1.setYtest(split[4]);
serialport1.setZup(split[5]);
serialport1.setZdown(split[6]);
serialport1.setZtest(split[7]);
serialport1.setLightOnUp(split[8]);
serialport1.setLightUpDown(split[9]);
serialport1.setLightOnTest(split[10]);
serialport1.setStatus(split[11]);
int i = mapper.setSerialport(serialport1);
System.out.println("成功插入"+i+"条数据!!!");
session.commit(); //提交事务,重点!不写的话不会提交到数据库
session.close();
}
});
} catch (NoSuchPortException | PortInUseException | UnsupportedCommOperationException | TooManyListenersException e) {
e.printStackTrace();
}
}
3、关闭串口
/**
* 关闭串口
*
* @throws IOException
*/
public void closeDriverSerialPort() {
SerialPortUtil.closeSerialPort(serialPort);
new Alert(Alert.AlertType.NONE, "关闭端口成功", new ButtonType[]{ButtonType.CLOSE}).show();
}
4、如果连接成功控制台就会打印消息,打开串口成功,关闭串口com2