Files
x03da/script/keithley.py
gac-x03da 70de87cafa Closedown
2018-02-09 16:45:00 +01:00

157 lines
5.2 KiB
Python

import ch.psi.pshell.epics as epics
import math
class Keithley(object):
RANGE_STATES = ['AUTO', '20 mA', '2 mA', '200 uA', '20 uA', '2 uA', '200 nA', '20 nA', '2 nA', '200 pA', '20 pA']
TTYPE_STATES = ['IMM', 'TLIN', 'BUS', 'EXT']
USER_MODE_STATES = ['def setting', 'poll curr fast', 'poll curr medi', 'poll curr slow', 'trig setting', 'trigger BUS', 'trigger TLIN', 'trigger EXT', 'poll volt medi']
def __init__(self, base_name, base_channel):
self.dwell = 0.
self.base_channel = base_channel
self.base_name = base_name
self.rangeCh = None
self.scanCh = None
self.ttypeCh = None
self.nplcCh = None
self.navgCh = None
self.tottimeCh = None
self.doinitCh = None
self.dotriggerCh = None
self.dofetchCh = None
self.readoutCh = None
def initialize(self):
self.rangeCh = epics.ChannelInteger(self.base_name + "Range", self.base_channel + "RANGE")
self.scanCh = epics.ChannelInteger(self.base_name + "Scan", self.base_channel + "READSCAN.SCAN")
self.ttypeCh = epics.ChannelInteger(self.base_name + "TType", self.base_channel + "TTYPE")
self.nplcCh = epics.ChannelDouble(self.base_name + "Nplc", self.base_channel + "NPLC")
self.navgCh = epics.ChannelInteger(self.base_name + "Navg", self.base_channel + "NAVG")
self.tottimeCh = epics.ChannelDouble(self.base_name + "TotTime", self.base_channel + "TOTTIME")
self.doinitCh = epics.ChannelInteger(self.base_name + "DoInit", self.base_channel + "DOINIT")
self.dotriggerCh = epics.ChannelInteger(self.base_name + "DoTrigger", self.base_channel + "DOTRIGGER")
self.dofetchCh = epics.ChannelInteger(self.base_name + "DoFetch", self.base_channel + "DOFETCH")
self.readoutCh = epics.ChannelDouble(self.base_name + "Readout", self.base_channel + "READOUT")
# DOZCHOFF
# ZCH_SP
# DOCURRENT
# DORESET
# DOSETDEFAULT
# USER_MODE
self.rangeCh.initialize()
self.scanCh.initialize()
self.ttypeCh.initialize()
self.nplcCh.initialize()
self.navgCh.initialize()
self.tottimeCh.initialize()
self.doinitCh.initialize()
self.dotriggerCh.initialize()
self.dofetchCh.initialize()
self.readoutCh.initialize()
def setup():
"""
EXPERIMENTAL
to set up the keithley after Reset, there are two options
1) do set defaults, set scan, set range
2) set user mode, set range
"""
self.dosetdefaultCh.write(1)
self.scanCh.write(9)
def prepare(self, dwell):
"""
prepare keithley for gpib polling:
scan passive, bus triggered, set dwell time
dwell = dwell time in seconds (0.1 - 20.0)
"""
self.scanCh.write(0)
self.ttypeCh.write(2)
nplc = 5.
navg = dwell / 0.1
if navg > 100:
nplc *= 2
navg /= 2
navg = min(navg, 100)
nplc = min(nplc, 10.)
self.nplcCh.write(nplc)
self.navgCh.write(navg)
self.dwell = self.tottimeCh.read() / 1000.
def trig(self):
"""
trigger keithleys, wait until done, and read the result into EPICS.
the value can then be read by pshell from the channel.
"""
self.doinitCh.write(1)
self.dotriggerCh.write(1)
def get_dwell(self):
"""
get dwell time in seconds.
"""
dwell = self.tottimeCh.read() / 1000.
self.dwell = dwell
return dwell
def fetch(self):
"""
fetch the current value from the keithley into EPICS.
"""
#time.sleep(self.get_dwell())
self.dofetchCh.write(1)
def read(self):
"""
read the curent value.
"""
return self.readoutCh.read()
def release(self):
"""
switch keithleys to free run.
0.1 s polling and dwell time
"""
self.nplcCh.write(5.)
self.navgCh.write(1)
self.scanCh.write(9)
self.ttypeCh.write(0)
def reset(self):
"""
switch to zero check
"""
self.doresetCh.write(1)
def set_range(self, value):
"""
set the current range.
value can be:
- float: current limit in A.
values between 2e-11 and 2e-3 set a fixed range.
values greater than 0.02 select AUTO.
- str: state label of EPICS channel (cf. self.RANGE_STATES).
must be one of the state labels, otherwise a ValueError is raised.
- int: state index of EPICS channel (0...10)
"""
if isinstance(value, float):
try:
value = int(-math.log10(value / 2)) - 1
value = max(value, 0)
value = min(value, len(self.RANGE_STATES)-1)
except ValueError:
value = 0
elif isinstance(value, str):
value = self.RANGE_STATES.index(value)
self.rangeCh.write(value)
KeiSample = Keithley("SampleKeithley", "X03DA-KEITHLEY-1:")
KeiReference = Keithley("ReferenceKeithley", "X03DA-KEITHLEY-2:")
KeiSample.initialize()
KeiReference.initialize()