Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ Installation instructions

The user has to install the drivers from ACS. The homing program provided with the stages
must be stored in a buffer of the controller (buffer 1 by default, set with the
'Homing buffer' parameter of the plugin). The plugin never modifies the buffers of the
controller: the Home button starts this program (it homes all the axes at once); the move is done when the
program ends. Stop interrupts the homing program and halts all the axes: the stages must then be
homed again before any other move, as the program disables the limit switch protection while homing.
homing_buffer entry of the configuration file of the plugin). The plugin never modifies the buffers of the
controller: the Home button runs this program and waits for its end (about 20 s); it homes all the
axes at once. The homing cannot be interrupted from PyMoDAQ, as the program disables the limit switch
protection while homing: use the emergency stop of the controller if needed.
It is recommended to keep a full backup of the controller application, made
with the Application Wizard of SPiiPlus MMI Application Studio. Users are encouraged to check
the compatibility of their ACS hardware with the latest version of the plugin, and to refer
Expand Down
49 changes: 23 additions & 26 deletions src/pymodaq_plugins_acs_motion/daq_move_plugins/daq_move_AcsXY.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
main, DataActuatorType, DataActuator)

from pymodaq_gui.parameter import Parameter
from pymodaq_utils.utils import ThreadCommand

try:
from pymodaq_plugins_acs_motion.hardware.acscontrol import Controller # ACS controller wrapper
Expand All @@ -28,11 +29,11 @@ class DAQ_Move_AcsXY(DAQ_Move_base):
The operating system used was Windows 11.
Installation instructions: ACS drivers must be installed from the manufacturer's.
The homing program provided with the stages must be stored in a buffer of the controller
(buffer 1 by default on the tested equipment, see the 'Homing buffer' parameter).
(buffer 1 on the tested equipment, set with the homing_buffer entry of the plugin configuration file).
The plugin never modifies it.
The Home button starts this program (it homes all the axes at once); the move is done when the
program ends. Stop interrupts the homing program and halts all the axes: the stages must then be
homed again before any other move, as the program disables the limit switch protection while homing.
The Home button runs this program and waits for its end (about 20 s); it homes all the axes at once.
The homing cannot be interrupted from PyMoDAQ, as the program disables the limit switch protection
while homing: use the emergency stop of the controller if needed.

Attributes:
-----------
Expand All @@ -51,9 +52,7 @@ class DAQ_Move_AcsXY(DAQ_Move_base):
data_actuator_type = DataActuatorType.DataActuator

params = [ {'title': 'Serial Number', 'name': 'serial_num', 'type': 'str',
'value': '', 'readonly': True,},
{'title': 'Homing buffer', 'name': 'buff_num', 'type': 'int',
'value': 1, 'limits': [0, 9],}
'value': '', 'readonly': True,}
] + comon_parameters_fun(is_multiaxes, axis_names=_axis_names)

def ini_attributes(self):
Expand Down Expand Up @@ -110,6 +109,7 @@ def ini_stage(self, controller=None):
self.controller = Controller(contype="ethernet", n_axes=2)
self.controller.connect() # any object that will control the stages
self.controller.enable_all() # enable all axes
self.controller.wait_all_enabled() #wait for axis enabled
self.settings['serial_num']=self.controller.serial_number()


Expand All @@ -129,27 +129,24 @@ def move_rel(self, value: DataActuator):
self.move_abs(self.get_actuator_value() + value)

def move_home(self):
"""Start the homing program of the controller, without waiting for its end"""
buffer = self.settings['buff_num']
if self.controller.is_program_running(buffer):
return # homing already in progress: ignore the repeated request
self.controller.run_buffer(buffer)
home = DataActuator(data=0, units=self.axis_unit)
self.target_value = self.get_position_with_scaling(home)

