Skip to main content

SdoClient

Struct SdoClient 

Source
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

Source

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");
Source

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
§Example
// Set modes_of_operation to Profile Position (1)
let tid = sdo.write(ctx.client, 0x6060, 0, json!(1));
Source

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 — the CommandClient from TickContext
  • index — CoE object dictionary index (e.g. 0x6064)
  • sub_index — CoE sub-index (usually 0)
§Example
// Read the actual position value
let tid = sdo.read(ctx.client, 0x6064, 0);
Source

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
§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);
    }
}
Source

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));
Source

pub fn pending_count(&self) -> usize

Number of in-flight SDO requests.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V