pub struct DiscreteInputs { /* private fields */ }Expand description
A collection of discrete input states retrieved from a Modbus server.
This structure maintains the context of the read operation (starting address and quantity)
and stores the actual bit-packed values in a memory-efficient heapless::Vec, making it
suitable for no_std and embedded environments.
Use the value() method to extract individual boolean states without
manually performing bitwise operations.
§Internal Representation
The values array stores these discrete input states. Each byte in values holds 8 input states,
where the least significant bit (LSB) of the first byte (values[0]) corresponds to the
from_address, the next bit to from_address + 1, and so on. This bit-packing is efficient
for memory usage and network transmission.
The MAX_DISCRETE_INPUT_BYTES constant ensures that the values array has enough space to
accommodate the maximum possible number of discrete inputs allowed in a single Modbus PDU
(MAX_DISCRETE_INPUTS_PER_PDU).
§Examples
use mbus_core::models::discrete_input::{DiscreteInputs, MAX_DISCRETE_INPUT_BYTES};
use mbus_core::errors::MbusError;
// Initialize a block of 8 discrete inputs starting at Modbus address 100.
// Initially all inputs are OFF (0).
let mut inputs = DiscreteInputs::new(100, 8).unwrap();
// Verify initial state: all inputs are false
assert_eq!(inputs.value(100).unwrap(), false);
assert_eq!(inputs.value(107).unwrap(), false);
// Simulate receiving data where inputs at offsets 0 and 2 are ON (0b0000_0101)
let received_data = [0x05, 0x00, 0x00, 0x00]; // Only the first byte is relevant for 8 inputs
inputs = inputs.with_values(&received_data, 8).expect("Valid quantity and data");
// Read individual input values
assert_eq!(inputs.value(100).unwrap(), true); // Address 100 (offset 0) -> LSB of 0x05 is 1
assert_eq!(inputs.value(101).unwrap(), false); // Address 101 (offset 1) -> next bit is 0
assert_eq!(inputs.value(102).unwrap(), true); // Address 102 (offset 2) -> next bit is 1
assert_eq!(inputs.value(107).unwrap(), false); // Address 107 (offset 7) -> MSB of 0x05 is 0
// Accessing values out of bounds will return an error
assert_eq!(inputs.value(99), Err(MbusError::InvalidAddress));
assert_eq!(inputs.value(108), Err(MbusError::InvalidAddress));
// Get the raw bit-packed bytes (only the first byte is active for 8 inputs)
assert_eq!(inputs.values(), &[0x05]);Implementations§
Source§impl DiscreteInputs
impl DiscreteInputs
Sourcepub fn new(
from_address: u16,
quantity: u16,
) -> Result<DiscreteInputs, MbusError>
pub fn new( from_address: u16, quantity: u16, ) -> Result<DiscreteInputs, MbusError>
Creates a new DiscreteInputs instance representing a block of read-only discrete inputs.
The internal values array is initialized to all zeros, meaning all discrete inputs
are initially considered OFF (false).
§Arguments
from_address- The starting Modbus address for this block of inputs.quantity- The total number of discrete inputs contained in this block.
§What happens:
- The
quantityis validated to ensure it does not exceedMAX_DISCRETE_INPUTS_PER_PDU. - A new
DiscreteInputsinstance is created with the specifiedfrom_addressandquantity. - The internal
valuesarray, which stores the bit-packed states, is initialized to all0u8s.
§Errors
Returns MbusError::InvalidQuantity if the requested quantity exceeds
MAX_DISCRETE_INPUTS_PER_PDU.
§Returns
A new initialized DiscreteInputs instance.
Sourcepub fn with_values(
self,
values: &[u8],
bits_length: u16,
) -> Result<DiscreteInputs, MbusError>
pub fn with_values( self, values: &[u8], bits_length: u16, ) -> Result<DiscreteInputs, MbusError>
Sets the bit-packed values for the discrete inputs and validates the length.
This method is typically used to populate a DiscreteInputs instance with actual
data received from a Modbus server. It copies the relevant portion of the provided
values slice into the internal fixed-size buffer.
§Arguments
values- A slice of bytes containing the bit-packed states. This slice should be at least as long as the number of bytes required to storebits_lengthinputs.bits_length- The number of bits (inputs) actually contained in the provided values. This parameter specifies the actual number of bits (discrete inputs) present in thevaluesslice, which should typically match thequantityof theDiscreteInputsinstance.
§What happens:
- The
bits_lengthis checked against thequantityof theDiscreteInputsinstance. - The necessary number of bytes (
byte_length) is calculated frombits_length. - The relevant portion of the input
valuesslice is copied into the internalself.valuesarray.
§Errors
Returns MbusError::InvalidQuantity if bits_length does not match self.quantity.
Sourcepub fn from_address(&self) -> u16
pub fn from_address(&self) -> u16
Returns the starting Modbus address of the first discrete input in this block.
Sourcepub fn quantity(&self) -> u16
pub fn quantity(&self) -> u16
Returns the total number of discrete inputs managed by this instance.
Sourcepub fn values(&self) -> &[u8] ⓘ
pub fn values(&self) -> &[u8] ⓘ
Returns a reference to the active bytes containing the bit-packed input states.
This method returns a slice &[u8] that contains only the bytes relevant to the
quantity of discrete inputs managed by this instance. It does not return the
entire MAX_DISCRETE_INPUT_BYTES array if quantity is smaller.
The length of the returned slice is calculated as ceil(self.quantity / 8).
Sourcepub fn value(&self, address: u16) -> Result<bool, MbusError>
pub fn value(&self, address: u16) -> Result<bool, MbusError>
Retrieves the boolean state of a specific input by its address.
This method performs boundary checking to ensure the requested address is within the range [from_address, from_address + quantity).
§Arguments
address- The Modbus address of the discrete input to query.
§What happens:
- Boundary Check: The
addressis validated to ensure it falls within the range[self.from_address, self.from_address + self.quantity). - Bit Index Calculation: The
bit_index(zero-based offset fromfrom_address) is calculated. - Byte and Bit Position: The
byte_index(bit_index / 8) determines which byte in thevaluesarray contains the target bit, andbit_in_byte(bit_index % 8) determines its position within that byte. - Masking: A
bit_mask(e.g.,0b0000_0001for bit 0,0b0000_0010for bit 1) is created to isolate the specific bit. - Extraction: A bitwise AND operation (
&) with thebit_maskis performed on the relevant byte. If the result is non-zero, the bit is ON (true); otherwise, it’s OFF (false).
§Returns
Ok(true)if the input is ON (1).Ok(false)if the input is OFF (0).Err(MbusError::InvalidAddress)if the address is out of the block’s range.
Trait Implementations§
Source§impl Clone for DiscreteInputs
impl Clone for DiscreteInputs
Source§fn clone(&self) -> DiscreteInputs
fn clone(&self) -> DiscreteInputs
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more