第一次接触这个,网上资料也是比较少,搞了一天也终于搞定了,总结一下过程中遇到的一些问题,为后面的人做个警戒
1.首先需要使用RXTX的串口通讯包,还有modbus4J的包,具体如下,文章结尾我会附上资源的地址
基本上所有的问题都是在这个过程中遇到的,首先要把rxtxParallel.dll,rxtxSerial.dll,放到你的jdk的jre/bin文件夹下,RXTXcomm.jar放到jre/lib文件夹下,然后在你的项目中导入RXTXcomm.jar,具体操作步骤如下
然后选择你刚才jre/bin目录下的RXTXcomm.jar,点击保存,点击ok,就可以了
这个过程中会遇到几种bug,他们产生的原因和解决办法我会一一解答,具体如下
Native lib Version = RXTX-2.2-20081207 Cloudhopper Build rxtx.cloudhopper.net
Java lib Version = RXTX-2.1-7
WARNING: RXTX Version mismatch
Jar version = RXTX-2.1-7
native lib Version = RXTX-2.2-20081207 Cloudhopper Build rxtx.cloudhopper.net
这个bug是由于RXTX里面各种包版本不一样的问题,也就是上面截图里的几种包,解决方法就是更换包,换成同一个版本
第二个问题 报错信息如下
#
# A fatal error has been detected by the Java Runtime Environment:
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000180004465, pid=25576, tid=30280
# JRE version: Java(TM) SE Runtime Environment (10.0.1+10) (build 10.0.1+10)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (10.0.1+10, mixed mode, tiered, compressed oops, g1 gc, windows-amd64)
# Problematic frame:
# C [rxtxSerial.dll+0x4465]
# No core dump will be written. Minidumps are not enabled by default on client versions of Windows
# An error report file with more information is saved as:
# D:\...l\hs_err_pid25576.log(保护隐私,路径已省略)
# If you would like to submit a bug report, please visit:
# http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
这个问题困扰了很久,最终原因很乌龙,是因为jdk版本不支持的问题,这里jdk的版本必须使用1.8-2以下的jdk版本才可以使用,我之前用的jdk9和jdk1.8-291全部都运行失败,
可能是这个开发包太老了导致这样的问题
第三个问题 modbus4J.jar,seroUtils.jar无法导入的问题,maven地址中找不到这两个包,我们可以把这个包下载下来之后,然后注册到本地仓库,具体步骤如下
1、进入cmd命令界面
2、输入指令如下:mvn install:install-file -Dfile=E:\CFCA\CFCA_xfraud_ml_01.jar -DgroupId=cfca.xfraud -DartifactId=ml -Dversion=1.0 -Dpackaging=jar -DgeneratePom=true -DcreateChecksum=true,其中
Dfile为jar包文件路径
DgroupId一般为jar开发组织的名称,也是坐标groupId
DartifactId一般为jar名称,也是坐标 artifactId
Dversion是版本号
Dpackaging是打包类型
然后你进入到你的本地仓库就可以看到
复制到maven地址就可以
然后基本上就没什么问题了
具体代码如下
package cn.wu.demo.modbus4j;
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 WriteToModbus1 {
// MODBUS网络上从站地址
private final static int SLAVE_ADDRESS = 1;
public static void main(String[] args) throws Exception {
SerialParameters serialParameters = new SerialParameters();
// 设定MODBUS通讯的串行口
serialParameters.setCommPortId("COM2");
// 设定成无奇偶校验
serialParameters.setParity(0
// 设定成数据位是8位
serialParameters.setDataBits(8);
// 设定为1个停止位
serialParameters.setStopBits(1);
serialParameters.setPortOwnerName("COM2");
// 串行口上的波特率
serialParameters.setBaudRate(9600);
ModbusFactory modbusFactory = new ModbusFactory();
ModbusMaster master = modbusFactory.createRtuMaster(serialParameters);
try {
master.init();
readDiscreteInputTest(master, 1, 0, 3);
writeRegistersTest(master, 1, 0, new short[] { 0x31, 0xb, 0xc, 0xd, 0xe,
0x9, 0x8, 0x7, 0x6 });
readHoldingRegistersTest(master, 1, 0, 3);
} finally {
master.destroy();
* 读开关量型的输入信号
* @param master
* 主站
* @param slaveId
* 从站地址
* @param start
* 起始偏移量
* @param len
* 待读的开关量的个数
private static void readDiscreteInputTest(ModbusMaster master, int slaveId, int start, int len) {
try {
ReadDiscreteInputsRequest request = new ReadDiscreteInputsRequest(slaveId, start, len);
ReadDiscreteInputsResponse response = (ReadDiscreteInputsResponse) master.send(request);
if (response.isException())
System.out.println("Exception response: message=" + response.getExceptionMessage());
System.out.println(Arrays.toString(response.getBooleanData()));
} catch (ModbusTransportException e) {
e.printStackTrace();
* 读保持寄存器上的内容
* @param master
* 主站
* @param slaveId
* 从站地址
* @param start
* 起始地址的偏移量
* @param len
* 待读寄存器的个数
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());
System.out.println(Arrays.toString(response.getShortData()));
} catch (ModbusTransportException e) {
e.printStackTrace();
* 批量写数据到保持寄存器
* @param master
* 主站
* @param slaveId
* 从站地址
* @param start
* 起始地址的偏移量
* @param values
* 待写数据
public static void writeRegistersTest(ModbusMaster master, int slaveId, int start,
short[] values) {
try {
WriteRegistersRequest request = new WriteRegistersRequest(slaveId, start, values);
WriteRegistersResponse response = (WriteRegistersResponse) master.send(request);
if (response.isException())
System.out.println("Exception response: message=" + response.getExceptionMessage());
System.out.println("Success");
} catch (ModbusTransportException e) {
e.printStackTrace();
}
pom包如下
<repositories>
<repository>
<id>alimaven</id>
<name>aliyun maven</name>
http://maven.aliyun.com/nexus/content/groups/public/
</repository>
<repository>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
<id>ias-snapshots</id>
<name>Infinite Automation Snapshot Repository</name>
<url>https://maven.mangoautomation.net/repository/ias-snapshot/</url>
</repository>
<repository>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>ias-releases</id>
<name>Infinite Automation Release Repository</name>
<url>https://maven.mangoautomation.net/repository/ias-release/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.5.4</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
//这个是modbus包,我下载jar包下来,注册到本地仓库的时候就随便起了个名字
<dependency>
<groupId>zyf</groupId>
<artifactId>modbus</artifactId>
<version>1.0.0</version>
</dependency>
//这个是串口用的包,也是随便起了个名字
<dependency>
<groupId>zyf1</groupId>
<artifactId>modbus</artifactId>
<version>1.0.0</version>
</dependency>
<!--<dependency>-->
<!--<groupId>com.infiniteautomation</groupId>-->
<!--<artifactId>modbus4j</artifactId>-->
<!--<version>3.0.3</version>-->
<!--</dependency>-->
<dependency>
<groupId>com.github.zengfr</groupId>
<artifactId>easymodbus4j</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>com.twitter.serial</groupId>
<artifactId>serial</artifactId>
<version>0.1.6</version>
</dependency>
<dependency>
<groupId>org.bidib.jbidib.org.qbang.rxtx</groupId>
<artifactId>rxtxcomm</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>compile</scope>
</dependency>
</dependencies>