pub struct SdoClient { /* private fields */ }Expand description
Non-blocking SDO client scoped to a single EtherCAT device.
Create one SdoClient per device in your control program struct. It holds
a map of outstanding requests keyed by transaction_id (returned by
CommandClient::send). Keep the returned handle and poll
result() each tick until it resolves.
§Example
use autocore_std::ethercat::{SdoClient, SdoResult};
use serde_json::json;
use std::time::Duration;
let mut sdo = SdoClient::new("ClearPath_0");
// Issue an SDO write (from process_tick):
let tid = sdo.write(ctx.client, 0x6060, 0, json!(1));
// Check result on subsequent ticks:
match sdo.result(ctx.client, tid, Duration::from_secs(3)) {
SdoResult::Pending => {}
SdoResult::Ok(_) => { /* success */ }
SdoResult::Err(e) => { log::error!("SDO error: {}", e); }
SdoResult::Timeout => { log::error!("SDO timed out"); }
}Implementations§
Source§impl SdoClient
impl SdoClient
Sourcepub fn new(device: &str) -> Self
pub fn new(device: &str) -> Self
Create a new client for the given device name.
The device string must match the name field in the slave’s
project.json configuration (e.g. "ClearPath_0").
let sdo = SdoClient::new("ClearPath_0");Sourcepub fn write(
&mut self,
client: &mut CommandClient,
index: u16,
sub_index: u8,
value: Value,
) -> u32
pub fn write( &mut self, client: &mut CommandClient, index: u16, sub_index: u8, value: Value, ) -> u32
Issue an SDO write (CoE download).
Sends a command to topic ethercat.{device}.sdo_write with payload:
{"index": "0x6060", "sub": 0, "value": 1}Returns a transaction handle for use with result().
§Arguments
client— theCommandClientfromTickContextindex— CoE object dictionary index (e.g.0x6060)sub_index— CoE sub-index (usually0)value— the value to write, as aserde_json::Value
§Example
// Set modes_of_operation to Profile Position (1)
let tid = sdo.write(ctx.client, 0x6060, 0, json!(1));Sourcepub fn read(
&mut self,
client: &mut CommandClient,
index: u16,
sub_index: u8,
) -> u32
pub fn read( &mut self, client: &mut CommandClient, index: u16, sub_index: u8, ) -> u32
Issue an SDO read (CoE upload).
Sends a command to topic ethercat.{device}.sdo_read with payload:
{"index": "0x6064", "sub": 0}Returns a transaction handle for use with result().
§Arguments
client— theCommandClientfromTickContextindex— CoE object dictionary index (e.g.0x6064)sub_index— CoE sub-index (usually0)
§Example
// Read the actual position value
let tid = sdo.read(ctx.client, 0x6064, 0);Sourcepub fn result(
&mut self,
client: &mut CommandClient,
tid: u32,
timeout: Duration,
) -> SdoResult
pub fn result( &mut self, client: &mut CommandClient, tid: u32, timeout: Duration, ) -> SdoResult
Check the result of a previous SDO request.
Call this each tick with the handle returned by write()
or read(). The result is consumed (removed from the
internal map) once it resolves to Ok,
Err, or Timeout.
§Arguments
client— theCommandClientfromTickContexttid— transaction handle returned bywrite()orread()timeout— maximum time to wait before returningSdoResult::Timeout
§Example
match sdo.result(ctx.client, tid, Duration::from_secs(3)) {
SdoResult::Pending => { /* keep waiting */ }
SdoResult::Ok(data) => {
log::info!("SDO response: {}", data);
sm.index = next_state;
}
SdoResult::Err(e) => {
log::error!("SDO failed: {}", e);
sm.set_error(1);
}
SdoResult::Timeout => {
log::error!("SDO timed out");
sm.set_error(2);
}
}Sourcepub fn drain_stale(&mut self, client: &mut CommandClient, timeout: Duration)
pub fn drain_stale(&mut self, client: &mut CommandClient, timeout: Duration)
Remove all requests that have been pending longer than timeout.
Call periodically (e.g. once per second) to prevent the internal map from growing unboundedly if callers forget to check results.
§Example
// At the end of process_tick, clean up anything older than 10s
self.sdo.drain_stale(ctx.client, Duration::from_secs(10));Sourcepub fn pending_count(&self) -> usize
pub fn pending_count(&self) -> usize
Number of in-flight SDO requests.