mbus-client
Modbus client state machine for Rust — poll-driven, no_std compatible, zero heap allocation.
Features
- Poll-driven — no threads, no blocking I/O
- no_std compatible — runs on embedded MCUs
- Transport agnostic — TCP, Serial RTU, Serial ASCII
- All standard FCs — coils, registers, discrete inputs, FIFO, file records, diagnostics
- Configurable retry — exponential/linear/fixed backoff with optional jitter
Quick Start
use ;
let config = new?;
let mut client = new?;
client.connect?;
client.coils.read_coils?;
loop
Documentation
| Topic | Link |
|---|---|
| Quick Start | documentation/client/quick_start.md |
| Building Apps | documentation/client/building_applications.md |
| Feature Flags | documentation/client/feature_flags.md |
| Architecture | documentation/client/architecture.md |
Related Crates
| Crate | Purpose |
|---|---|
modbus-rs |
Top-level convenience crate |
mbus-core |
Shared protocol types |
mbus-async |
Tokio async facade |
mbus-network |
TCP transport |
mbus-serial |
Serial RTU/ASCII transport |
- Runtime-safe path:
ClientServices::new(...)validates serialN == 1. - Compile-time-safe path:
ClientServices::new_serial(...)enforcesN == 1. - Recommended type alias:
SerialClientServices<TRANSPORT, APP>.
Feature Flags
This crate uses selective compilation so you only build required protocol services.
Available features:
coilsregistersdiscrete-inputsfifofile-recorddiagnosticsserial-ascii(forwards tombus-core/serial-asciito enable ASCII-sized ADU buffers)traffic(enables raw TX/RX frame callbacks viaTrafficNotifier)logging(enables low-priority internal state-machine diagnostics via thelogfacade)
Default behavior:
defaultenables all service features above.
Feature forwarding:
- Each feature forwards to the equivalent model feature in
mbus-core.
Example (minimal feature set):
[]
= { = "0.6.0", = false, = ["coils"] }
Traffic Callbacks (optional traffic feature)
When traffic is enabled, apps can implement TrafficNotifier to observe raw ADU frames:
use ;
use UnitIdOrSlaveAddr;
;
Logging
mbus-client can emit low-priority internal diagnostics through the log facade when the
logging feature is enabled.
These logs are intentionally limited to debug and trace so applications can filter them
without treating normal control-flow events as warnings or errors.
Examples of logged events:
- frame parse/resynchronization
- response dispatch matching
- timeout scans and retry scheduling
- retry send failures
- pending-request flush during connection loss or reconnect
Typical filtering example:
RUST_LOG=mbus_client=trace
Usage Pattern
Typical flow:
- Implement required callback traits in your app type.
- Provide a
Transportimplementation (custom,mbus-network, ormbus-serial). - Build a
ModbusConfig. - Construct
ClientServices. - Issue requests.
- Call
poll()periodically to process responses and timeouts.
Minimal Example
use ;
use ;
use Vec;
;
;
Feature-Scoped Access Style
ClientServices now supports feature facades so request APIs can be grouped by domain:
client.coils()client.registers()client.discrete_inputs()client.diagnostic()client.fifo()client.file_records()
For grouped request submission in a single scoped borrow, use batch helpers:
client.with_coils(...)client.with_registers(...)client.with_discrete_inputs(...)client.with_diagnostic(...)client.with_fifo(...)client.with_file_records(...)
Build Examples
From workspace root:
# default services
# only coils service
# registers + discrete inputs only
Notes
- This crate is
no_stdfriendly and usesheaplessinternally. - Service and callback traits are conditionally compiled by feature flags.
- Use exact feature names with hyphens:
discrete-inputsfile-record
License
This crate is licensed under GPL-3.0-only.
If you require a commercial license to use this crate in a proprietary project, please contact ch.raghava44@gmail.com to purchase a license.
Disclaimer
This is an independent Rust implementation of the Modbus specification and is not affiliated with the Modbus Organization.
Contact
For questions or support:
- Name: Raghava Ch
- Email: ch.raghava44@gmail.com