Modbus RTU protocol + debugging tool + java tool class

If the spring breeze feels pity for the flowers, can it allow me to stay young again?

Modbus RTUCommunication protocol instruction learning

Modbus RTUThe 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:

  • MSBIndicates high byte, LSBindicates 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:

ModbusCommunication 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

  1. modbus4j: Supports three protocols Modbus-RTU: , , Modbus-ASCIIand . 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-TCPModbus-RTU over SerialModbus-RTU over TCP/UDPModbus-ASCII over SerialModbus-TCP over TCP/UDP

  2. jlibmodbus: Support Modbus-RTUtwo Modbus-TCPprotocols, support Modbus-RTU over Serial, Modbus-RTU over TCP, Modbus-TCP over TCP, and Modbus-TCPinternally support asynchronous support through socket. Modbus-RTU SerialThrough RXTXimplementation.

  3. modbus-master-tcp: Supports Modbus-TCPa protocol that supports asynchronous implementation Modbus-TCP over TCPinternally . nettyExtensions can be implemented to support Modbus-RTU over TCPand Modbus-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();
        }
    }
}

Guess you like

Origin blog.csdn.net/2301_76354366/article/details/131963186