Modbus TCP Data Writing with modbus4j in Java

Maven Dependency Configuration

Add the modbus4j dependency to your pom.xml. Note that some mirror repositories (e.g., Alibaba's) might not host this artifact; using the default Maven central repository is recommended.

<dependency>
    <groupId>com.infiniteautomation</groupId>
    <artifactId>modbus4j</artifactId>
    <version>3.0.3</version>
</dependency>

Establishing a Modbus TCP Master Connection

Create a connection to the Modbus slave using IP parameters and initialize the master.

import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.ip.IpParameters;

public class ModbusConnector {
    private static final ModbusFactory FACTORY = new ModbusFactory();

    public static ModbusMaster connect(String host, int port) throws Exception {
        IpParameters params = new IpParameters();
        params.setHost(host);
        params.setPort(port);
        ModbusMaster master = FACTORY.createTcpMaster(params, false);
        master.init();
        return master;
    }
}

Writing to Digital Outputs (Coils)

Single Coil (Function Code 5)

Set the state of a single coil.

import com.serotonin.modbus4j.msg.WriteCoilRequest;
import com.serotonin.modbus4j.msg.WriteCoilResponse;

public static boolean setCoil(ModbusMaster master, int unitId, int offset, boolean state)
        throws Exception {
    WriteCoilRequest request = new WriteCoilRequest(unitId, offset, state);
    WriteCoilResponse response = (WriteCoilResponse) master.send(request);
    return !response.isException();
}

Multiple Coils (Function Code 15)

Write a sequence of boolean values to consecutive coils.

import com.serotonin.modbus4j.msg.WriteCoilsRequest;
import com.serotonin.modbus4j.msg.WriteCoilsResponse;

public static boolean setMultipleCoils(ModbusMaster master, int unitId,
                                       int startOffset, boolean[] values) throws Exception {
    WriteCoilsRequest request = new WriteCoilsRequest(unitId, startOffset, values);
    WriteCoilsResponse response = (WriteCoilsResponse) master.send(request);
    return !response.isException();
}

Writing Holding Registers

Single Register (Function Code 6)

Write a 16-bit value to a holding register.

import com.serotonin.modbus4j.msg.WriteRegisterRequest;
import com.serotonin.modbus4j.msg.WriteRegisterResponse;

public static boolean writeSingleRegister(ModbusMaster master, int unitId,
                                          int registerOffset, short data) throws Exception {
    WriteRegisterRequest request = new WriteRegisterRequest(unitId, registerOffset, data);
    WriteRegisterResponse response = (WriteRegisterResponse) master.send(request);
    if (response.isException()) {
        System.err.println(response.getExceptionMessage());
        return false;
    }
    return true;
}

Multiple Registers (Function Code 16)

Write an array of 16-bit values starting at a given offset.

import com.serotonin.modbus4j.msg.WriteRegistersRequest;
import com.serotonin.modbus4j.msg.ModbusResponse;

public static boolean writeMultipleRegisters(ModbusMaster master, int unitId,
                                             int startOffset, short[] data) throws Exception {
    WriteRegistersRequest request = new WriteRegistersRequest(unitId, startOffset, data);
    ModbusResponse response = master.send(request);
    if (response.isException()) {
        System.err.println(response.getExceptionMessage());
        return false;
    }
    return true;
}

Advanced Value Writing with Data Types

For analog values like floats, doubles, or integers of various sizes, you can use locators with a specified data type to write direct.

import com.serotonin.modbus4j.locator.BaseLocator;
import com.serotonin.modbus4j.code.DataType;

public static void writeTypedValue(ModbusMaster master, int unitId,
                                   int registerOffset, Number value, int dataType) throws Exception {
    BaseLocator<Number> locator = BaseLocator.holdingRegister(unitId, registerOffset, dataType);
    master.setValue(locator, value);
}

Example Usage

The following snippet demonstrates how to connect and perform various write operations. (A Modbus slave, either real or simulated, must be running to test these calls.)

public static void main(String[] args) {
    try {
        ModbusMaster master = ModbusConnector.connect("localhost", 502);

        // Write a single coil
        boolean coilResult = setCoil(master, 1, 0, true);
        System.out.println("Coil write success: " + coilResult);

        // Write multiple coils
        boolean coilsResult = setMultipleCoils(master, 1, 0,
                               new boolean[]{true, false, true});
        System.out.println("Multiple coils write success: " + coilsResult);

        // Write a single register
        boolean regResult = writeSingleRegister(master, 1, 0, (short) 323764);
        System.out.println("Register write success: " + regResult);

        // Write multiple registers
        boolean regsResult = writeMultipleRegisters(master, 1, 0,
                               new short[]{-3, 3, 9});
        System.out.println("Multiple registers write success: " + regsResult);

        // Write a float value using data type
        writeTypedValue(master, 1, 1, 1.1f, DataType.FOUR_BYTE_FLOAT);
        System.out.println("Float value written.");

        master.destroy();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Tags: java Modbus tcp modbus4j Holding Register

Posted on Fri, 10 Jul 2026 17:10:01 +0000 by habbardone