ModPackQTModPackQT
Node-RED ExamplesResourcesSign up
HomeResourcesNode-RED ExamplesWrite Multiple Registers — Including FLOAT32 (FC16)
WritesNode-RED Modbus Example

Write Multiple Registers — Including FLOAT32 (FC16)

FC16 writes a block of consecutive holding registers atomically. This is how you write FLOAT32 values (2 registers), INT32 values, or set several parameters at once. The example writes a 32-bit float setpoint (AB-CD byte order) to registers 10–11.

What you need

  • Node-RED v3+
  • node-red-contrib-modbus installed
  • Modbus device with writable holding registers

Flow Overview


200.0 as IEEE-754 float = 0x43480000

AB-CD byte order:
  register 10 = 0x4348 (high word)
  register 11 = 0x0000 (low word)

┌────────────┐   ┌─────────────────────────────────┐   ┌────────────────────────┐
│ Inject 200 │──▶│ Function: float → [0x4348,0x0000]│──▶│ FC16 write regs 10–11  │
└────────────┘   └─────────────────────────────────┘   └────────────────────────┘

Node-RED Flow JSON

Node-RED Flow JSON
[
  {"id":"inj9","type":"inject","name":"Write 200.0°C","payload":"200","payloadType":"num","wires":[["fn9"]],"x":120,"y":900},
  {"id":"fn9","type":"function","name":"Float32 to 2 registers (AB-CD)","func":"const val = parseFloat(msg.payload);
const buf = Buffer.alloc(4);
buf.writeFloatBE(val, 0);
const hi = buf.readUInt16BE(0);
const lo = buf.readUInt16BE(2);
msg.payload = { value: [hi, lo], address: 10, quantity: 2, unitid: 1, fc: 16 };
return msg;","wires":[["req9"]],"x":360,"y":900},
  {"id":"req9","type":"modbus-flex-write","name":"FC16 Write 2 regs","server":"srv1","wires":[["dbg11"],[]],"x":590,"y":900},
  {"id":"dbg11","type":"debug","name":"Write result","active":true,"wires":[],"x":790,"y":900},
  {"id":"srv1","type":"modbus-client","name":"My Slave","clienttype":"tcp","tcpHost":"192.168.1.100","tcpPort":502,"unit_id":1}
]

To import: open Node-RED → Hamburger menu → Import → paste this JSON → Deploy.

Expected Output

msg.payload = {
  success: true,
  data: { address: 10, quantity: 2 }
}
// Registers 10 and 11 now contain 200.0 as FLOAT32 AB-CD

Common Gotchas

  • Use buf.writeFloatBE for AB-CD (big-endian), or swap hi/lo assignment for CD-AB (word-swap).
  • For CD-AB: assign hi = buf.readUInt16BE(2) and lo = buf.readUInt16BE(0) — just swap the two values.
  • The value field in the payload must be an array for FC16, e.g. [hi, lo] — not a single number.
  • fc must be 16 (number) in the payload — not the string '16'.
  • Writing out of range addresses returns exception 02; ensure registers 10–11 both exist and are writable.

Same in ModPackQT — in 30 seconds

ModPackQT lets you type a float value directly into a register row, select the byte order, and write — it handles the split into two registers and FC16 formatting automatically.

Was this example helpful?

More Writes examples

All Node-RED Modbus Examples (30)

ModPackQT · Node-RED Modbus Examples · Updated 2026