Expand description
§mbus-client
mbus-client is a high-level, no_std compatible Modbus client implementation.
It provides a structured way to interact with Modbus servers (slaves) over various
transport layers like TCP, RTU, or ASCII.
§Core Concepts
ClientServices: The central coordinator. It manages the lifecycle of a request, including ADU construction, transmission, response tracking, timeouts, and retries.Transport: An abstraction over the physical or link layer. This allows the client to work seamlessly over hardware-specific UARTs, TCP sockets, or custom implementations.AppTraits: A set of traits (e.g.,CoilResponse,RegisterResponse) that the user implements to receive asynchronous-style callbacks when a response is parsed.
§Features
- Pipelining: Supports multiple concurrent outstanding requests (configurable via const generics).
- Reliability: Built-in support for automatic retries and configurable response timeouts.
- Memory Safety: Uses
heaplessfor all internal buffering, ensuring zero dynamic allocation and suitability for hard real-time or embedded systems. - Protocol Coverage: Implements standard function codes for coils, discrete inputs, holding/input registers, FIFO queues, and file records.
§Example Usage
// These core imports are always available
use mbus_core::transport::{UnitIdOrSlaveAddr, ModbusConfig, ModbusTcpConfig, Transport, TransportType, TimeKeeper};
use mbus_core::errors::MbusError;
// 1. Define your application state and implement response traits
// Application traits and service modules are feature-gated.
// To use Coil services, enable the "coils" feature in Cargo.toml.
struct MyDevice;
#[cfg(feature = "coils")]
impl CoilResponse for MyDevice {
fn read_coils_response(&mut self, txn_id: u16, unit_id: UnitIdOrSlaveAddr, coils: &Coils) {
// Handle the data here
}
// Implement other CoilResponse methods or use default empty implementations if not needed
fn read_single_coil_response(&mut self, _: u16, _: UnitIdOrSlaveAddr, _: u16, _: bool) {}
fn write_single_coil_response(&mut self, _: u16, _: UnitIdOrSlaveAddr, _: u16, _: bool) {}
fn write_multiple_coils_response(&mut self, _: u16, _: UnitIdOrSlaveAddr, _: u16, _: u16) {}
}
// 2. Initialize transport and config
let transport = YourTransport::new();
let config = ModbusConfig::Tcp(ModbusTcpConfig::new("192.168.1.10", 502)?);
// 3. Create the service (N=5 allows 5 concurrent requests)
let mut client = ClientServices::<_, _, 5>::new(transport, MyDevice, config)?;
client.connect()?;
// 4. Send a request (only available if the "coils" feature is enabled)
#[cfg(feature = "coils")]
{
client.coils().read_multiple_coils(1, UnitIdOrSlaveAddr::new(1)?, 0, 8)?;
}
// 5. Periodically poll to process incoming bytes and handle timeouts
loop {
client.poll();
}Modules§
- app
- Application-level traits and callback definitions. Users implement these to handle data returned by the Modbus server. These modules are conditionally compiled based on features. Modbus Application Layer Module
- services
- Internal Modbus services.
Contains logic for specific function codes (Coils, Registers, etc.) and
the core
ClientServicesorchestration logic.