def user_condition_to_reach_target(self) -> bool:
"""A move is done only when the homing program is not running"""
return not self.controller.is_program_running(self.settings['buff_num'])
"""Run the homing program of the controller (all axes) and wait for its end.
The homing cannot be interrupted from PyMoDAQ: the program disables the limit switch
protection while homing, so stopping it midway would leave the stages unprotected.
"""
if self.controller.is_program_running(self.controller.homing_buffer):
self.emit_status(ThreadCommand('Update_Status', ['Homing already in progress']))
return
self.emit_status(ThreadCommand('Update_Status',
['Homing all axes (about 20 s), it cannot be interrupted...']))
try:
self.controller.home()
except Exception as e: # timeout or communication error: the move is over in any case
self.emit_status(ThreadCommand('Update_Status', [f'Homing error: {e}']))
self.move_done(self.get_actuator_value())

def stop_motion(self):
"""Stop the homing program if it is running, then halt the axes"""
buffer = self.settings['buff_num']
if self.controller.is_program_running(buffer):
self.controller.stop_buffer(buffer)
for axis in self.controller.axes:
axis.halt() # the program may have left any axis jogging
else:
self.controller.axes[self.axis_value].halt()
"""Stop the current axis and emit the move_done signal"""
self.controller.axes[self.axis_value].halt()
Comment thread
jerlfan marked this conversation as resolved.
Resolved
self.move_done()


Expand Down
31 changes: 30 additions & 1 deletion src/pymodaq_plugins_acs_motion/hardware/acscontrol.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
"""
from __future__ import division, print_function
from acspy import acsc
from ctypes import c_int
from pymodaq_utils.config import GlobalConfig

config = GlobalConfig()


class Controller(object):
Expand Down Expand Up @@ -35,7 +39,21 @@ def run_buffer(self, buffer_number=1):
def is_program_running(self, buffer_number=1):
"""Returns True while the program of the buffer is running."""
return bool(acsc.getProgramState(self.hc, buffer_number) & self.PST_RUN)


def wait_program_end(self, buffer_number=1, timeout=60000):
"""Waits until the program of the buffer has finished (timeout in ms)."""
acsc.waitProgramEnd(self.hc, buffer_number, timeout)

@property
def homing_buffer(self) -> int:
"""Buffer storing the homing program, as set in the configuration file of the plugin"""
return config('acs_motion', 'homing_buffer')

def home(self, timeout=60000):
"""Runs the homing program provided with the stages and waits for its end (timeout in ms)"""
self.run_buffer(self.homing_buffer)
self.wait_program_end(self.homing_buffer, timeout)

def stop_buffer(self, buffer_number=1):
"""Stops the program running in the buffer."""
acsc.stopBuffer(self.hc, buffer_number)
Expand All @@ -49,6 +67,11 @@ def enable_all(self, wait=acsc.SYNCHRONOUS):
for a in self.axes:
a.enable()

def wait_all_enabled(self, timeout=5000):
"""Waits until all axes are enabled (timeout in ms for each axis)."""
for a in self.axes:
a.wait_enabled(timeout)

def disable_all(self, wait=acsc.SYNCHRONOUS):
"""Disables all axes."""
for a in self.axes:
Expand All @@ -74,6 +97,12 @@ def enable(self, wait=acsc.SYNCHRONOUS):
def disable(self, wait=acsc.SYNCHRONOUS):
acsc.disable(self.controller.hc, self.axisno, wait)

def wait_enabled(self, timeout=5000):
"""Waits until the axis is enabled (timeout in ms), raises an AcscError on timeout.
acsc_WaitMotorEnabled is not exposed by ACSpy, so it is called directly."""
acsc.call_acsc(acsc.acs.acsc_WaitMotorEnabled, self.controller.hc,
c_int(self.axisno), c_int(1), c_int(timeout))

def ptp(self, target, coordinates="absolute", wait=acsc.SYNCHRONOUS):
"""Performs a point to point move in either relative or absolute
(default) coordinates."""
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
title = 'this is the configuration file of the plugin pymodaq_plugins_acs_motion'

homing_buffer = 1 # buffer of the controller storing the homing program provided with the stages
Loading