From 880327c544f5d2b360867cf413cde41f5c7bd593 Mon Sep 17 00:00:00 2001 From: l_samenv Date: Tue, 20 Oct 2020 14:17:24 +0200 Subject: [PATCH] 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 --- secop_psi/ls370res.py | 83 ++++++++++++++++++++++++++++++++++--------- secop_psi/ls370sim.py | 4 ++- 2 files changed, 69 insertions(+), 18 deletions(-) diff --git a/secop_psi/ls370res.py b/secop_psi/ls370res.py index 999449f..5a7bb20 100644 --- a/secop_psi/ls370res.py +++ b/secop_psi/ls370res.py @@ -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 diff --git a/secop_psi/ls370sim.py b/secop_psi/ls370sim.py index a445ef4..130bb74 100644 --- a/secop_psi/ls370sim.py +++ b/secop_psi/ls370sim.py @@ -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: