πŸ“¦ Archived documentation: r1 (committed 2026-07-24) View current documentation β†’

modbus

Modbus TCP/serial master and a script-managed slave register table.

The modbus object works in two directions:

Register data is packed binary β€” use the bin buffer read/write methods with format strings like "F32BADC" or "U32DCBA" to convert between registers and numbers. Test slave tables with the free modpoll tool.

Function codes 1, 2 and 15 expect a bit array rather than register data.

Functions

modbus.connect()

modbus.connect(host, port, unitId) β†’ number

Opens a Modbus TCP connection to a remote device.

Arguments

NameTypeRequiredDefaultDescription
host string yes β€” IP address of the Modbus device, e.g. "172.16.220.111".
port number yes β€” TCP port, normally 502.
unitId number yes β€” Slave unit ID.

Returns

number 0 on success, otherwise an error code.

Example

let ret = modbus.connect("172.16.220.111", 502, 1);
if(ret === 0){
  // read / write ...
  modbus.disconnect();
} else {
  print("Modbus Connect Failed, err=", ret);
}

modbus.read()

modbus.read(port, unitId, fc, startReg, count) β†’ { status, data }

Reads registers or coils from a Modbus slave.

Reads from a connected slave and returns { status, data } where status is 0 on success and data is a binary buffer. Parse the buffer with data.seek(0) then repeated data.read(format) calls.

Arguments

NameTypeRequiredDefaultDescription
port number yes β€” Communication port: 0 = TCP, >0 = Hardware Serial Port (serial ports need serial.init() first).
unitId number yes β€” Slave unit ID.
fc number yes β€” Modbus function code, e.g. 3/4 = read registers. FCs 1/2 return a bit array.
startReg number yes β€” Starting register address, e.g. 0x88B9.
count number yes β€” Number of registers or coils to read.

Returns

object { status, data } β€” status 0 = success; data is a bin buffer.

Example

let ret = modbus.read(0,       // 0=tcp, >0 = physical serial port
                      1,       // slave unitID
                      4,       // function code
                      0x88B9,  // start register
                      30);     // register count

if(ret.status === 0){
  ret.data.seek(0);
  let data = {
    meanWindSpeed:     ret.data.read("U32DCBA")/10, // m/s
    meanWindDirection: ret.data.read("U32")/10,     // degrees
    airTemp:           ret.data.read("S32")/10,     // Β°C
  };
  print(string(data));
} else {
  print("Read Failed, err=", string(ret));
}

modbus.write()

modbus.write(port, unitId, functionCode, startReg, count, data) β†’ number

Writes registers or coils to a Modbus slave.

Writes packed binary data to the slave. Build the buffer from a numeric array with bin.fromArray(array, format, byteOrder).

Arguments

NameTypeRequiredDefaultDescription
port number yes β€” Communication port: 0 = TCP, >0 = Hardware Serial Port (serial ports need serial.init() first).
unitId number yes β€” Slave unit ID.
functionCode number yes β€” Function code, e.g. 16 = write multiple registers. FC 15 expects a bit array.
startReg number yes β€” Starting register address.
count number yes β€” Number of registers or coils to write.
data bin buffer yes β€” Packed data, e.g. from bin.fromArray([1,2,3], "U16", "AB").

Returns

number 0 on success, otherwise an error code.

Example

let arrayData = [1,2,3,4,5,6,7,8];
let data = bin.fromArray(arrayData, "U16", "AB");

let ret = modbus.write(0, 1, 16, 0, arrayData.length, data);
if(ret === 0){ print("Write Successful"); }
else { print("Modbus Write Failed, err=", ret); }

modbus.setData()

modbus.setData(buffer)

Backs the device Modbus slave register table with a script-managed bin buffer.

Points the device's Modbus TCP slave data table at a buffer allocated with bin.alloc(). Remote clients then read and write your table; your script updates it through the buffer's seek/read/write methods, guarded by modbus.setLock().

Arguments

NameTypeRequiredDefaultDescription
buffer bin buffer yes β€” Buffer from bin.alloc(bytes) sized for your registers (4 bytes per 32-bit value).

Example

let mbData = bin.alloc(20*4);  // room for float registers
modbus.setData(mbData);        // expose as the slave data table

modbus.setLock()

modbus.setLock(locked) β†’ boolean

Locks/unlocks the slave data table so clients never read a half-updated table.

Lock the table before updating it from your script, then unlock so clients can read and write again. modbus.setLock(true) returns true when the lock was acquired.

Arguments

NameTypeRequiredDefaultDescription
locked boolean yes β€” true to lock the table, false to unlock.

Returns

boolean true when the lock state was applied.

Example

if(modbus.setLock(true)){
  mbData.seek(0);
  mbData.write("F32BADC", [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]);
  mbData.write("U32BADC", 23.33);
  modbus.setLock(false);
}

modbus.disconnect()

modbus.disconnect()

Closes the master connection to the remote Modbus device.

Example

modbus.disconnect();