java 通过 Modbus TCP 接收数据
介绍
Modbus由MODICON公司于1979年开发,是一种工业现场总线协议标准。1996年施耐德公司推出基于以太网TCP/IP的Modbus协议:ModbusTCP。
- Modbus协议是一种通信协议,用于在不同设备之间进行数据传输和通信。它最初由Modicon(现在是施耐德电气)开发,用于在工业自动化领域中的设备之间进行通信。
- Modbus协议基于主从架构,其中一个设备充当主站(Master),其他设备充当从站(Slave)。主站负责发起通信请求,而从站则响应这些请求并提供所需的数据。
- Modbus协议支持多种物理层和传输方式,包括串行通信(如RS-232、RS-485)和以太网通信。它使用简单的二进制格式进行数据传输,具有较低的开销和较高的可靠性。
- Modbus协议定义了一组功能码,用于执行不同的操作,例如读取和写入数据寄存器、线圈等。这些功能码可以通过Modbus消息进行传输,并且可以在主站和从站之间进行双向通信。
总结:Modbus协议是一种用于工业自动化设备之间通信的协议,它具有简单、可靠的特点,并支持多种物理层和传输方式。
modbustcp 主要是用于工业上的通讯,像是作者现在和PLC进行连接就是使用modbustcp协议。
modbustcp协议格式内容分为两个部分,其一是MBAP,其二是PDU
MBAP是表示modbustcp协议中的报文头部分,长度为7个字节
事务处理标识 | 协议表示 | 长度 | 单元标识符 |
2个字节 | 2个字节 | 2个字节 | 1个字节 |
名称 | 解释 |
---|---|
事务处理标识 | 是本次通讯中在发送通讯的第几次,一般按照每发送一次后+1 |
协议表示 | 默认00 00 是表示此次通讯是modbustcp协议 |
长度 | 表示此次PDU中携带数据长度 |
单元标识符 | 表示此次协议发送的端口中设备所处的地址 |
PDU是表示modbustcp协议中的数据内容,主要由功能码和数据组成;
其中功能吗所占用的字节为1,表示此次的所要实现的操作,数据长度根据MBAP中的长度数值来判断。
功能码中主要是对四类操作对象进行操作(此处可以理解为Java中的对象)
对象 | 含义 |
---|---|
线圈 | PLC的输出位,开关量,在Modbus中可读可写 |
离散量 | PLC的输入位,开关量,在Modbus中只读 |
输入寄存器 | PLC中只能从模拟量输入端改变的寄存器,在Modbus中只读 |
保持寄存器 | PLC中用于输出模拟量信号的寄存器,在Modbus中可读可写 |
功能码就是展示此次通讯的操作,具体功能码的识别在下方展示
代码 | 中文名称 | 英文名 | 位操作/字操作 | 操作数量 |
01 | 读线圈状态 | READ COIL STATUS | 位操作 | 单个或多个 |
02 | 读离散输入状态 | READ INPUT STATUS | 位操作 | 单个或多个 |
03 | 读保持寄存器 | READ HOLDING REGISTER | 字操作 | 单个或多个 |
04 | 读输入寄存器 | READ INPUT REGISTER | 字操作 | 单个或多个 |
05 | 写线圈状态 | WRITE SINGLE COIL | 位操作 | 单个 |
06 | 写单个保持寄存器 | WRITE SINGLE REGISTER | 字操作 | 单个 |
15 | 写多个线圈 | WRITE MULTIPLE COIL | 位操作 | 多个 |
16 | 写多个保持寄存器 | WRITE MULTIPLE REGISTER | 字操作 | 多个 |
Java中实现
pom.xml中引入modbus4j的jar包进行调用。
<dependency>
<groupId>com.infiniteautomation</groupId>
<artifactId>modbus4j</artifactId>
<version>3.0.3</version>
</dependency>
备注:如果出现无法引入的情况,可以推荐大家直接去github上下载modbus4j。
下载地址:https://gitcode.com/MangoAutomation/modbus4j/overview
通过 Modbus TCP 接收数据
整体流程
功能实现
1. 建立连接
我们需要确保我们可以与Modbus设备建立连接。为此,我们需要引入相关的库文件,并创建一个TCP连接。
我们需要在Java代码中导入Modbus库。我们可以使用以下代码:
import net.wimpi.modbus.Modbus;
import net.wimpi.modbus.io.ModbusTCPTransaction;
import net.wimpi.modbus.msg.ReadInputDiscretesRequest;
import net.wimpi.modbus.msg.ReadInputDiscretesResponse;
import net.wimpi.modbus.net.TCPMasterConnection;
接下来我们需要创建一个TCP连接以连接到Modbus设备。代码如下:
// Modbus设备的IP地址
String ipAddress = "192.168.0.1";
// Modbus设备的端口号
int port = Modbus.DEFAULT_PORT;
TCPMasterConnection connection = new TCPMasterConnection(InetAddress.getByName(ipAddress));
connection.setPort(port);
connection.connect();
2. 创建Modbus主站
建立连接之后,我们需要创建一个Modbus主站,以便与Modbus设备进行通信。ModbusTCPTransaction transaction = new ModbusTCPTransaction(connection);
3. 连接到Modbus设备
创建Modbus主站之后,我们需要使用Modbus主站连接到Modbus设备。这里需要连接设备的地址。
// Modbus设备的地址
int deviceId = 1;
transaction.setUnitID(deviceId);
4. 读取数据
以上1至3的步骤完成后,就可以使用Modbus主站来读取Modbus设备上的数据,这里读取的是输入开关的状态。
// 起始地址
int startAddress = 0;
// 数据数量
int quantity = 10;
ReadInputDiscretesRequest request = new ReadInputDiscretesRequest(startAddress, quantity);
request.setUnitID(deviceId);
transaction.setRequest(request);
transaction.execute();
ReadInputDiscretesResponse response = (ReadInputDiscretesResponse) transaction.getResponse();
// 读取到的数据
boolean[] data = response.getBooleanData();
完结