上面我们写了一篇关于modbus-tcp的文章,这一篇我们主要将关于modbus-rtu的对接方式,好了,废话不多说,直接开搞。
一、环境准备
1.下载Virtual Serial Port Driver 6.9,使用此工具模拟com串口
链接:https://pan.baidu.com/s/1mBoqHZ4LzaSuY7EFHEjyxQ
提取码:7qku
2.下载modscan32,其中应该会包含modscan32(主机)及modsim32(从机),我们后续会使用modsim32模拟从机。
下载地址或自行百度搜索(网上资源还是很多的):
3.java环境准备,此处我们使用的是jdk1.8
二、代码编写
2.1 Virtual Serial Port Driver准备
首先我们先使用Virtual Serial Port Driver打开两个串口COM7,COM8,入下图所示
2.2 modsim准备
然后我们打开modsim,开始模拟准备从机数据,操作流程入下图所示。
1.连接设置->连接->端口7(因为我们刚才添加的com7和com8,我们使用com7作为从机口,com8一会我们java代码使用)
2.文件->新建
3.配置从机相关数据
2.3 编写Java代码
上述准备工作都做完了,我们开始编写Java主机代码rtu解析
1.创建一个maven项目
2.创建lib文件夹在maven项目中,并添加modbus4J.jar、RXTXcomm.jar、seroUtils.jar三个jar包
3.添加maven依赖
<dependencies>
<dependency>
<groupId>com.beyondli</groupId>
<artifactId>modbus4j</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/modbus4J.jar</systemPath>
</dependency>
<dependency>
<groupId>com.beyondli</groupId>
<artifactId>sero</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/seroUtils.jar</systemPath>
</dependency>
<dependency>
<groupId>com.beyondli</groupId>
<artifactId>rxtx</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/RXTXcomm.jar</systemPath>
</dependency>
</dependencies>
4.jre中添加rxtxParallel.dll和rxtxSerial.dll文件
首先,我们找到我们的jdk环境安装地址进入到对应的jre文件夹中,此地址每个同学需要根据自己的安装目录进行调整。以下是我的目录结构
rxtxSerial.dll文件我们放到jdk的jre/bin文件夹下
rxtxParallel.dll文件我们放到jre\lib\ext文件夹下
5.编写Java代码(主机)获取从机信息
读取从机和修改写入从机的对应方法均在下面的代码中,同学们可以自行阅读注释,根据自行业务进行调整。
package com.beyondli;
import com.serotonin.io.serial.SerialParameters;
import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.msg.*;
import java.util.Arrays;
public class ModbusPollRTUTest {
public static void main(String[] args) {
SerialParameters serialParameters = new SerialParameters();
// 设定MODBUS通讯的串行口
serialParameters.setCommPortId("COM8");
// 设定成无奇偶校验
serialParameters.setParity(0);
// 设定成数据位是8位
serialParameters.setDataBits(8);
// 设定为1个停止位
serialParameters.setStopBits(1);
// 设定端口名称
serialParameters.setPortOwnerName("Numb nuts");
// 设定端口波特率
serialParameters.setBaudRate(19200);
// 创建ModbusFactory工厂实例
ModbusFactory modbusFactory = new ModbusFactory();
// 创建ModbusMaster实例
ModbusMaster master = modbusFactory.createRtuMaster(serialParameters);
// 初始化
try {
master.init();
//写入从站3号位为7166
writeHoldingRegistersTest(master,1,2,7166);
//读取从站信息
while (true) {
readHoldingRegistersTest(master,1,0,5);
Thread.sleep(1000);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
master.destroy();
}
}
private static void readHoldingRegistersTest(ModbusMaster master,
int slaveId, int start, int len) {
try {
ReadHoldingRegistersRequest request = new ReadHoldingRegistersRequest(
slaveId, start, len);
ReadHoldingRegistersResponse response = (ReadHoldingRegistersResponse) master
.send(request);
if (response.isException()) {
System.out.println("Exception response: message="
+ response.getExceptionMessage());
} else {
//System.out.println(Arrays.toString(response.getShortData()));
short[] list = response.getShortData();
for(int i = 0; i < list.length; i++){
System.out.println(list[i] + " ");
}
/*
System.out.println();
int hight = (list[3] - 4000) /160;
if(hight <= 0){
System.out.println("水位高度为:0CM");
}else{
System.out.println("水位高度为:" + (hight + 13.5) + "CM");
}*/
}
} catch (ModbusTransportException e) {
e.printStackTrace();
}
}
private static void writeHoldingRegistersTest(ModbusMaster master,
int slaveId, int start, int value) {
try {
/*
value.replace(" ", ""); //去除所有空格,包括首尾、中间
//先把Stirng数据转成char数组
char[] dataChar = value.toCharArray();
//创建一个short数组,大小为参数的长度
short[] dataShort = new short[value.length()];
//循环dataChar数组,把dataChar一个一个存到short中
for (int i = 0; i < dataChar.length; i++) {
dataShort[i] = (short) dataChar[i];
}*/
WriteRegisterRequest request = new WriteRegisterRequest(
slaveId, start, value);
WriteRegisterResponse response = (WriteRegisterResponse) master
.send(request);
if (response.isException()){
System.out.println("Exception response: message=" + response.getExceptionMessage());
}
else {
System.out.println("Success");
}
} catch (ModbusTransportException e) {
e.printStackTrace();
}
}
}
最终效果入下图所示