fix frappy_demo.lakeshore

reading back the target does not work properly, because
  a) the readback value might be delayed
  b) there is no command to read back the target, SETP?1
     is returning the working setpoint, which might be distinct
     in case of a ramp

Change-Id: I0da2dbfc1a8ddbecbae6d0456ff64e008bc56336
Reviewed-on: https://forge.frm2.tum.de/review/c/secop/frappy/+/31983
Tested-by: Jenkins Automated Tests <pedersen+jenkins@frm2.tum.de>
Reviewed-by: Markus Zolliker <markus.zolliker@psi.ch>
This commit is contained in:
zolliker 2023-08-18 10:07:20 +02:00
parent bf4b3e5683
commit 4c5109e5a3
2 changed files with 18 additions and 15 deletions

View File

@ -200,7 +200,10 @@ implemented the readable stuff. We need to define some properties of the ``targe
parameter and add a property ``loop`` indicating, which control loop and
heater output we use.
In addition, we have to implement the methods ``write_target`` and ``read_target``:
In addition, we have to implement the method ``write_target``. Remark: we do not
implement ``read_target`` here, because the lakeshore does not offer to read back the
real target. The SETP command is returning the working setpoint, which may be distinct
from target during a ramp.
.. code:: python
@ -216,11 +219,9 @@ In addition, we have to implement the methods ``write_target`` and ``read_target
def write_target(self, target):
# we always use a request / reply scheme
reply = self.communicate(f'SETP {self.loop},{target};SETP?{self.loop}')
return float(reply)
self.communicate(f'SETP {self.loop},{target};*OPC?')
return target
def read_target(self):
return float(self.communicate(f'SETP?{self.loop}'))
In order to test this, we will need to change the entry module ``T`` in the
configuration file:
@ -272,13 +273,12 @@ There are two things still missing:
def write_target(self, target):
# reactivate heater in case it was switched off
self.communicate(f'RANGE {self.loop},{self.heater_range};RANGE?{self.loop}')
reply = self.communicate(f'SETP {self.loop},{target};SETP? {self.loop}')
self.communicate(f'SETP {self.loop},{target};*OPC?')
self._driving = True
# Setting the status attribute triggers an update message for the SECoP status
# parameter. This has to be done before returning from this method!
self.status = BUSY, 'target changed'
return float(reply)
return target
...
def read_status(self):
@ -403,4 +403,10 @@ Appendix 2: Extract from the LakeShore Manual
Command (340) RANGE? *term*
Command (336/350) RANGE?<loop> *term*
Reply <range> *term*
**Operation Complete Query**
----------------------------------------------
Command *OPC?
Reply 1
Description in Frappy, we append this command to request in order
to generate a reply
====================== =======================

View File

@ -69,24 +69,21 @@ class TemperatureSensor(HasIO, Readable):
class TemperatureLoop(TemperatureSensor, Drivable):
# lakeshore loop number to be used for this module
loop = Property('lakeshore loop', IntRange(1, 2), default=1)
target = Parameter(datatype=FloatRange(min=0, max=1500, unit='K'))
target = Parameter(datatype=FloatRange(unit='K', min=0, max=1500))
heater_range = Property('heater power range', IntRange(0, 5)) # max. 3 on LakeShore 336
tolerance = Parameter('convergence criterion', FloatRange(0), default=0.1, readonly = False)
tolerance = Parameter('convergence criterion', FloatRange(0), default=0.1, readonly=False)
_driving = False
def write_target(self, target):
# reactivate heater in case it was switched off
# the command has to be changed in case of model 340 to f'RANGE {self.heater_range};RANGE?'
self.communicate(f'RANGE {self.loop},{self.heater_range};RANGE?{self.loop}')
reply = self.communicate(f'SETP {self.loop},{target};SETP? {self.loop}')
self.communicate(f'SETP {self.loop},{target};*OPC?')
self._driving = True
# Setting the status attribute triggers an update message for the SECoP status
# parameter. This has to be done before returning from this method!
self.status = BUSY, 'target changed'
return float(reply)
def read_target(self):
return float(self.communicate(f'SETP?{self.loop}'))
return target
def read_status(self):
code = int(self.communicate(f'RDGST?{self.channel}'))