PhloemDocs
Markdown
Connector

Modbus

Read and write Modbus TCP and RTU devices

Category
Industrial
Kind
source
Capabilities
StreamsAssetsCommandsOperationsEntities
Runs on
Linux x64Linux ARM64macOS Apple siliconmacOS IntelWindows x64

Read and write PLCs, power meters, sensors and process controllers over Modbus TCP or serial (RTU). One connector covers any Modbus device: you describe yours with a register map. No code needed.

What you get

  • Live readings — each mapped value is its own channel, scaled into engineering units.
  • Setpoints — values marked writable can be set from Trellis via ch.write(path, value). Each write is read back, so you see what the device took.
  • One device per input, named by its Device name. Channels read /modbus/plc1/….

Setup

  1. Note the device's address and unit ID (usually 1). The standard Modbus TCP port is 502. For an RTU device, note its serial port (/dev/ttyUSB0, COM3) and line settings.
  2. In Inputs, choose Add input, pick modbus, and fill in:
    • Device name — a short label, e.g. plc1
    • Connection — 192.168.1.60:502, or the serial port for RTU
    • Transport — tcp (default) or rtu. RTU uses Serial baud rate / parity / stop bits / data bits (default 9600 8N1).
    • Model — pick a built-in map, or paste your device's map into Register map. Each entry names a value, its address, type and scaling.
  3. Press Test connection. It reads the first mapped register, so a pass means the device answered.
  4. Channels appear on Live. Writable entries are available in Trellis.
  5. In the Channels table, give a channel a name and unit, such as temp → bearing temperature, degC.

Register map example

[
  {"alias": "temp", "address": 0, "kind": "input", "dtype": "i16",
   "scale": {"gain": 0.1, "offset": 0}, "unit": "degC"},
  {"alias": "pump_speed_sp", "address": 10, "kind": "holding",
   "dtype": "u16", "unit": "rpm", "writable": true}
]
  • Addresses are zero-based: a manual's 40001 is address 0.
  • Types: u16, i16, u32, i32, f32, and bool for coils and discrete inputs.
  • For a 32-bit value sent low word first, set word_swap.

Dead-man (heartbeat)

If this computer hangs, loses power or loses the network, a Modbus output keeps its last value. A dead-man lets your PLC take over. While a test setup is deployed, Phloem keeps changing a heartbeat register. Your PLC drives its outputs safe when the heartbeat stops changing.

Your PLC needs a few lines of logic, or a drive's communication-loss setting:

  • The heartbeat is one holding register (u16).
  • 0 means "not supervised": do nothing while it reads 0.
  • Any other value must change at least once per timeout. If it does not, drive the outputs to their safe states.

Then fill in the input's Dead-man section:

  • Heartbeat register — the alias of that register in your map. Map it without writable, so a test setup can never write it.
  • PLC timeout (s) — the timeout you set in the PLC. Phloem uses it to decide how often to write.
  • Outputs the PLC drives safe — the writable aliases your PLC makes safe. Outputs you leave out show as not credited to the dead-man.
{"alias": "heartbeat", "address": 100, "kind": "holding", "dtype": "u16"}

When a setup is undeployed, Phloem writes 0. The PLC stops supervising and leaves the outputs where they are. Pick a timeout longer than your slowest write; a few seconds suits most networks.

Notes

  • A device we have never seen works as soon as you paste its map.
  • Writes are checked against the map before they are sent. Every write is recorded.

#Supports

  • Any Modbus-TCP device via a register map (paste your device's map)
  • Any Modbus-RTU (serial) device via the same register map

#Connection fields

Every field the Add input form shows for this connector.

FieldTypeRequiredDefault
Device name
plc1
TextYes—
Connection (host:port or serial device)
192.168.1.60:502 | /dev/ttyUSB0
TextYes—
Transport
tcp | rtu
Text—tcp
Serial baud rate (RTU)
9600
Number—9600
Serial parity (RTU)
none | even | odd
Text—none
Serial stop bits (RTU)
1 | 2
Number—1
Serial data bits (RTU)
8
Number—8
Unit ID
1
Number—1
Model (built-in map)
leave empty when pasting a map
Text——
Register map (JSON)
[{"alias":"temp","address":40001,...}]
Text——
Poll rate (Hz)
1
Number—1
Heartbeat register (alias)
The alias of a one-word holding register your PLC watches. Map it read-only: the connector writes it, a document never can. Empty = no dead-man.
heartbeat
Text——
PLC timeout (s)
How long your PLC waits on an unchanged heartbeat before it drives the outputs safe — the value configured in the PLC.
2
Number——
Outputs the PLC drives safe
The writable aliases your PLC drives to a safe state when the heartbeat stops.
valve, pump_speed_sp
Text——

Updated