Modbus read task
Read the coils and registers of a Modbus TCP server into channels.
A Modbus read task reads coils and registers from one Modbus server into channels. For example, it can record a tank level from holding registers 0 and 1 of a PLC at 10 Hz.
Before you start, you need a connected server.
Registers and coils
A read task reads four types of data, each with its own address range:
A register holds 16 bits. An 8-bit or 16-bit value uses one register, and an 8-bit value is the low byte. A 32-bit value uses two registers, and a 64-bit value uses four. The Data type of the channel sets the size.
For each type, the Driver reads all addresses from the lowest to the highest in one request. One request can hold at most 125 registers or 2000 coils or discrete inputs.
The Driver timestamps each read with the computer clock. See timing.
Byte and word order
By default, the Driver reads the low word of a 32-bit or 64-bit value first. Many devices send the high word first. The Swap words switch of the server puts the high word first, and Swap bytes swaps the two bytes in each register. The switches set the order for every register channel of the server.
To change the order of one channel, use its Bytes and Words selects. Each select has three options:
- device -> uses the switch of the server, and shows its value, such as device (swapped).
- swapped -> swaps the order of this channel, whatever the server sets.
- not swapped -> does not swap the order of this channel, whatever the server sets.
The Console hides Words for 8-bit and 16-bit data types, because they fit in one
register. In code, leave bytes_swapped and words_swapped unset to use the order of
the server.
Create a Modbus read task
Console
Python
TypeScript
- In the devices toolbar, right-click the server and select Create read task.
- Set Sample rate and Stream rate.
- Click Add channel. Select the type, then enter the address. For a register, select the Data type.
- Click (Start).
The Console creates the channels. For the server Pump skid PLC, a float32 holding
register at address 0 gives Pump_skid_PLC_holding_register_input_0_f32, and a coil at
address 3 gives Pump_skid_PLC_coil_input_3. The index channel is Pump_skid_PLC_time.
Python does not create channels. Create them first.
import synnax as sy
from synnax import modbus
dev = client.devices.retrieve(name="Pump skid PLC")
time = client.channels.create(
name="plc_time", is_index=True, data_type=sy.DataType.TIMESTAMP
)
level = client.channels.create(
name="tank_level", index=time.key, data_type=sy.DataType.FLOAT32
)
pump_on = client.channels.create(
name="pump_on", index=time.key, data_type=sy.DataType.UINT8
)
task = modbus.ReadTask(
name="Pump skid",
device=dev.key,
sample_rate=10,
stream_rate=5,
channels=[
modbus.HoldingRegisterReadChannel(
address=0, data_type="float32", words_swapped=True, channel=level.key
),
modbus.CoilReadChannel(address=3, channel=pump_on.key),
],
)
client.tasks.configure(task)
task.start()TypeScript does not create channels. Create them first.
import { modbus } from "@synnaxlabs/client";
const [dev] = await client.devices.retrieve({ names: ["Pump skid PLC"] });
const time = await client.channels.create({
name: "plc_time",
isIndex: true,
dataType: "timestamp",
});
const level = await client.channels.create({
name: "tank_level",
index: time.key,
dataType: "float32",
});
const task = await client.tasks.create({
name: "Pump skid",
rack: dev.rack,
type: "modbus_read",
config: modbus.readConfigZ.parse({
device: dev.key,
sampleRate: 10,
streamRate: 5,
channels: [
{
type: "holding_register",
address: 0,
dataType: "float32",
wordsSwapped: true,
channel: level.key,
},
],
}),
});
await task.start();Task options
Channel reference
Each channel has an address, from 0 to 65535, and a channel, the Synnax channel that
records the value. Each table shows the Console label of a setting, with its Python
field under it.
Troubleshooting
“Illegal data address”
The server does not have one of the addresses in the task. Check the address map of the device. Some devices count addresses from 1, so try the address minus 1.
“unsupported data type: …”
The Console also lists the boolean, timestamp, and uuid data types, but the Driver
does not support them. Select a data type from the
channel reference.
“Too many data”
The addresses of one type span more than one request can hold. Move the channels closer together, or split them into two tasks.
The values are wrong
Set the byte and word order of the server or the channel. Check that the data type matches the device.
The task stopped when the connection dropped
The task stops on any connection error. Start the task again when the server is back.
For other problems, see Connect a Modbus server and Troubleshoot hardware.