Modbus
Modbus RTU Client Subsystem Documentation
Section titled “Modbus RTU Client Subsystem Documentation”Overview
Section titled “Overview”This document describes the classes, structures, and enums involved in the Modbus RTU Client functionality within the firmware. This subsystem is primarily managed by the ModbusRTU
class and is responsible for communicating with downstream Modbus RTU slave devices over a serial (RS485) connection. It often works in conjunction with the Modbus TCP server (ModbusManager
) to act as a TCP-to-RTU gateway.
The core tasks include queuing read/write operations, managing communication timing, handling retries and errors, caching slave data, and providing an interface to interact with the RTU devices.
Key Classes
Section titled “Key Classes”ModbusRTU
Section titled “ModbusRTU”- Header:
src/ModbusRTU.h
- Source:
src/ModbusRTU.cpp
- Purpose: The central class managing Modbus RTU client communication. It uses the
eModbus
library’sModbusClientRTU
internally. - Responsibilities:
- Initializes the RTU client and serial port.
- Manages a queue (
operationQueue
) of pendingModbusOperation
requests. - Handles the execution of operations, respecting timing intervals (
minOperationInterval
). - Processes responses and errors from the
eModbus
library via callbacks (onDataReceived
,onErrorReceived
). - Maintains a cache (
slaveData
) of the last known values for registers and coils on each slave device usingSlaveData
andModbusValueEntry
. - Provides public methods (
readCoil
,writeRegister
, etc.) to queue operations. - Manages an optional filter chain (
ModbusOperationFilter
) to preprocess outgoing operations (e.g., prevent duplicates, rate limit). - Provides status information (error counts, success rates).
- Handles adaptive timing adjustments if
ENABLE_ADAPTIVE_TIMEOUT
is defined.
BaseModbusDevice
Section titled “BaseModbusDevice”- Header:
src/ModbusTypes.h
- Source:
src/ModbusTypes.cpp
- Purpose: Represents the state and basic interaction logic for a single external Modbus RTU slave device being managed by
ModbusRTU
. - Responsibilities:
- Stores the slave ID (
deviceId
). - Tracks the device’s communication state (
E_DeviceState
: IDLE, RUNNING, ERROR). - Manages communication timing (timeout, sync interval) and error counts for the specific device.
- Holds collections (
inputRegisters
,outputRegisters
) ofRegisterState
objects representing the data points on the slave. - Provides methods to add/manage
RegisterState
objects (addInputRegister
,addOutputRegister
). - Provides methods to interact with the device’s registers via the
ModbusRTU
manager (initialize
,syncFromDevice
,writeOutputs
). - Provides local accessors for register values (
getInputRegisterValue
,getOutputRegisterValue
,setOutputRegisterValue
). - Includes helper methods for state management (
printState
,reset
,runTestSequence
).
- Stores the slave ID (
ModbusDeviceState
Section titled “ModbusDeviceState”- Header:
src/ModbusDeviceState.h
- Source:
src/ModbusDeviceState.cpp
- Purpose: A derived class of
BaseModbusDevice
. Intended for application-specific implementations or specializations of Modbus RTU slave devices. - Responsibilities:
- Currently, mainly overrides
setState
to add specific logging. - Its constructor can be used to add specific default registers required by the application logic using the
addInputRegister
/addOutputRegister
methods inherited fromBaseModbusDevice
.
- Currently, mainly overrides
RegisterState
Section titled “RegisterState”- Header:
src/ModbusTypes.h
- Source:
src/ModbusTypes.cpp
- Purpose: Represents a single data point (Input Register, Holding Register, Coil, or Discrete Input) on an external Modbus RTU slave device.
- Responsibilities:
- Stores the register type (
RegType
), Modbus address, current value, min/max values (for validation), and priority. - Provides methods (
readFromDevice
,writeToDevice
) to queue corresponding read/write operations via theModbusRTU
manager. - Includes helper methods for boolean conversion (
getBoolValue
,setBoolValue
) and printing state (printState
).
- Stores the register type (
Supporting Structures
Section titled “Supporting Structures”ModbusOperation
Section titled “ModbusOperation”- Header:
src/ModbusTypes.h
- Purpose: Represents a single Modbus read or write request waiting to be executed or currently in progress. Stored in the
ModbusRTU
’soperationQueue
. - Key Members:
timestamp
: When the operation was created.token
: Unique identifier used byeModbus
library for asynchronous handling.address
,value
,quantity
: Modbus request parameters.slaveId
: Target slave device.type
: The type of operation (E_MB_OpType
).status
: Current status (E_MB_OpStatus
: PENDING, SUCCESS, FAILED, RETRYING).retries
: Number of times execution has been attempted.flags
: Bit flags indicating state (USED, HIGH_PRIORITY, IN_PROGRESS, BROADCAST, SYNCHRONIZED).
ModbusValueEntry
Section titled “ModbusValueEntry”- Header:
src/ModbusTypes.h
- Purpose: Represents a cached value for a single register or coil address on a specific slave. Used within the
SlaveData
structure. - Key Members:
address
: The Modbus address.value
: The last known value.lastUpdate
: Timestamp of the last update.synchronized
: Flag indicating if the cached value is believed to be in sync with the device.used
: Flag indicating if this entry is actively used.
SlaveData
Section titled “SlaveData”- Header:
src/ModbusTypes.h
- Purpose: Holds the cached data for a single Modbus RTU slave device managed by
ModbusRTU
. An array ofSlaveData
is stored inModbusRTU
. - Key Members:
coils
: Fixed-size array ofModbusValueEntry
for coils.registers
: Fixed-size array ofModbusValueEntry
for registers.coilCount
,registerCount
: Number of used entries in the arrays.
Operation Filtering
Section titled “Operation Filtering”ModbusOperationFilter
(Base Class)
Section titled “ModbusOperationFilter (Base Class)”- Header:
src/ModbusTypes.h
- Purpose: Abstract base class for filters that can be chained together to process
ModbusOperation
requests before they are queued for execution byModbusRTU
. - Key Methods:
filter(op)
: Pure virtual method; derived classes implement logic here. Returnstrue
to allow the operation,false
to drop it.process(op)
: Processes the operation through the current filter and the rest of the chain.setNext(filter*)
,getNext()
: Manage the filter chain links.notifyOperationExecuted(op)
,notifyOperationCompleted(op)
: Optional methods for stateful filters.getType()
: Returns the filter type (E_FilterType
).
Derived Filter Classes
Section titled “Derived Filter Classes”- Header:
src/ModbusTypes.h
- Source:
src/ModbusTypes.cpp
- Classes:
DuplicateOperationFilter
: Prevents queuing an operation if an identical one (same slave, type, address) is already pending in theModbusRTU
queue. Requires a pointer to theModbusRTU
instance.RateLimitFilter
: Enforces a minimum time interval between consecutive operations passing through it.PriorityFilter
: Currently a placeholder; intended to potentially adjust operation priority flags (though filtering itself always returns true).OperationLifecycleFilter
: Drops operations that have exceededMAX_RETRIES
or have timed out (OPERATION_TIMEOUT
).
Key Enums
Section titled “Key Enums”E_MB_OpType
: (src/ModbusTypes.h
) Defines the type of Modbus operation (READ_COIL, WRITE_REGISTER, etc.).E_MB_OpStatus
: (src/ModbusTypes.h
) Defines the status of a queuedModbusOperation
(PENDING, SUCCESS, FAILED, RETRYING).MB_Error
: (src/ModbusTypes.h
) Comprehensive error codes, combining standard Modbus exceptions, internal queue/operation errors, andeModbus
communication errors.E_FilterType
: (src/ModbusTypes.h
) Identifies the type of aModbusOperationFilter
.E_DeviceState
: (src/ModbusTypes.h
) State of aBaseModbusDevice
(IDLE, RUNNING, ERROR).RegType
: (src/ModbusTypes.h
) Type of aRegisterState
(INPUT, HOLDING, COIL, DISCRETE_INPUT).E_InitState
: (src/ModbusRTU.h
) Internal state for theModbusRTU
class initialization process.
Key Constants
Section titled “Key Constants”MAX_MODBUS_SLAVES
: (src/ModbusTypes.h
) Max number of RTU slaves the client can manage.MAX_ADDRESSES_PER_SLAVE
: (src/ModbusTypes.h
) Size of theModbusValueEntry
arrays withinSlaveData
.MAX_PENDING_OPERATIONS
: (src/ModbusTypes.h
) Size of theModbusRTU
operation queue.MAX_RETRIES
: (src/ModbusTypes.h
) Default max retries for a failing operation.OPERATION_TIMEOUT
: (src/ModbusTypes.h
) Default timeout for an operation before being considered failed/expired byOperationLifecycleFilter
.BAUDRATE
: (src/ModbusTypes.h
) Default serial baud rate for RS485.PRIORITY_*
Defines: (src/ModbusTypes.h
) Constants used for settingRegisterState
priorities.OP_FLAG_*
Defines: (src/ModbusTypes.h
) Bit flags used withinModbusOperation.flags
.
Callback Functions
Section titled “Callback Functions”ResponseCallback
: (src/ModbusTypes.h
) typedefvoid (*ResponseCallback)(uint8_t slaveId)
. Can be set onModbusRTU
to trigger custom logic when any response (success or error) is received for a slave.OnRegisterChangeCallback
: (src/ModbusTypes.h
) typedefvoid (*OnRegisterChangeCallback)(const ModbusOperation& op, uint16_t oldValue, uint16_t newValue)
. Set onModbusRTU
to be notified when a successful read operation results in a changed value in the cache.OnWriteCallback
: (src/ModbusTypes.h
) typedefvoid (*OnWriteCallback)(const ModbusOperation& op)
. Set onModbusRTU
to be notified when a write operation completes successfully.OnErrorCallback
: (src/ModbusTypes.h
) typedefvoid (*OnErrorCallback)(const ModbusOperation& op, int errorCode, const char* errorMessage)
. Set onModbusRTU
to be notified when an operation fails (either timeout, Modbus exception, or internal error).