easymodbus4j

repository·master·Indexed 42 days ago

https://github.com/zengfr/easymodbus4j

A high-performance Java implementation of the Modbus protocol built on Netty. It supports TCP and RTU protocols with flexible deployment modes for Master/Slave and Client/Server roles. Features include the DeviceClient for sending commands, ChannelSender for request handling, and support for custom ModbusChannelInitializer configurations.

Tokens
3.1K
Snippets
12
Records
16
Agent score
52%

What's inside easymodbus4j

  1. Implement Modbus Handlers for Master and Slave

    master

    Easymodbus4j requires you to implement specific interfaces to handle Modbus communication logic depending on whether your component acts as a Master or a Slave.

    For Master (Client) roles:

    • Implement the ResponseHandler interface.
    • OR implement the ModbusMasterResponseProcessor interface and use it with new ModbusMasterResponseHandler(responseProcessor).

    For Slave (Server) roles:

    • Implement the RequestHandler interface.
    • OR implement the ModbusSlaveRequestProcessor interface and use it with new ModbusSlaveRequestHandler(reqProcessor).
  2. Install easymodbus4j via Maven

    master

    To use easymodbus4j in your Java project, add the following dependencies to your pom.xml. Note that you typically need the client, server, and extension modules to implement full Modbus functionality.

    <dependency>
      <groupId>com.github.zengfr</groupId>
      <artifactId>easymodbus4j-client</artifactId>
      <version>0.0.5</version>
    </dependency>
    <dependency>
      <groupId>com.github.zengfr</groupId>
      <artifactId>easymodbus4j-server</artifactId>
      <version>0.0.5</version>
    </dependency>
    <dependency>
      <groupId>com.github.zengfr</groupId>
      <artifactId>easymodbus4j-extension</artifactId>
      <version>0.0.5</version>
    </dependency>
  3. Implement Modbus Handlers

    master

    You must implement handlers to process Modbus requests (for Slaves/Servers) or responses (for Masters/Clients).

    For Master Mode (Client/Server)

    Implement the ResponseHandler interface or the ModbusMasterResponseProcessor interface. If using the processor, wrap it using new ModbusMasterResponseHandler(responseProcessor).

    For Slave Mode (Client/Server)

    Implement the RequestHandler interface or the ModbusSlaveRequestProcessor interface. If using the processor, wrap it using new ModbusSlaveRequestHandler(reqProcessor).

  4. Select a Modbus Deployment Mode

    master

    Easymodbus4j supports 8 deployment modes across TCP and RTU protocols. Use the corresponding Factory to instantiate your client or server.

    TCP Modes

    • TCP Server Master: ModbusServerTcpFactory.getInstance().createServer4Master(port, responseHandler)
    • TCP Client Slave: ModbusClientTcpFactory.getInstance().createClient4Slave(host, port, requestHandler)
    • TCP Client Master: ModbusClientTcpFactory.getInstance().createClient4Master(host, port, responseHandler)
    • TCP Server Slave: ModbusServerTcpFactory.getInstance().createServer4Slave(port, requestHandler)

    RTU Modes

    • RTU Server Master: ModbusServerRtuFactory.getInstance().createServer4Master(port, responseHandler)
    • RTU Client Slave: ModbusClientRtuFactory.getInstance().createClient4Slave(host, port, requestHandler)
    • RTU Client Master: ModbusClientRtuFactory.getInstance().createClient4Master(host, port, responseHandler)
    • RTU Server Slave: ModbusServerRtuFactory.getInstance().createServer4Slave(port, requestHandler)
  5. Send Modbus Requests

    master

    To send data, retrieve a Channel from your client or server, obtain a ChannelSender via the ChannelSenderFactory, and call the appropriate function method.

    Note: Since connections are established asynchronously, it is recommended to wait briefly (e.g., Thread.sleep) after opening a connection before sending requests.

    // Wait for async connection
    Thread.sleep(3*1000);
    
    // Get channel and sender
    Channel channel = client.getChannel();
    ChannelSender sender = ChannelSenderFactory.getInstance().get(channel);
    
    // Send requests
    sender.readCoils(...);
    sender.readDiscreteInputs(...);
    sender.writeSingleRegister(...);
  6. Use DeviceClient.sendCommand2 for multiple coil or register writes

    master

    When performing operations that involve writing multiple coils or multiple registers, use the DeviceClient.sendCommand2 method. This is specifically intended for use with the following function codes:

    • WRITE_MULTIPLE_COILS (0x0F)
    • WRITE_MULTIPLE_REGISTERS (0x10)

    Method Signature: DeviceClient.sendCommand2(String host, int port, DeviceCommand<T> cmd);

    DeviceClient.sendCommand2(String host, int port, DeviceCommand<T> cmd);
  7. Send Modbus Requests using ChannelSender

    master

    To send a request, obtain the Channel from your client or server, then use a ChannelSender obtained from the ChannelSenderFactory.

    // For a client
    Channel channel = client.getChannel();
    // For a server
    // Channel channel = server.getChannelsBy(...);
    
    ChannelSender sender = ChannelSenderFactory.getInstance().get(channel);
    
    // Example requests
    sender.readCoils(...);
    sender.readDiscreteInputs(...);
    sender.writeSingleRegister(...);
  8. Initialize Modbus TCP and RTU Modes

    master

    Use the factory classes to create your Modbus instances. The library supports 8 deployment modes by combining Master/Slave and Client/Server roles across TCP and RTU protocols.

    // TCP Modes
    modbusServer = ModbusServerTcpFactory.getInstance().createServer4Master(port, responseHandler);
    modbusClient = ModbusClientTcpFactory.getInstance().createClient4Slave(host, port, requestHandler);
    
    modbusClient = ModbusClientTcpFactory.getInstance().createClient4Master(host, port, responseHandler);
    modbusServer = ModbusServerTcpFactory.getInstance().createServer4Slave(port, requestHandler);
    
    // RTU Modes
    modbusServer = ModbusServerRtuFactory.getInstance().createServer4Master(port, responseHandler);
    modbusClient = ModbusClientRtuFactory.getInstance().createClient4Slave(host, port, requestHandler);
    
    modbusClient = ModbusClientRtuFactory.getInstance().createClient4Master(host, port, responseHandler);
    modbusServer = ModbusServerRtuFactory.getInstance().createServer4Slave(port, requestHandler);
  9. Process Modbus Responses and Requests

    master

    Data processing occurs within the implementation of your handler's response/request methods. You can check the type of the response object (e.g., ReadCoilsResponse) to extract specific data.

    public void processResponseFrame(Channel channel, int unitId, AbstractFunction reqFunc, ModbusFunction respFunc) {
    	if (respFunc instanceof ReadCoilsResponse) {
    		ReadCoilsResponse resp = (ReadCoilsResponse) respFunc;
    		ReadCoilsRequest req = (ReadCoilsRequest) reqFunc;
    		// process business logic for req/resp
    	}
    	if (respFunc instanceof ReadDiscreteInputsResponse) {
    		ReadDiscreteInputsResponse resp = (ReadDiscreteInputsResponse) respFunc;
    		byte[] resutArray = resp.getInputStatus().toByteArray();
    	}
    }
  10. Process Modbus Request/Response Frames

    master

    In your handler's processResponseFrame method, you can cast the respFunc to specific response types to access the data.

    Example of processing a ReadCoilsResponse:

    public void processResponseFrame(Channel channel, int unitId, AbstractFunction reqFunc, ModbusFunction respFunc) {
        if (respFunc instanceof ReadCoilsResponse) {
            ReadCoilsResponse resp = (ReadCoilsResponse) respFunc;
            ReadCoilsRequest req = (ReadCoilsRequest) reqFunc;
            // process business logic for req/resp
        }
    }

    To get the raw byte array for custom decoding (e.g., from ReadDiscreteInputsResponse):

    if (respFunc instanceof ReadDiscreteInputsResponse) {
        ReadDiscreteInputsResponse resp = (ReadDiscreteInputsResponse) respFunc;
        byte[] resultArray = resp.getInputStatus().toByteArray();
    }
  11. Customizing Modbus Channel Initialization

    master

    You can provide a custom ModbusChannelInitializer to the factory to advance the configuration of your client or server.

    ModbusChannelInitializer modbusChannelInitializer = ...;
    ModbusServerTcpFactory.getInstance().createServer4Master(port, modbusChannelInitializer);