### Complete PDO Workflow Example Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/pdo-interface.md Demonstrates a full PDO workflow: setting up the EtherCAT bus and device, starting the PDO loop, enabling a motor, queuing a position move, and monitoring its completion. Includes error handling and cleanup. ```python from cooethercat import ( EtherCATBus, MaxonEPOS4, PDOLoop, OperatingMode, ControlwordCommand ) # Setup bus and device bus = EtherCATBus("eth0") with bus: bus.scan() bus.configure() motor = MaxonEPOS4(bus, slave_index=0, name="motor_1") # Start PDO loop pdo_loop = PDOLoop(bus, period_s=0.002) pdo_loop.add_device(motor) pdo_loop.start() try: # Enable motor via SDO (one-time) motor.enable(timeout_s=3.0) # Queue position move via PDO (cyclic) motor.queue_profile_position_pdo( position=10000, velocity=5000, acceleration=15000, ) # Wait for completion by polling PDO inputs import time deadline = time.time() + 30.0 while time.time() < deadline: position = motor.position_pdo moving = motor.moving_pdo if not moving: print(f"Motion complete. Final position: {position}") break time.sleep(0.01) else: print("Motion timeout") finally: pdo_loop.stop() motor.disable_voltage(timeout_s=2.0) ``` -------------------------------- ### Full EtherCAT Setup with Maxon EPOS4 Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/configuration.md A comprehensive example demonstrating the initialization of an EtherCAT bus, scanning for slaves, configuring a Maxon EPOS4 motor, setting up a PDO loop for cyclic control, enabling the watchdog, configuring motion profiles, and executing a position command. ```python from cooethercat import ( EtherCATBus, MaxonEPOS4, PDOLoop, EtherCATState, CiA402State, OperatingMode, HomingMethod, PositionSource ) # Initialize bus bus = EtherCATBus("eth0") bus.open() slaves = bus.scan() bus.configure() # Setup motor motor = MaxonEPOS4(bus, slave_index=0, name="axis_1") # Setup PDO loop for cyclic control pdo_loop = PDOLoop(bus, period_s=0.002, timeout_us=2000, expected_working_counter=2) pdo_loop.add_device(motor) # Enable watchdog bus.set_watchdog(0, timeout_ms=50.0) # Configure motion motor.configure_profile_motion( velocity=5000, acceleration=15000, deceleration=15000, ) # Start PDO loop pdo_loop.start() try: # Enable motor motor.enable(timeout_s=3.0) # Queue motion motor.queue_profile_position_pdo(10000, velocity=5000, acceleration=15000) # Wait for completion import time while motor.moving_pdo: time.sleep(0.01) finally: # Cleanup pdo_loop.stop() motor.disable_voltage() bus.close() ``` -------------------------------- ### Example: Set PDO Outputs Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/maxon-epos4.md Demonstrates how to update multiple output PDO fields simultaneously using keyword arguments. This example sets the target position and profile velocity. ```python motor.set_pdo_outputs( target_position=5000, profile_velocity=3000, ) ``` -------------------------------- ### home Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/maxon-epos4.md Configures and starts homing immediately. Optionally waits for completion. ```APIDOC ## home ### Description Configure and start homing immediately. ### Parameters #### Path Parameters - **method** (HomingMethod) - Required - Homing method - **position_source** (PositionSource | None) - Optional - Home position source - **position** (int | None) - Optional - User home position - **current_threshold** (int) - Optional - Default: 400 - Current threshold - **wait** (bool) - Optional - Default: True - Wait for homing to complete - **timeout_s** (float) - Optional - Default: 30.0 - Timeout in seconds ### Returns Final statusword if `wait=True`, otherwise None. ### Raises `MaxonEPOS4Error` if homing fails; `TimeoutError` if timeout expires. ### Example ```python try: statusword = motor.home( method=HomingMethod.INDEX_POSITIVE_SPEED, position_source=PositionSource.SSI, wait=True, timeout_s=30.0, ) print("Homing successful") except (MaxonEPOS4Error, TimeoutError) as e: print(f"Homing failed: {e}") ``` ``` -------------------------------- ### setup_homing Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/maxon-epos4.md Configures EPOS4 homing parameters via SDO writes. Does not start homing; call `home()` to initiate. ```APIDOC ## setup_homing ### Description Configure EPOS4 homing parameters via SDO writes. Does not start homing; call `home()` to start. ### Parameters #### Path Parameters - **method** (HomingMethod) - Required - Homing method (e.g., INDEX_POSITIVE_SPEED) - **position_source** (PositionSource | None) - Optional - Home position source (SSI, CURRENT, USER) - **position** (int | None) - Optional - User-provided home position - **current_threshold** (int) - Optional - Default: 400 - Current threshold (mA) for switch detection - **homing_acceleration** (int) - Optional - Default: 5000 - Homing acceleration - **switch_search_speed** (int) - Optional - Default: 4000 - Speed for switch search - **zero_search_speed** (int) - Optional - Default: 2000 - Speed for zero search - **offset_distance** (int) - Optional - Default: 100 - Offset distance from home switch - **home_position** (int) - Optional - Default: 0 - Home position to assign - **timeout_s** (float) - Optional - Default: 1.0 - Timeout for mode transitions ### Example ```python motor.setup_homing( method=HomingMethod.INDEX_POSITIVE_SPEED, position_source=PositionSource.SSI, current_threshold=500, ) ``` ``` -------------------------------- ### Install cooethercat Package Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/quick-start.md Install the cooethercat library using pip. Ensure you have Python 3.12+ and pysoem installed. ```bash pip install cooethercat ``` -------------------------------- ### Initialize PDOLoop with a device Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/pdo-interface.md Demonstrates how to initialize the EtherCATBus, configure it, add a device (MaxonEPOS4 motor), and start the PDOLoop for cyclic PDO communication. ```python from cooethercat import EtherCATBus, MaxonEPOS4, PDOLoop bus = EtherCATBus("eth0") with bus: bus.scan() bus.configure() motor = MaxonEPOS4(bus, 0, name="axis_1") pdo_loop = PDOLoop(bus, period_s=0.002) pdo_loop.add_device(motor) pdo_loop.start() # Control via PDO motor.queue_profile_position_pdo(1000, velocity=5000, acceleration=15000) pdo_loop.stop() ``` -------------------------------- ### Set Operating Mode Example Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/types.md Demonstrates how to set the operating mode of a drive using the OperatingMode enum. ```python drive.set_operating_mode(OperatingMode.PROFILE_POSITION) # or drive.set_operating_mode(OperatingMode.HOMING) ``` -------------------------------- ### Handle PDOLoop Already Running Error Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/errors.md This example shows how to handle a PDOLoopAlreadyRunningError, which is raised when attempting to start a PDO loop that is already active. The PDOLoop class and its start method are used here. ```python pdo_loop = PDOLoop(bus) pdo_loop.start() try: pdo_loop.start() # Raises PDOLoopAlreadyRunningError except PDOLoopAlreadyRunningError: print("PDO loop already running") ``` -------------------------------- ### EtherCAT State Transitions Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/types.md Examples of how to set and wait for specific EtherCAT master states. Ensure the bus object is initialized before use. ```python bus.set_master_state(EtherCATState.PREOP) bus.wait_for_master_state(EtherCATState.OP) ``` -------------------------------- ### Configure and Start EPOS4 Homing Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/maxon-epos4.md Immediately configures and starts the homing process for the EPOS4 controller. It can optionally wait for completion and returns the statusword upon success or raises errors on failure or timeout. ```python try: statusword = motor.home( method=HomingMethod.INDEX_POSITIVE_SPEED, position_source=PositionSource.SSI, wait=True, timeout_s=30.0, ) print("Homing successful") except (MaxonEPOS4Error, TimeoutError) as e: print(f"Homing failed: {e}") ``` -------------------------------- ### Example of Maxon EPOS4 PDO-based motion queueing Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/MANIFEST.txt Demonstrates how to queue motion commands for a Maxon EPOS4 drive using PDOs. This allows for pre-programmed motion sequences to be executed efficiently. ```python from cooethercat.maxon_epos4 import MaxonEPOS4 # Assuming drive is an initialized MaxonEPOS4 instance drive: MaxonEPOS4 # Queue a position move command drive.queue_position_move(target_pos=10000, profile_velocity=5000) # Queue another command drive.queue_position_move(target_pos=5000, profile_velocity=5000) # Execute the queued commands drive.execute_motion_queue() ``` -------------------------------- ### Example of EtherCAT bus watchdog configuration Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/MANIFEST.txt Demonstrates how to configure the watchdog timeout for the EtherCAT bus. This ensures that communication is reset if a slave stops responding. ```python from cooethercat.ethercat_bus import EtherCATBus # Assuming bus is an initialized EtherCATBus instance bus: EtherCATBus # Set the watchdog timeout to 100 milliseconds bus.set_watchdog(timeout_ms=100) # Enable the watchdog bus.enable_watchdog() ``` -------------------------------- ### Example of custom PDO layout configuration Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/MANIFEST.txt Illustrates how to define and use a custom PDO layout for a device. This is useful when the default PDO mapping does not meet specific needs. ```python from cooethercat.pdo_interface import PDOLayout, PDOEntry # Define custom PDO entries custom_rx_pdo_entries = [ PDOEntry(index=0x6000, subindex=0x01, data_type='INT16'), PDOEntry(index=0x6000, subindex=0x02, data_type='UINT32') ] # Create a custom PDOLayout custom_layout = PDOLayout(name='CustomRxPDO', entries=custom_rx_pdo_entries) # Assuming bus is an initialized EtherCATBus instance bus: EtherCATBus # Configure the slave with the custom layout (example for slave index 2) bus.configure_pdo_layout(slave_idx=2, rx_pdo_layout=custom_layout) ``` -------------------------------- ### Example of SDO read/write Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/MANIFEST.txt Demonstrates how to perform Server Data Object (SDO) read and write operations on an EtherCAT bus. This is typically used for configuring device parameters. ```python from cooethercat.ethercat_bus import EtherCATBus # Assuming bus is an initialized EtherCATBus instance bus: EtherCATBus # Read from SDO index 0x1000, subindex 0x01 value = bus.sdo_read(slave_idx=1, index=0x1000, subindex=0x01) # Write to SDO index 0x1010, subindex 0x01 with value 0x0001 bus.sdo_write(slave_idx=1, index=0x1010, subindex=0x01, value=0x0001) ``` -------------------------------- ### profile_position_move_sdo Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/cia402-drive.md Start a profile-position move using SDO writes. For cyclic control, use PDO methods instead. ```APIDOC ## profile_position_move_sdo ### Description Start a profile-position move using SDO writes. For cyclic control, use PDO methods instead. ### Method Signature ```python def profile_position_move_sdo( self, position: int, *, velocity: int, acceleration: int, deceleration: int | None = None, absolute: bool = True, timeout_s: float = 2.0, ) -> None ``` ### Parameters #### Path Parameters - **position** (int) - Required - Target position - **velocity** (int) - Required - Profile velocity - **acceleration** (int) - Required - Profile acceleration - **deceleration** (int | None) - Optional - Profile deceleration - **absolute** (bool) - Optional - Absolute positioning; if False, relative - **timeout_s** (float) - Optional - Timeout for mode/enable transitions ``` -------------------------------- ### Example of CiA402 state transition Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/MANIFEST.txt Shows how to use the transition_sequence function to move a CiA402 compliant drive through its state machine. Ensure the drive is in the correct initial state before calling. ```python from cooethercat.cia402_drive import CiA402Drive, CiA402State # Assuming drive is an initialized CiA402Drive instance drive: CiA402Drive # Transition the drive to the 'Switched On Disabled' state try: drive.transition_sequence(target_state=CiA402State.SWITCHED_ON_DISABLED) except Exception as e: print(f"State transition failed: {e}") ``` -------------------------------- ### Example of PDO-based cyclic control Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/MANIFEST.txt Illustrates setting up and running cyclic control using Process Data Objects (PDOs). This is suitable for real-time control loops where data is exchanged periodically. ```python from cooethercat.pdo_interface import PDOLoop # Assuming bus is an initialized EtherCATBus instance bus: EtherCATBus # Initialize PDOLoop with the bus and desired cycle time pdo_loop = PDOLoop(bus=bus, cycle_time_ms=1) # Start the PDO loop in the background pdo_loop.start() # ... perform control operations ... # Stop the PDO loop when done pdo_loop.stop() ``` -------------------------------- ### Write Motion Command to Drive Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/types.md Example of how to write a motion command to a drive object. Ensure the `MotionCommand` enum is imported. ```python drive.write_controlword(MotionCommand.ABSOLUTE_START_IMMEDIATELY) ``` -------------------------------- ### Setup Homing with External Switch Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/configuration.md Configures homing using an external home switch. Define the home position and offset distance from the switch. ```python motor.setup_homing( method=HomingMethod.HOME_SWITCH_POSITIVE_SPEED, home_position=0, offset_distance=200, ) ``` -------------------------------- ### Configure EPOS4 Homing Parameters Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/maxon-epos4.md Sets up EPOS4 homing parameters via SDO writes. This function configures the homing process but does not start it; call `home()` separately to initiate homing. ```python motor.setup_homing( method=HomingMethod.INDEX_POSITIVE_SPEED, position_source=PositionSource.SSI, current_threshold=500, ) ``` -------------------------------- ### Fetch and Load Motor Configuration Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/INDEX.md Retrieve the current configuration of the motor and load a new configuration, for example, setting the nominal current in milliamperes. ```python config = motor.fetch_config() motor.load_config({"NOMINAL_CURRENT_MA": 5000}) ``` -------------------------------- ### Write Controlword Command to Drive Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/types.md Example of how to write a controlword command to a drive object. Ensure the `ControlwordCommand` enum is imported. ```python drive.write_controlword(ControlwordCommand.SWITCH_ON) ``` -------------------------------- ### Setup Current-Based Homing Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/configuration.md Configures homing based on motor current thresholds. Useful for detecting home via torque, especially when combined with other methods. ```python motor.setup_homing( method=HomingMethod.CURRENT_THRESHOLD_NEG_SPEED_AND_INDEX, position_source=PositionSource.USER, position=0, current_threshold=500, ) ``` -------------------------------- ### Control Drive via PDO (Cyclic Operations) Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/INDEX.md Sets up a periodic PDO loop for cyclic control and adds the drive to it. This is efficient for continuous or high-frequency movements. The example demonstrates queuing a profile position command and waiting for the movement to complete. ```python from cooethercat import PDOLoop pdo_loop = PDOLoop(bus, period_s=0.002) pdo_loop.add_device(motor) pdo_loop.start() motor.queue_profile_position_pdo(10000, velocity=5000, acceleration=15000) while motor.moving_pdo: sleep(0.01) pdo_loop.stop() ``` -------------------------------- ### Check Statusword Bit Example Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/types.md Shows how to read the drive's statusword and check for specific conditions using the StatuswordBit enum, such as confirming if a motion target has been reached. ```python statusword = drive.read_statusword() if StatuswordBit.TARGET_REACHED in statusword: print("Motion is complete") ``` -------------------------------- ### Initiate Profile Position Move via SDO Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/cia402-drive.md Starts a profile-position move using SDO writes. This is suitable for non-cyclic control. For cyclic control, PDO methods should be used. Supports absolute or relative positioning and configurable timeouts. ```python def profile_position_move_sdo( self, position: int, *, velocity: int, acceleration: int, deceleration: int | None = None, absolute: bool = True, timeout_s: float = 2.0, ) -> None ``` -------------------------------- ### Setup Homing with Encoder Index Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/configuration.md Configures homing using the encoder index pulse. Specify speeds and offsets for accurate home position detection. ```python motor.setup_homing( method=HomingMethod.INDEX_POSITIVE_SPEED, position_source=PositionSource.SSI, switch_search_speed=3000, zero_search_speed=1000, offset_distance=50, ) ``` -------------------------------- ### Home EPOS4 Motor with Actual Position and SSI Source Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/types.md Example of homing an EPOS4 motor using the ACTUAL_POSITION method, with the home position defined by an SSI absolute position sensor. Requires importing both HomingMethod and PositionSource. ```python motor.home( HomingMethod.ACTUAL_POSITION, position_source=PositionSource.SSI, ) ``` -------------------------------- ### Control Motor via Cyclic PDO Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/INDEX.md Set up a PDOLoop for cyclic communication, add the motor as a device, start the loop, queue a PDO command, and then stop the loop. This is for real-time control. ```python pdo_loop = PDOLoop(bus, period_s=0.002) pdo_loop.add_device(motor) pdo_loop.start() motor.queue_profile_position_pdo(target, velocity=5000, acceleration=15000) pdo_loop.stop() ``` -------------------------------- ### Enable CiA402 Drive Operation Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/cia402-drive.md Enable the drive for operation. If the drive is faulted, this function will reset the fault first. Use this to start drive operation. ```python def enable(self, *, timeout_s: float = 2.0) -> Statusword: # ... implementation details ... pass ``` ```python drive.enable(timeout_s=3.0) if drive.enabled: print("Drive is operational") ``` -------------------------------- ### Get PDO Outputs Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/maxon-epos4.md Retrieves the current output PDO values as a dictionary. This is useful for inspecting the device's current state before making changes. ```python def get_pdo_outputs(self) -> Mapping[str, Any] ``` -------------------------------- ### Get PDO Inputs Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/maxon-epos4.md Returns the latest received input PDO values as a dictionary. This allows for easy access to the current input state of the device. ```python def get_pdo_inputs(self) -> dict[str, Any] ``` -------------------------------- ### transition_sequence Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/cia402-drive.md Calculates the shortest sequence of controlword commands to transition between two CiA 402 states using a breadth-first search algorithm. It takes a starting state and a target state and returns a list of controlword commands. ```APIDOC ## Function: transition_sequence ### Description Return the shortest known sequence of controlword commands to transition from one state to another using breadth-first search. ### Parameters #### Path Parameters - **start** (CiA402State) - Required - Starting state - **target** (CiA402State) - Required - Target state ### Returns List of controlword commands in order. ### Raises `CiA402StateError` if no transition path exists. ### Example ```python commands = transition_sequence(CiA402State.READY_TO_SWITCH_ON, CiA402State.OPERATION_ENABLED) # Returns [ControlwordCommand.SWITCH_ON_AND_ENABLE_OPERATION] ``` ``` -------------------------------- ### Handle CiA402StateError Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/errors.md Catch errors when a CiA 402 state transition fails, such as when the current state is unknown or no valid transition path exists. This example demonstrates handling such errors and checking the drive's current state. ```python drive = CiA402Drive(bus, 0) try: drive.transition_to(CiA402State.OPERATION_ENABLED) except CiA402StateError as e: print(f"Cannot reach target state: {e}") print(f"Current state: {drive.state}") ``` -------------------------------- ### Perform a single PDO cycle Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/pdo-interface.md Executes one full PDO cycle, including writing outputs, exchanging process data, and reading inputs. It also includes an example of checking for and reporting deadline misses. ```python while True: stats = pdo_loop.cycle_once() if stats.deadline_miss_s > 0: print(f"Cycle deadline miss: {stats.deadline_miss_s * 1000:.2f} ms") ``` -------------------------------- ### Initialize and Open EtherCATBus Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/ethercat-bus.md Demonstrates how to initialize an EtherCATBus instance and open the network interface. It shows both manual open/close and context manager usage. ```python bus = EtherCATBus("eth0") bus.open() try: # Use bus pass finally: bus.close() # Or use as context manager with EtherCATBus("eth0") as bus: bus.scan() # Use bus ``` -------------------------------- ### PDOLoopAlreadyRunningError Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/errors.md Raised when attempting to start a PDO loop that is already in progress. ```APIDOC ## PDOLoopAlreadyRunningError ### Description Raised when attempting to start a PDO loop that is already running. This prevents duplicate PDO loop initializations. ### Import `from cooethercat import PDOLoopAlreadyRunningError` ### Example ```python pdo_loop = PDOLoop(bus) pdo_loop.start() try: pdo_loop.start() # Raises PDOLoopAlreadyRunningError except PDOLoopAlreadyRunningError: print("PDO loop already running") ``` ``` -------------------------------- ### Initialize PDOLoop with Options Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/configuration.md Configure PDOLoop with the EtherCAT bus instance. Adjust cycle period, timeout, expected working counter, and warning callbacks. ```python pdo_loop = PDOLoop( bus: EtherCATBus, *, period_s: float = 0.002, timeout_us: int = 2_000, expected_working_counter: int | None = None, on_warning: Callable[[str], None] | None = None, ) ``` ```python # Fast loop (1 ms cycle) pdo_loop = PDOLoop(bus, period_s=0.001, timeout_us=1000) ``` ```python # Standard loop (2 ms cycle) pdo_loop = PDOLoop(bus, period_s=0.002, timeout_us=2000, expected_working_counter=2) ``` ```python # Custom warning handler def my_warning(msg): print(f"[PDO Warning] {msg}") pdo_loop = PDOLoop(bus, on_warning=my_warning) ``` -------------------------------- ### transition_to Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/cia402-drive.md Moves the drive through the CiA 402 state machine using controlword commands to reach a target state. ```APIDOC ## transition_to ### Description Move the drive through the CiA 402 state machine using controlword commands. ### Method `transition_to(target: CiA402State, *, timeout_s: float = 2.0, poll_s: float | None = None) -> Statusword` ### Parameters #### Path Parameters - **target** (CiA402State) - Required - Target state - **timeout_s** (float) - Optional - Timeout in seconds (default: 2.0) - **poll_s** (float | None) - Optional - Poll interval (default: None) ### Returns Final statusword when target state is reached. ### Raises `CiA402StateError` if current state is unknown or no transition path exists. ### Example ```python try: drive.transition_to(CiA402State.OPERATION_ENABLED, timeout_s=3.0) except CiA402StateError as e: print(f"State transition failed: {e}") ``` ``` -------------------------------- ### Initialize CiA402Drive Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/cia402-drive.md Instantiate a CiA402Drive object. Ensure the EtherCAT bus is opened, scanned, and configured before creating the drive instance. ```python from cooethercat import EtherCATBus, CiA402Drive bus = EtherCATBus("eth0") bus.open() bus.scan() bus.configure() drive = CiA402Drive(bus, slave_index=0, name="motor_1") ``` -------------------------------- ### CiA 402 State Check Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/types.md Example of checking if a drive is in the 'OPERATION_ENABLED' state. This is a common check before sending motion commands. ```python if drive.state == CiA402State.OPERATION_ENABLED: print("Drive is ready for motion") ``` -------------------------------- ### PDOLoopAlreadyRunningError Exception Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/pdo-interface.md Raised when an attempt is made to start a PDO loop that is already active. This prevents concurrent PDO loop operations. ```python class PDOLoopAlreadyRunningError(PDOError): pass ``` -------------------------------- ### Read MaxonEPOS4 Drive Temperature Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/maxon-epos4.md Get the drive's internal temperature in Celsius. This is useful for thermal monitoring and preventing overheating. ```python temp = motor.temperature_c() if temp > 80: print(f"Warning: Motor hot ({temp}°C)") ``` -------------------------------- ### Initialize EtherCATBus with Options Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/configuration.md Instantiate EtherCATBus with network interface name. Optionally provide a custom pysoem.Master or disable interface validation. ```python bus = EtherCATBus( ifname: str, *, master: Optional[pysoem.Master] = None, validate_interface: bool = True, ) ``` ```python # Standard setup bus = EtherCATBus("eth0") ``` ```python # Disable validation for testing bus = EtherCATBus("eth0", validate_interface=False) ``` ```python # Use custom master import pysoem custom_master = pysoem.Master() bus = EtherCATBus("eth0", master=custom_master) ``` -------------------------------- ### Read Motor Diagnostics and Temperature Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/INDEX.md Retrieve motor information, read any active error, and get the current motor temperature in Celsius. ```python info = motor.info() error = motor.read_error() temp = motor.temperature_c() ``` -------------------------------- ### Control Drive via SDO (Single Moves) Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/INDEX.md Enables the drive, configures profile motion parameters, sets a target position, and initiates the move. This method is suitable for individual, non-cyclic movements. It waits until the target position is reached. ```python motor.enable() motor.configure_profile_motion(velocity=5000, acceleration=15000) motor.write_target_position(10000) motor.write_controlword(0x003F) # START motor.wait_for_bits(StatuswordBit.TARGET_REACHED) ``` -------------------------------- ### Handle BusNotOpenError Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/errors.md Catch errors that occur when attempting bus operations before the bus is opened. This example demonstrates opening the bus and retrying the operation. ```python bus = EtherCATBus("eth0") try: bus.scan() # Raises BusNotOpenError except BusNotOpenError: print("Bus is not open; call bus.open() first") bus.open() bus.scan() ``` -------------------------------- ### CiA402Drive Constructor Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/cia402-drive.md Initializes a new CiA402Drive instance. Requires an EtherCATBus instance and the slave index. An optional human-readable name can be provided. ```APIDOC ## Constructor ```python def __init__( self, bus: EtherCATBus, slave_index: int, *, name: str | None = None, ) -> None ``` ### Parameters - **bus** (EtherCATBus) - Required - EtherCAT bus instance - **slave_index** (int) - Required - Slave index on the bus - **name** (str | None) - Optional - Human-readable device name; defaults to "slave-{index}" ### Example ```python from cooethercat import EtherCATBus, CiA402Drive bus = EtherCATBus("eth0") bus.open() bus.scan() bus.configure() drive = CiA402Drive(bus, slave_index=0, name="motor_1") ``` ``` -------------------------------- ### Initialize MaxonEPOS4 Drive Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/maxon-epos4.md Instantiate and enable a MaxonEPOS4 drive on the EtherCAT bus. Ensure the bus is configured and scanned before creating the drive instance. ```python from cooethercat import EtherCATBus, MaxonEPOS4 bus = EtherCATBus("eth0") with bus: bus.scan() bus.configure() motor = MaxonEPOS4(bus, slave_index=0, name="axis_1") motor.enable() ``` -------------------------------- ### Handling Drive Faults in Python Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/errors.md Demonstrates how to catch a CiA402StateError, read the drive's error description, and perform a fault reset if the error is clearable with a fault reset. ```python try: motor.enable(timeout_s=3.0) except CiA402StateError: # Drive is faulted; read the error error = motor.read_error() print(f"Drive fault: {error.description}") # Reset if possible if error.reaction_code == "f": motor.fault_reset(timeout_s=2.0) motor.enable(timeout_s=3.0) else: print("Device reset required") ``` -------------------------------- ### Get Velocity Actual Value via PDO Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/maxon-epos4.md Retrieve the latest velocity actual value from the drive via PDO. This value is updated cyclically. ```python motor.velocity_pdo ``` -------------------------------- ### Get Position Actual Value via PDO Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/maxon-epos4.md Retrieve the latest position actual value from the drive via PDO. This value is updated cyclically. ```python motor.position_pdo ``` -------------------------------- ### Get Statusword via PDO Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/maxon-epos4.md Retrieve the latest statusword from the drive using PDO. This property reflects the most recent status received during a PDO cycle. ```python motor.statusword_pdo ``` -------------------------------- ### shutdown Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/cia402-drive.md Transitions the drive to the READY_TO_SWITCH_ON state. ```APIDOC ## shutdown ### Description Transition to READY_TO_SWITCH_ON state. ### Method `shutdown(self, *, timeout_s: float = 2.0) -> Statusword` ### Parameters #### Path Parameters - **timeout_s** (float) - Optional - Timeout in seconds (default: 2.0) ### Returns Final statusword. ``` -------------------------------- ### CiA402Drive Constructor Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/configuration.md Initializes a CiA402Drive object for controlling a drive. Requires the EtherCAT bus instance and the slave index. ```python drive = CiA402Drive( bus: EtherCATBus, slave_index: int, *, name: str | None = None, ) ``` -------------------------------- ### Multi-Motor Control with PDO Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/quick-start.md Initializes two motors and a PDO loop to manage them. Enables both motors, queues profile position commands, and waits for their completion. Includes cleanup to stop the PDO loop and disable motor voltage. Requires `PDOLoop` and `time` imports. ```python from cooethercat import PDOLoop, MaxonEPOS4 import time motor1 = MaxonEPOS4(bus, slave_index=0, name="axis_1") motor2 = MaxonEPOS4(bus, slave_index=1, name="axis_2") pdo_loop = PDOLoop(bus, period_s=0.002) pdo_loop.add_device(motor1) pdo_loop.add_device(motor2) pdo_loop.start() try: motor1.enable() motor2.enable() # Move both motors motor1.queue_profile_position_pdo(10000, velocity=5000, acceleration=15000) motor2.queue_profile_position_pdo(5000, velocity=3000, acceleration=10000) # Wait for both to complete while motor1.moving_pdo or motor2.moving_pdo: time.sleep(0.01) finally: pdo_loop.stop() motor1.disable_voltage() motor2.disable_voltage() ``` -------------------------------- ### Home EPOS4 Motor with Index Positive Speed Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/types.md Example of how to initiate homing for an EPOS4 motor using the INDEX_POSITIVE_SPEED method. Ensure the HomingMethod enum is imported. ```python motor.home(HomingMethod.INDEX_POSITIVE_SPEED) ``` -------------------------------- ### Manual PDO Cycling with cycle_once() Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/INDEX.md Use this pattern for explicit control over PDO cycle timing, suitable for real-time constraints. It requires creating a PDOLoop, adding devices, and manually calling cycle_once() within a loop. ```python pdo_loop = PDOLoop(bus) pdo_loop.add_device(motor) while not done: stats = pdo_loop.cycle_once() print(f"Elapsed: {stats.elapsed_s}") ``` -------------------------------- ### Initialize EtherCAT Bus Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/INDEX.md Initializes and opens the EtherCAT bus on a specified network interface, then scans for connected slaves and configures the bus. Ensure the network interface (e.g., 'eth0') is correct. ```python from cooethercat import EtherCATBus bus = EtherCATBus("eth0") bus.open() slaves = bus.scan() bus.configure() ``` -------------------------------- ### Reading and Printing EPOS4 Error Details Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/errors.md Example of how to read an error from a MaxonEPOS4 motor and print its details. Ensure the MaxonEPOS4 class and necessary imports are available. ```python motor = MaxonEPOS4(bus, 0) error = motor.read_error() print(f"Code: {error.code:#06x}") print(f"Description: {error.description}") print(f"Reaction: {error.reaction_code}") print(f"Position clearable: {error.position_clear_possible}") ``` -------------------------------- ### Example of EPOS4 error lookup Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/MANIFEST.txt Shows how to retrieve detailed information about an EPOS4 error code using the get_epos4_error function. This is crucial for diagnosing drive issues. ```python from cooethercat.errors import get_epos4_error # Example EPOS4 error code (e.g., 0x3112) error_code = 0x3112 # Get the EPOS4Error dataclass for the given code error_info = get_epos4_error(error_code) if error_info: print(f"Error Code: {hex(error_code)}") print(f"Description: {error_info.description}") print(f"Reaction: {error_info.reaction}") else: print(f"Unknown EPOS4 error code: {hex(error_code)}") ``` -------------------------------- ### Import All Public Symbols Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/INDEX.md Import all available public symbols from the cooethercat library for general use. This includes classes and exceptions for bus management, CiA 402 drives, EPOS4 drives, and PDO communication. ```python from cooethercat import ( # Bus EtherCATBus, EtherCATState, SlaveInfo, BusNotOpenError, SlaveNotFoundError, StateTransitionError, EtherCATError, # CiA 402 CiA402Drive, CiA402State, OperatingMode, Statusword, StatuswordBit, ControlwordBit, ControlwordCommand, MotionCommand, ObjectEntry, transition_sequence, CiA402Error, CiA402StateError, CiA402ModeError, # EPOS4 MaxonEPOS4, EPOS4Object, HomingMethod, PositionSource, DEFAULT_PROFILE_POSITION_RX_PDO, DEFAULT_PROFILE_POSITION_TX_PDO, MaxonEPOS4Error, # Errors EPOS4Error, EPOS4_ERRORS, get_epos4_error, is_known_epos4_error, # PDO PDOLoop, PDOLayout, PDOEntry, PDODevice, BufferedPDODevice, PDOError, PDOLoopAlreadyRunningError, PDOLoopNotRunningError, ) ``` -------------------------------- ### Get MaxonEPOS4 Debug Info Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/maxon-epos4.md Obtain a detailed status dictionary that includes additional parameters such as controlword, torque, and temperature, extending the basic 'info' dictionary. ```python debug_info = motor.debug_info() ``` -------------------------------- ### Configure Profile Motion Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/configuration.md Sets up profile velocity and acceleration parameters for motor movement. Use this to define how the motor accelerates and reaches its target velocity. ```python motor.configure_profile_motion( velocity: int, acceleration: int, deceleration: int | None = None, quick_stop_deceleration: int | None = None, ) ``` ```python # Slow, smooth motion motor.configure_profile_motion( velocity=2000, acceleration=5000, deceleration=5000, ) ``` ```python # Fast motion motor.configure_profile_motion( velocity=10000, acceleration=30000, deceleration=30000, ) ``` -------------------------------- ### Create Maxon EPOS4 Drive Instance Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/quick-start.md Instantiate a Maxon EPOS4 drive object, associating it with the EtherCAT bus and specifying its slave index and a unique name. ```python from cooethercat import MaxonEPOS4 motor = MaxonEPOS4(bus, slave_index=0, name="motor_1") ``` -------------------------------- ### Get Following Error Actual Value via PDO Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/maxon-epos4.md Retrieve the latest following error actual value from the drive via PDO. This value is updated cyclically. ```python motor.following_error_pdo ``` -------------------------------- ### Get EPOS4 Error Descriptor Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/errors.md Retrieves a known EPOS4 error descriptor using the error code and optionally the error register. Returns a placeholder for unknown codes. ```python def get_epos4_error(code: int, *, error_register: int = 0) -> EPOS4Error ``` ```python code = 0x6320 error = get_epos4_error(code) print(f"{error}") # "Software parameter error code=0x6320 reaction='f' position_clear_possible=False" ``` -------------------------------- ### Continuous Position Tracking with PDO Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/quick-start.md Sets up a PDO loop for continuous data transfer and enables the motor. Continuously prints the motor's PDO position and velocity until interrupted. Requires `PDOLoop` and `time` imports. ```python from cooethercat import PDOLoop import time pdo_loop = PDOLoop(bus, period_s=0.002) pdo_loop.add_device(motor) pdo_loop.start() try: motor.enable() # Continuous position tracking while True: print(f"Position: {motor.position_pdo} Velocity: {motor.velocity_pdo}") time.sleep(0.1) finally: pdo_loop.stop() ``` -------------------------------- ### Get Slave State - Python Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/ethercat-bus.md Retrieves and returns the current state of a specific slave device on the EtherCAT bus. Ensure the slave index is valid to avoid errors. ```python def get_slave_state(self, slave_index: int) -> int: pass ``` -------------------------------- ### Handle StateTransitionError Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/errors.md Catch errors related to network or slave state transition timeouts. This example shows how to handle a failed master state assertion and inspect current states. ```python try: bus.assert_master_state(EtherCATState.OP, timeout_us=50000) except StateTransitionError as e: print(f"State transition failed: {e}") print(f"Current states: {bus.read_states()}") ``` -------------------------------- ### enable Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/cia402-drive.md Enables the drive for operation. If the drive is currently faulted, it will reset the fault first. ```APIDOC ## enable ### Description Enable the drive for operation. If faulted, resets the fault first. ### Method `enable(self, *, timeout_s: float = 2.0) -> Statusword` ### Parameters #### Path Parameters - **timeout_s** (float) - Optional - Timeout in seconds (default: 2.0) ### Returns Final statusword in OPERATION_ENABLED state. ### Raises `CiA402StateError` or `TimeoutError` on failure. ### Example ```python drive.enable(timeout_s=3.0) if drive.enabled: print("Drive is operational") ``` ``` -------------------------------- ### CiA402 State Transition Sequence Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/cia402-drive.md Calculates the shortest sequence of controlword commands to transition between CiA402 states using breadth-first search. Raises CiA402StateError if no path exists. Import: from cooethercat import transition_sequence. ```python def transition_sequence( start: CiA402State, target: CiA402State, ) -> list[ControlwordCommand]: ``` ```python commands = transition_sequence(CiA402State.READY_TO_SWITCH_ON, CiA402State.OPERATION_ENABLED) # Returns [ControlwordCommand.SWITCH_ON_AND_ENABLE_OPERATION] ``` -------------------------------- ### PDOLoop Constructor Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/pdo-interface.md Initializes the PDOLoop controller. It requires an EtherCATBus instance and allows configuration of cycle period, timeout, expected working counter, and a warning callback. ```APIDOC ## PDOLoop Constructor ### Description Initializes the PDOLoop controller with an EtherCAT bus instance and optional parameters for cycle timing, timeouts, and error handling. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Method Signature ```python def __init__( self, bus: EtherCATBus, *, period_s: float = 0.002, timeout_us: int = 2_000, expected_working_counter: int | None = None, on_warning: Callable[[str], None] | None = None, ) ``` ### Parameters - **bus** (EtherCATBus) - Required - EtherCAT bus instance. - **period_s** (float) - Optional - Target cycle period in seconds (defaults to 0.002). - **timeout_us** (int) - Optional - PDO receive timeout in microseconds (defaults to 2000). - **expected_working_counter** (int | None) - Optional - Expected pysoem working counter for warnings. - **on_warning** (Callable[[str], None] | None) - Optional - Warning callback function (defaults to logging). ``` -------------------------------- ### Enable Motor with Error Handling Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/INDEX.md Enable a motor using the `enable()` method, with a timeout. Catches `CiA402StateError` if the motor cannot be enabled. ```python try: motor.enable(timeout_s=3.0) except CiA402StateError as e: print(f"Cannot enable: {e}") ``` -------------------------------- ### Handle CiA402ModeError Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/errors.md Catch errors during CiA 402 operating mode changes, including timeouts or verification failures. This example shows how to handle a failed mode change and specifies a timeout for the operation. ```python try: drive.set_operating_mode(OperatingMode.HOMING, timeout_s=2.0) except CiA402ModeError as e: print(f"Mode change failed: {e}") ``` -------------------------------- ### fetch_config Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/maxon-epos4.md Fetches commonly useful EPOS4 commissioning parameters via SDO reads. Returns a dictionary containing motor and controller parameters. ```APIDOC ## fetch_config ### Description Fetch commonly useful EPOS4 commissioning parameters via SDO reads. ### Returns Dictionary with keys for motor and controller parameters (current limits, pole pairs, thermal constant, torque constant, encoder settings, gear ratios, controller gains). ### Example ```python config = motor.fetch_config() print(f"Nominal current: {config['NOMINAL_CURRENT_MA']} mA") print(f"Pole pairs: {config['NUMBER_OF_POLE_PAIRS']}") ``` ``` -------------------------------- ### Fetch EPOS4 Configuration Parameters Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/maxon-epos4.md Retrieves common EPOS4 commissioning parameters like current limits, pole pairs, and encoder settings. Use this to get a snapshot of the motor's current configuration. ```python config = motor.fetch_config() print(f"Nominal current: {config['NOMINAL_CURRENT_MA']} mA") print(f"Pole pairs: {config['NUMBER_OF_POLE_PAIRS']}") ``` -------------------------------- ### Get MaxonEPOS4 Drive Info Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/maxon-epos4.md Retrieve a dictionary of essential drive status information, including state, position, velocity, and error details. This provides a quick overview of the drive's current condition. ```python info = motor.info() print(f"Position: {info['position']}") print(f"Error: {info['error'].description}") ``` -------------------------------- ### quick_stop Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/cia402-drive.md Commands a quick stop, transitioning the drive to the QUICK_STOP_ACTIVE state. ```APIDOC ## quick_stop ### Description Command quick stop (transition to QUICK_STOP_ACTIVE). ### Method `quick_stop(self, *, timeout_s: float = 2.0) -> Statusword` ### Parameters #### Path Parameters - **timeout_s** (float) - Optional - Timeout in seconds (default: 2.0) ### Returns Final statusword. ### Aliases `stop()`, `halt()` ``` -------------------------------- ### Configure Profile Position Parameters via PDO Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/maxon-epos4.md Queue profile motion parameters (velocity, acceleration, deceleration) for position mode. These settings will be applied in the next PDO cycle. ```python def configure_profile_position_pdo( self, *, velocity: int, acceleration: int, deceleration: int | None = None, ) -> None: ``` -------------------------------- ### Enable Watchdog Timer Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/configuration.md Configure the watchdog timer for a specific slave device. If no PDO is received within the specified timeout, the drive will trigger a fault. Typical values are 50 ms for 2 ms PDO loops. ```python bus.set_watchdog(slave_index=0, timeout_ms=50.0) ``` -------------------------------- ### Queue Profile Position Motion Command via PDO Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/maxon-epos4.md Queue a profile-position motion command for the next PDO cycle. This includes target position and motion parameters. The command is sent non-blockingly. ```python def queue_profile_position_pdo( self, position: int, *, velocity: int, acceleration: int, deceleration: int | None = None, absolute: bool = True, ) -> None: ``` ```python motor.queue_profile_position_pdo( position=10000, velocity=5000, acceleration=15000, absolute=True, ) # PDOLoop will send this on the next cycle ``` -------------------------------- ### BufferedPDODevice Constructor Source: https://github.com/caltechopticalobservatories/coo-ethercat/blob/main/_autodocs/pdo-interface.md Initializes a new instance of the BufferedPDODevice class with the specified slave index and PDO layouts. ```APIDOC ## BufferedPDODevice Constructor ### Description Initializes a new instance of the BufferedPDODevice class. ### Parameters #### Path Parameters - **slave_index** (int) - Required - Slave position on the bus - **rx_pdo** (PDOLayout) - Required - Outgoing PDO layout - **tx_pdo** (PDOLayout) - Required - Incoming PDO layout ```