Skip to content

Commit

Permalink
Merge pull request #213 from SiLab-Bonn/motorstage
Browse files Browse the repository at this point in the history
Improvements for mercury driver
  • Loading branch information
YannickDieter committed May 17, 2024
2 parents 417fdd2 + 4480251 commit 4bde44a
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 7 deletions.
62 changes: 58 additions & 4 deletions basil/HL/mercury.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
# ------------------------------------------------------------
#
from basil.HL.RegisterHardwareLayer import HardwareLayer
import logging
import time

logger = logging.getLogger(__name__)
# logger.setLevel(logging.DEBUG)


class Mercury(HardwareLayer):
Expand All @@ -15,8 +20,8 @@ class Mercury(HardwareLayer):
Therefore '\x03' has to be set a read termination in the transport layer! And a read termination
of 0.1 s should be set!
Despite the manual telling SCPI compatibility, this is not correct for our devices with our
firmware.
'''
firmware. The manual explaining every "native" command: https://twiki.cern.ch/twiki/pub/ILCBDSColl/Phase2Preparations/MercuryNativeCommands_MS176E101.pdf
The overall manual: https://www.le.infn.it/~chiodini/allow_listing/pi/Manuals/C-863_Benutzerhandbuch_Kurzversion_MS205Dqu200.pdf'''

def __init__(self, intf, conf):
super(Mercury, self).__init__(intf, conf)
Expand Down Expand Up @@ -48,6 +53,21 @@ def get_address(self, address):
self._write_command("TB", address)
return self.read()

def motor_on(self, address=None):
self._write_command("MN", address)

def motor_off(self, address=None):
self._write_command("MF", address)

def LL(self, address=None): # logic active low
self._write_command("LL", address)

def set_home(self, address=None): # Defines the current position as 0
self._write_command("DH", address)

def go_home(self, address=None): # Moves motor to zero position
self._write_command("GH", address)

def get_position(self, address=None):
self._write_command("TP", address)
return int(self.read()[2:-3])
Expand All @@ -56,8 +76,42 @@ def get_channel(self, address=None):
self._write_command("TS", address)
return self.read()

def set_position(self, value, address=None):
def set_position(self, value, precision=100, address=None, wait=False):
self._write_command("MA%d" % value, address)
if wait is True:
pos = self._wait(address)
if abs(pos - value) <= precision:
logger.debug("At position {pos}, Target at {target}".format(pos=pos, target=value))
else:
logger.warning("Target not reached! Target: {target}, actual position: {pos}, precision: {pre}".format(target=value, pos=pos, pre=precision))

def move_relative(self, value, address=None):
def move_relative(self, value, precision=100, address=None, wait=False):
target = self.get_position(address=1) + value
self._write_command("MR%d" % value, address)
if wait is True:
pos = self._wait(address)
if abs(pos - target) <= precision:
logger.debug("At position {pos}, Target at {target}".format(pos=pos, target=target))
else:
logger.warning("Target not reached! Target: {target}, actual position: {pos}, precision: {pre}".format(target=target, pos=pos, pre=precision))

def abort(self, address=None):
self._write_command("AB", address)

def find_edge(self, n, address=None):
self._write_command("FE%d" % n, address)
pos = self._wait(address)
logger.debug("Edge found at position: {pos}".format(pos=pos))

def _wait(self, address=None): # waits until motor stops moving
logger.debug("Moving! Starting position: {pos}".format(pos=self.get_position(address)))
done = False
while done is False:
a = self.get_position(address)
time.sleep(1)
b = self.get_position(address)
if a == b:
done = True
else:
time.sleep(0.5)
return b
29 changes: 26 additions & 3 deletions examples/lab_devices/MotorStage.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,33 @@
''' This script shows how to use a Motor Stage
'''


import time
from basil.dut import Dut

dut = Dut('mercury_pyserial.yaml')
dut.init()
print(dut["MotorStage"].get_position())
# dut["MotorStage"].set_position(100000)

# setup (for c-862)
# needed if mercury is connected the first time after power up
# MN Motor=on
# LL: switch logic active low (hardware)

dut["MotorStage"].motor_on(address=1)
time.sleep(0.1)
dut["MotorStage"].LL(address=1)
time.sleep(0.1)

# move to absolute position 10000:
# dut["MotorStage"].set_position(10000, address=1, wait=True)

# get position:
# print(dut["MotorStage"].get_position(address=1))

# move relative 10000:
dut["MotorStage"].move_relative(10000, address=1, wait=True)

# finding edge example:
# dut["MotorStage"].find_edge(1,address=1) # 0 or 1 indicates direction of movement

# abort any movement abruptly:
# dut["MotorStage"].abort(address=1)

0 comments on commit 4bde44a

Please sign in to comment.