The Viam Modbus module enables seamless communication with modbus devices by acting as a client. It allows for reading and writing (currently only in module version 0.4.x, version 0.5.x WIP) of coils or registers on the server, enabling efficient data exchange and operational command execution.
This repository contains the clientand sensor components which abstract away a modbus interface and its registers.
The Viam client component(s) allows you to configure the modbus clients and the sensor component(s) allow you to read and write modbus registers.
The module can easily be installed via the Viam registry: Viam Modbus Module
⚠️ Warning:
Module version0.5.xis a complete overhaul of version 4 and contains small breaking changes! Upgrade instructions: UPGRADE.md
Configuration Instructions for previous versions: Versions <= 0.4.x
The Viam modbus client component supports connections over tcp and serial. Which mode is used, depends on the modbus.url prefix as explained below.
As with any other Viam module you can apply the configuration to your component into the Configure section.
Add this to your modbus client component for TCP or serial communication.
| Name | Type | Inclusion | Applies | Description |
|---|---|---|---|---|
url |
string | Required | TCP & RTU | TCP: "tcp://hostname-or-ip-address:502" / serial: "rtu://<serial device path>" |
timeout_ms |
string | Optional | TCP & RTU | Connection timeout |
endianness |
string | Optional | TCP & RTU | One of big or little. Default big |
word_order |
string | Optional | TCP & RTU | One of high or low first. Default high |
speed |
string | Optional | RTU | Default 19200 Bit (bit/s) |
data_bits |
uint | Optional | RTU | Default 8 |
parity |
uint | Optional | RTU | Default 0 -> none |
stop_bits |
uint | Optional | RTU | Default 2 if parity is none |
tls_client_cert |
string | Optional | TCP | Not implemented yet |
tls_root_cas |
string | Optional | TCP | Not implemented yet |
Add this to your modbus client component for serial communication.
{
"url": "rtu:///dev/tty...",
"speed": 9600
}{
"url": "tcp://192.168.1.124:502",
"timeout_ms": 10000
}The modbus sensor component allows you to read modbus coils and register values.
| Name | Type | Inclusion | Description |
|---|---|---|---|
modbus_connection_name |
string | Required | Provide the nameof the Modbus client configured |
blocks |
[]Block | Required | Registers etc. to read see below |
unit_id |
int | Optional | Optionally set the unit id, valid range 0-247 |
component_type |
string | Optional | Viam component type - a construct to aggregrate a block of registers |
component_description |
string | Optional | Viam component description - what this block of registers represents |
| Name | Type | Inclusion | Description |
|---|---|---|---|
name |
string | Required | Name of the key for the value being read |
type |
string | Required | "input_registers" | "discrete_inputs" | "coils" | "holding_registers" |
offset |
int | Required | Register address decimal |
length |
int | Required | Number of words to include from register address |
unit_id |
int | Optional | Set the unit id, valid range 0-247 |
{
"modbus_connection_name": "client",
"unit_id": 1,
"component_type": "tank",
"component_description": "Main storage fuel tank",
"blocks": [
{
"length": 1,
"name": "TankLevelMax",
"offset": 20,
"type": "input_registers"
},
{
"length": 1,
"name": "TankLevelActual",
"offset": 21,
"type": "holding_registers"
},
{...}
]
}| Register Type | Access | Size | Features |
|---|---|---|---|
| Coil (discrete output) | Read-write | 1 bit | Read/Write on/off value |
| Discrete input | Read-only | 1 bit | Read on/off value |
| Input register | Read-only | 16 bits (0-65,535) | Read measurements and statuses |
| Holding register | Read-write | 16 bits (0-65,535) | Read/Write configuration values |
Often, a block of registers will provide values for a single "thing". The "thing" might be a tank, engine, battery, etc.
A Viam modbus sensor might be an aggregation of these registers. Not part of the modbus protocol specification, Viam recommends
grouping these registers into a sensor, defining a block of registers in an array, and giving the sensor a component_type
and a component_description. For example, a tank sensor might be described by several registers; the max capacity of
the tank, the actual level of the tank, the percentage full of the tank. An engine might be many dozens of registers that
describe the fuel pressure, fuel consumption rate, RPMs, turbocharger, exhaust gas temp, load. Listing them individually would
be redundant.
The modbus registers returned are raw values and it might be difficult to discern what the units of measure are for each
particular register. Another useful Viam technique is to give the block name values with meaningful descriptions.
For example, in the case of a tank component, these block name key/value pairs
"attributes": {
"modbus_connection_name": "modbus-yacht",
"component_type": "tank",
"component_description": "Fuel tank - Port",
"blocks": [
{
"name": "level_%",
...
},
{
"name": "max_L",
...
},
{
"name": "actual_L",
...
}
]
} For TCP there is a useful public modbus server available: https://modbus.pult.online/
Modbus test utilities are helpful:
- Add write capability to v5
- Authentication
- Simon Vetter Go Modbus Library