If the spring breeze feels pity for the flowers, can it allow me to stay young again?
Modbus RTU
Communication protocol instruction learning
Modbus RTU
The protocol is a compact, binary representation of data with a cyclic redundancy checksum.
Read command format
The 03 function code is commonly used during use, so take 03 reading as an example.
Read request:
01 03 00 00 00 02 C4 0B
01: Device address, the device address is 1
03: Function code, currently 03 read request
00 00: Register starting address, reading starts from 00 00 register
00 02: Read register length, Read 2 lengths, corresponding to reply 4 bytes
C4 0B: CRC checksum
Read request reply:
01 03 04 00 0C 00 02 BB F1
01: Device address, the device address is 1
03: Function code, currently 03 read reply
04: Data length, including 4 bytes of data
00 0C: Register 1 value
00 02: Register 2 value
BB F1: CRC checksum
Master node sends frame format:
Slave node response frame format:
Notice:
-
MSB
Indicates high byte,LSB
indicates low byte -
Each register stores two bytes. For register data type of 1 byte, it is required to be stored in the low byte.
Write command format
During use, the 10 function code can be written to one or more registers, so taking 10 writing as an example
Write request:
01 10 00 00 00 02 04 00 00 00 0A 73 A8
01: Device address, the device address is 1
10: Function code, currently 10 write request
00 00: Register starting address, starting from the 00 00 register to write
00 02 : Write the register length, write 2 lengths, corresponding to the next 4 bytes of data
04: Data length, including 4 bytes of data
00 00: Register 1 value
00 0A: Register 2 value
73 A8: CRC checksum
Write a request reply:
01 10 00 00 00 02 41 C8
01: Device address, the device address is 1
10: Function code
00 00: Register starting address
00 02: Write register length, write 2 lengths
41 C8: CRC checksum
Master node sends frame format (writes a single register):
Normal response frame format from the node:
Master node sends frame format (write multiple registers):
Normal response frame format from the node:
Modbus
Communication tool learning
Virtual serial port debugging tool
Configure Virtual Serial Port Driver
Simulate two serial ports, COM2
,COM3
Modbus Poll
It can be understood as a Modbus terminal , and the simulation program sends various instructions to the device.
Common Functions:
1. connection: Set the connection method
2. Setup Read/Write sets the address, function code, register starting address, length, collection interval and other information of the communication device.
Modbus Slave
It can be understood as the device side of Modbus , which simulates the device responding to the instructions sent by the program.
1. connection: Set the connection method
2. Setup Definition sets the address, function code, register starting address, length and other information of the communication device.
Communication test
Click the button in the red box in the picture to view real-time instructions
TX: command sent
RX: response command
Modbus-Java toolkit
-
modbus4j
: Supports three protocolsModbus-RTU
: , ,Modbus-ASCII
and . It supports , , and . However, this tool is synchronous and does not support asynchronous, so it can be used if real-time requirements are not strong .Modbus-TCP
Modbus-RTU over Serial
Modbus-RTU over TCP/UDP
Modbus-ASCII over Serial
Modbus-TCP over TCP/UDP
-
jlibmodbus
: SupportModbus-RTU
twoModbus-TCP
protocols, supportModbus-RTU over Serial
,Modbus-RTU over TCP
,Modbus-TCP over TCP
, andModbus-TCP
internally support asynchronous support through socket.Modbus-RTU Serial
ThroughRXTX
implementation. -
modbus-master-tcp
: SupportsModbus-TCP
a protocol that supports asynchronous implementationModbus-TCP over TCP
internally .netty
Extensions can be implemented to supportModbus-RTU over TCP
andModbus-RTU over Serial
.
Note: All connections of the above three tool kits do not have disconnection and reconnection functions , so you need to solve the problem of disconnection and reconnection by yourself when using them.
Modbus4J
maven depends on coordinates
<dependency>
<groupId>com.infiniteautomation</groupId>
<artifactId>modbus4j</artifactId>
<version>3.0.3</version>
</dependency>
Java tool class
import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.locator.BaseLocator;
import com.serotonin.modbus4j.msg.ReadMultipleRegistersRequest;
import com.serotonin.modbus4j.msg.ReadMultipleRegistersResponse;
import com.serotonin.modbus4j.msg.WriteRegistersRequest;
import com.serotonin.modbus4j.msg.WriteRegistersResponse;
public class ModbusUtils {
private ModbusMaster modbusMaster;
/**
* 创建ModbusMaster实例并设置主机和端口
*/
public ModbusUtils(String host, int port) {
ModbusFactory modbusFactory = new ModbusFactory();
modbusMaster = modbusFactory.createTcpMaster(true);
modbusMaster.setHost(host);
modbusMaster.setPort(port);
}
/**
* 初始化ModbusMaster并建立与Modbus设备的连接
*/
public void connect() throws ModbusInitException {
modbusMaster.init();
}
/**
* 关闭与Modbus设备的连接
*/
public void disconnect() {
modbusMaster.destroy();
}
/**
* 读取Modbus设备寄存器的值
* slaveId 设备序列号
* startOffset 读取寄存器开始的地址
* numberOfRegisters 读取连续的几个寄存器
*/
public int[] readHoldingRegisters(int slaveId, int startOffset, int numberOfRegisters) throws ModbusTransportException {
ReadMultipleRegistersRequest request = new ReadMultipleRegistersRequest(slaveId, startOffset, numberOfRegisters);
ReadMultipleRegistersResponse response = (ReadMultipleRegistersResponse) modbusMaster.send(request);
return response.getIntData();
}
/**
* 向Modbus设备的保持寄存器写入值
* slaveId 设备序列号
* startOffset 写入寄存器开始的地址
* values 写入寄存器里的值
*/
public void writeHoldingRegisters(int slaveId, int startOffset, int[] values) throws ModbusTransportException {
WriteRegistersRequest request = new WriteRegistersRequest(slaveId, startOffset, values);
modbusMaster.send(request);
}
}
Call test
public class Main {
public static void main(String[] args) {
ModbusUtils modbusUtils = new ModbusUtils("192.168.0.1", 502);
try {
modbusUtils.connect();
// 读取保持寄存器
int[] values = modbusUtils.readHoldingRegisters(1, 0, 5);
System.out.println("读取的保持寄存器值:" + Arrays.toString(values));
// 写入保持寄存器
int[] writeValues = {10, 20, 30};
modbusUtils.writeHoldingRegisters(1, 0, writeValues);
System.out.println("写入保持寄存器成功");
} catch (Exception e) {
e.printStackTrace();
} finally {
modbusUtils.disconnect();
}
}
}