main ls370 module is now drivable

the value is the current channel, when the target (=channel) is changed,
the value changes to 0, until the switching has finished, including pause time
This commit is contained in:
l_samenv 2020-10-20 14:17:24 +02:00
parent 1b4865c608
commit 880327c544
2 changed files with 69 additions and 18 deletions

View File

@ -21,8 +21,9 @@
"""LakeShore Model 370 resistance channel"""
import time
import json
from secop.modules import Module, Readable, Drivable, Parameter, Override, Property, Attached
from secop.modules import Readable, Drivable, Parameter, Override, Property, Attached
from secop.metaclass import Done
from secop.datatypes import FloatRange, IntRange, EnumType, BoolType
from secop.stringio import HasIodev
@ -58,27 +59,66 @@ class StringIO(secop.stringio.StringIO):
wait_before = 0.05
class Main(HasIodev, Module):
class Main(HasIodev, Drivable):
parameters = {
'channel':
Parameter('the current channel', poll=REGULAR, datatype=IntRange(), readonly=False, handler=scan),
'value': Override('the current channel', poll=REGULAR, datatype=IntRange(0, 17)),
'target': Override('channel to select', datatype=IntRange(0, 17)),
'autoscan':
Parameter('whether to scan automatically', datatype=BoolType(), readonly=False, handler=scan),
'pollinterval': Parameter('sleeptime between polls', default=5,
readonly=False,
datatype=FloatRange(0.1, 120),
),
Parameter('whether to scan automatically', datatype=BoolType(), readonly=False, default=False),
'pollinterval': Override('sleeptime between polls', default=1),
}
pollerClass = Poller
iodevClass = StringIO
def analyze_scan(self, channel, autoscan):
return dict(channel=channel, autoscan=autoscan)
def earlyInit(self):
self._channel_changed = 0
self._channels = {}
def change_scan(self, change):
change.readValues()
return change.channel, change.autoscan
def register_channel(self, modobj):
self._channels[modobj.channel] = modobj
def startModule(self, started_callback):
started_callback()
for ch in range(1, 16):
if ch not in self._channels:
self.sendRecv('INSET %d,0,0,0,0,0;INSET?%d' % (ch, ch))
def read_value(self):
channel, auto = json.loads('[%s]' % self.sendRecv('SCAN?'))
if not self._channels[channel].enabled:
# channel was disabled recently, but still selected
nextchannel = 0
for ch, mobj in self._channels.items():
if mobj.enabled:
if ch > channel:
nextchannel = ch
break
if nextchannel == 0:
nextchannel = ch
if not nextchannel:
self.write_target(nextchannel)
return 0
now = time.time()
if channel != self.target:
print('changed' , channel, self.target)
self._channel_changed = now
self.target = channel
self.autoscan = int(auto)
if now < self._channel_changed + self._channels[channel].pause + self._channels[channel].filter:
self.status = [Status.BUSY, 'switching']
return 0
self.status = [Status.IDLE, '']
return channel
def write_target(self, channel):
self.sendRecv('SCAN %d,%d;SCAN?' % (channel, self.autoscan))
if channel != self.value:
self.value = 0
self._channel_changed = time.time()
self.status = [Status.BUSY, 'switching']
return channel
class ResChannel(HasIodev, Readable):
@ -133,13 +173,16 @@ class ResChannel(HasIodev, Readable):
Parameter('filter time', datatype=FloatRange(1, 200), readonly=False, handler=filterhdl),
}
def initModule(self):
self._main = self.DISPATCHER.get_module(self.main)
self._main.register_channel(self)
def startModule(self, started_callback):
self._last_range_change = 0
self._main = self.DISPATCHER.get_module(self.main)
super().startModule(started_callback)
def read_value(self):
if self.channel != self._main.channel:
if self.channel != self._main.value:
return Done
if not self.enabled:
self.status = [self.Status.DISABLED, 'disabled']
@ -177,7 +220,7 @@ class ResChannel(HasIodev, Readable):
def read_status(self):
if not self.enabled:
return [self.Status.DISABLED, 'disabled']
if self.channel != self._main.channel:
if self.channel != self._main.value:
return Done
result = int(self.sendRecv('RDGST?%d' % self.channel))
result &= 0x37 # mask T_OVER and T_UNDER (change this when implementing temperatures instead of resistivities)
@ -242,3 +285,9 @@ class ResChannel(HasIodev, Readable):
if change.filter:
return 1, change.filter, 80 # always use 80% filter
return 0, settle, window
def write_enabled(self, value):
inset.write(self, 'enabled', value)
if value:
self._main.write_target(self.channel)
return Done

View File

@ -32,8 +32,10 @@ class Ls370Sim(Communicator):
]
OTHER_COMMANDS = [
('*IDN?', 'LSCI,MODEL370,370184,05302003'),
('SCAN?', '3,1'),
('SCAN?', '1,1'),
]
channel = [None]
def earlyInit(self):
self._data = dict(self.OTHER_COMMANDS)
for fmt, v in self.CHANNEL_COMMANDS: