Commit 91efd0ebc5b41da7d6b45177f563eb5b40337d5e

Authored by mer0m
Committed by GitHub
1 parent 861f505391
Exists in master

Add files via upload

Showing 9 changed files with 806 additions and 0 deletions Side-by-side Diff

instruments/AG34461A.py
  1 +from abstract_instrument import abstract_instrument
  2 +import socket
  3 +
  4 +#==============================================================================
  5 +
  6 +ALL_VAL_TYPE = ['DCV', 'ACV', 'DCI', 'ACI', 'RES2W', 'RES4W', 'FREQ']
  7 +ALL_CHANNELS = ['1']
  8 +
  9 +ADRESS = "192.168.0.61"
  10 +CONF_VAL_TYPE = ['CONF:VOLT:DC', 'CONF:VOLT:AC', 'CONF:CURR:DC', 'CONF:CURR:AC', 'CONF:RES', 'CONF:FRES', 'CONF:FREQ']
  11 +
  12 +#==============================================================================
  13 +
  14 +class AG34461A(abstract_instrument):
  15 + def __init__(self, channels, vtypes, adress=ADRESS):
  16 + self.adress = adress
  17 + self.port = 5025
  18 + self.channels = channels
  19 + self.vtypes = vtypes
  20 +
  21 + def model(self):
  22 + #self.send("*IDN?")
  23 + #return self.read()
  24 + return "AG34461A"
  25 +
  26 + def connect(self):
  27 + print('Connecting to device @%s:%s...' %(self.adress, self.port))
  28 + self.sock = socket.socket(socket.AF_INET,
  29 + socket.SOCK_STREAM,
  30 + socket.IPPROTO_TCP)
  31 + self.sock.settimeout(10.0) # Don't hang around forever
  32 + self.sock.connect((self.adress, self.port))
  33 + self.send("SYST:BEEP")
  34 + print(' --> Ok')
  35 + print(self.model())
  36 + self.configure()
  37 +
  38 + def configure(self):
  39 + for ch in self.channels:
  40 + self.send(CONF_VAL_TYPE[ALL_VAL_TYPE.index(self.vtypes[self.channels.index(ch)])])
  41 +
  42 + def getValue(self):
  43 + mes = ''
  44 + for ch in self.channels:
  45 + self.send("READ?")
  46 + mesTemp = self.read()
  47 + mes = mes + '\t' + mesTemp
  48 + return mes
  49 +
  50 + def read(self):
  51 + ans = ''
  52 + nb_data_list = []
  53 + nb_data = ''
  54 + try:
  55 + while ans != '\n':
  56 + ans = self.sock.recv(1)
  57 + nb_data_list.append(ans) # Return the number of data
  58 + list_size = len(nb_data_list)
  59 + for j in range (0, list_size):
  60 + nb_data = nb_data+nb_data_list[j]
  61 + return nb_data
  62 + except socket.timeout:
  63 + print "Socket timeout error when reading."
  64 + raise
  65 +
  66 + def disconnect(self):
  67 + self.send('*RST')
  68 + self.send("SYST:BEEP")
  69 + self.sock.close()
  70 +
  71 + def send(self, command):
  72 + self.sock.send("%s\n"%command)
instruments/AG34972A.py
  1 +from abstract_instrument import abstract_instrument
  2 +import socket
  3 +
  4 +#==============================================================================
  5 +
  6 +ALL_VAL_TYPE = ['DCV', 'ACV', 'DCI', 'ACI', 'RES2W', 'RES4W', 'FREQ']
  7 +ALL_CHANNELS = ['101', '102', '103', '104', '105']
  8 +
  9 +ADRESS = "192.168.0.72"
  10 +CONF_VAL_TYPE = ['CONF:VOLT:DC', 'CONF:VOLT:AC', 'CONF:CURR:DC', 'CONF:CURR:AC', 'CONF:RES', 'CONF:FRES', 'CONF:FREQ']
  11 +
  12 +#==============================================================================
  13 +
  14 +class AG34972A(abstract_instrument):
  15 + def __init__(self, channels, vtypes, adress):
  16 + self.adress = adress
  17 + self.port = 5025
  18 + self.channels = channels
  19 + self.vtypes = vtypes
  20 +
  21 + def model(self):
  22 + #self.send("*IDN?")
  23 + #return self.read()
  24 + return "AG34972A"
  25 +
  26 + def connect(self):
  27 + print('Connecting to device @%s:%s...' %(self.adress, self.port))
  28 + self.sock = socket.socket(socket.AF_INET,
  29 + socket.SOCK_STREAM,
  30 + socket.IPPROTO_TCP)
  31 + self.sock.settimeout(2.0) # Don't hang around forever
  32 + self.sock.connect((self.adress, self.port))
  33 + self.send("SYST:BEEP")
  34 + print(' --> Ok')
  35 + print(self.model())
  36 + self.configure()
  37 +
  38 + def configure(self):
  39 + self.strCh = ''
  40 + for ch in self.channels:
  41 + self.send('%s (@%s)'%(CONF_VAL_TYPE[ALL_VAL_TYPE.index(self.vtypes[self.channels.index(ch)])], ch))
  42 + self.strCh = self.strCh + ch + ','
  43 + self.strCh = self.strCh[0:-1]
  44 + self.send("ROUT:SCAN (@%s)"%self.strCh)
  45 + self.send("TRIG:COUN 1")
  46 +
  47 + def getValue(self):
  48 + self.send("INIT")
  49 + self.send("FETC?")
  50 + return self.read()
  51 +
  52 + def read(self):
  53 + ans = ''
  54 + nb_data_list = []
  55 + nb_data = ''
  56 + try:
  57 + while ans != '\n':
  58 + ans = self.sock.recv(1)
  59 + nb_data_list.append(ans) # Return the number of data
  60 + list_size = len(nb_data_list)
  61 + for j in range (0, list_size):
  62 + nb_data = nb_data+nb_data_list[j]
  63 + return nb_data
  64 + except socket.timeout:
  65 + print "Socket timeout error when reading."
  66 + raise
  67 +
  68 + def disconnect(self):
  69 + self.send('*RST')
  70 + self.sock.close()
  71 +
  72 + def send(self, command):
  73 + self.sock.send("%s\n"%command)
instruments/LS350.py
  1 +from abstract_instrument import abstract_instrument
  2 +import socket
  3 +
  4 +#==============================================================================
  5 +
  6 +ALL_VAL_TYPE = ['TEMP', 'RES']
  7 +ALL_CHANNELS = ['a', 'b', 'c', 'd']
  8 +
  9 +ADRESS = "192.168.0.12"
  10 +CONF_VAL_TYPE = ['krdg?', 'srdg?']
  11 +
  12 +#==============================================================================
  13 +
  14 +class LS350(abstract_instrument):
  15 + def __init__(self, channels, vtypes, adress):
  16 + self.adress = adress
  17 + self.port = 7777
  18 + self.channels = channels
  19 + self.vtypes = vtypes
  20 +
  21 + def model(self):
  22 + #self.send("*IDN?")
  23 + #return self.read()
  24 + return "LS350"
  25 +
  26 + def connect(self):
  27 + print('Connecting to device @%s:%s...' %(self.adress, self.port))
  28 + self.sock = socket.socket(socket.AF_INET,
  29 + socket.SOCK_STREAM,
  30 + socket.IPPROTO_TCP)
  31 + self.sock.settimeout(10.0) # Don't hang around forever
  32 + self.sock.connect((self.adress, self.port))
  33 + print(' --> Ok')
  34 + print(self.model())
  35 + self.configure()
  36 +
  37 + def configure(self):
  38 + self.strCh = ''
  39 + for ch in self.channels:
  40 + self.strCh = self.strCh + '%s %s;'%(CONF_VAL_TYPE[ALL_VAL_TYPE.index(self.vtypes[self.channels.index(ch)])], ch)
  41 + self.strCh = self.strCh[0:-1]
  42 + print(self.strCh)
  43 +
  44 + def getValue(self):
  45 + self.send(self.strCh)
  46 + return self.read()
  47 +
  48 + def read(self):
  49 + self.send("++read eoi")
  50 + ans = ''
  51 + nb_data_list = []
  52 + nb_data = ''
  53 + try:
  54 + while ans != '\n':
  55 + ans = self.sock.recv(1)
  56 + nb_data_list.append(ans) # Return the number of data
  57 + list_size = len(nb_data_list)
  58 + for j in range (0, list_size):
  59 + nb_data = nb_data+nb_data_list[j]
  60 + return nb_data
  61 + except socket.timeout:
  62 + print "Socket timeout error when reading."
  63 + raise
  64 +
  65 + def disconnect(self):
  66 + self.send('MODE0')
  67 + self.sock.close()
  68 +
  69 + def send(self, command):
  70 + self.sock.send("%s\n"%command)
instruments/PM100D.py
  1 +from abstract_instrument import abstract_instrument
  2 +import os
  3 +
  4 +#==============================================================================
  5 +
  6 +ALL_VAL_TYPE = ['PWR']
  7 +ALL_CHANNELS = ['1']
  8 +
  9 +ADRESS = "/dev/usbtmc0"
  10 +CONF_VAL_TYPE = ['PWR']
  11 +
  12 +#==============================================================================
  13 +
  14 +class PM100D(abstract_instrument):
  15 + def __init__(self, channels, vtypes, adress):
  16 + self.adress = adress
  17 + self.channels = channels
  18 + self.vtypes = vtypes
  19 +
  20 + def model(self):
  21 + #self.send("*IDN?")
  22 + #return self.read()
  23 + return "PM100D"
  24 +
  25 + def connect(self):
  26 + print('Connecting to device @%s...' %(self.adress))
  27 + self.FILE = os.open(self.adress, os.O_RDWR)
  28 + print(' --> Ok')
  29 + print(self.model())
  30 + self.configure()
  31 +
  32 + def configure(self):
  33 + pass
  34 +
  35 + def getValue(self):
  36 + self.send("READ?")
  37 + return self.read()
  38 +
  39 + def read(self):
  40 + return os.read(self.FILE, 300)
  41 +
  42 + def disconnect(self):
  43 + self.send('*RST')
  44 +
  45 + def send(self, command):
  46 + os.write(self.FILE, command)
instruments/T7Pro.py
  1 +from abstract_instrument import abstract_instrument
  2 +from labjack import ljm
  3 +import numpy
  4 +
  5 +#==============================================================================
  6 +
  7 +ALL_VAL_TYPE = ['TEMP', 'RES']
  8 +ALL_CHANNELS = ['TEMP', '1', '2', '3', '4']
  9 +ADRESS = "192.168.0.25"
  10 +
  11 +#==============================================================================
  12 +
  13 +class T7Pro(abstract_instrument):
  14 + def __init__(self, adress=ADRESS, vtype=[ALL_VAL_TYPE[0]], channels = [ALL_CHANNELS[0]]):
  15 + self.adress = adress
  16 + self.vtype = vtype
  17 + self.tempName = ["TEMPERATURE_AIR_K"]
  18 + self.res1Name = ["AIN0", "AIN10"]
  19 + self.res2Name = ["AIN2", "AIN11"]
  20 + self.res3Name = ["AIN4", "AIN12"]
  21 + self.res4Name = ["AIN6", "AIN13"]
  22 +
  23 + def model(self):
  24 + return 'T7Pro'
  25 +
  26 + def connect(self):
  27 + try:
  28 + print('Connecting to device @%s...' %(self.adress))
  29 + self.handle = ljm.openS("T7", "ETHERNET", self.adress)
  30 + self.configureAINs()
  31 + print(' --> Ok')
  32 +
  33 + print(self.model())
  34 +
  35 + if self.vtype == "TEMP":
  36 + 1
  37 + elif self.vtype == "RES":
  38 + 1
  39 + else:
  40 + print("Wrong -v argument")
  41 + raise
  42 +
  43 + except Exception as er:
  44 + print("Unexpected error during connection: " + str(er))
  45 + raise
  46 +
  47 + def getValue(self):
  48 + mesTemp = self.read(self.tempName)
  49 + mesRes1 = self.read(self.res1Name)
  50 + mesRes2 = self.read(self.res2Name)
  51 + mesRes3 = self.read(self.res3Name)
  52 + mesRes4 = self.read(self.res4Name)
  53 +# mesRes4 = [1, 1]
  54 +# print("~~~~~~~~~~~~~~~~~~~~~~\n" + str(results) + "~~~~~~~~~~~~~~~~~~~~~~\n")
  55 + temp = mesTemp[0]
  56 + res1 = 100.*mesRes1[0]/mesRes1[1]
  57 + res2 = 100.*mesRes2[0]/mesRes2[1]
  58 + res3 = 100.*mesRes3[0]/mesRes3[1]
  59 + res4 = 100.*mesRes4[0]/mesRes4[1]
  60 +
  61 + if self.vtype == 'TEMP':
  62 + # Temperature calculation
  63 + temp1 = self.res2tempSensor(628, res1)
  64 + temp2 = self.res2tempSensor(16947, res2)
  65 + temp3 = self.res2tempSensor(625, res3)
  66 + temp4 = self.res2tempSensor(100, res4)
  67 + string = '%f\t%f\t%f\t%f\t%f\n'%(temp, temp1, temp2, temp3, temp4)
  68 +# string = '%f\t%f\n'%(temp, temp1)
  69 + elif self.vtype == 'RES':
  70 + string = '%f\t%f\t%f\t%f\t%f\n'%(temp, res1, res2, res3, res4)
  71 +# string = '%f\t%f\n'%(temp, res1)
  72 + else:
  73 + string = ''
  74 +
  75 + return string
  76 +
  77 + def read(self, names):
  78 + return ljm.eReadNames(self.handle, len(names), names)
  79 +
  80 + def disconnect(self):
  81 + ljm.close(self.handle)
  82 +
  83 + def send(self, command):
  84 + pass
  85 +
  86 + def configureAINs(self):
  87 + # Setup and call eWriteNames to configure AINs on the LabJack.
  88 + names = ["AIN0_NEGATIVE_CH", "AIN0_RANGE", "AIN0_RESOLUTION_INDEX",
  89 + "AIN1_NEGATIVE_CH", "AIN1_RANGE", "AIN1_RESOLUTION_INDEX",
  90 + "AIN2_NEGATIVE_CH", "AIN2_RANGE", "AIN2_RESOLUTION_INDEX",
  91 + "AIN3_NEGATIVE_CH", "AIN3_RANGE", "AIN3_RESOLUTION_INDEX",
  92 + "AIN4_NEGATIVE_CH", "AIN4_RANGE", "AIN4_RESOLUTION_INDEX",
  93 + "AIN5_NEGATIVE_CH", "AIN5_RANGE", "AIN5_RESOLUTION_INDEX",
  94 + "AIN6_NEGATIVE_CH", "AIN6_RANGE", "AIN6_RESOLUTION_INDEX",
  95 + "AIN7_NEGATIVE_CH", "AIN7_RANGE", "AIN7_RESOLUTION_INDEX",
  96 + "AIN8_NEGATIVE_CH", "AIN8_RANGE", "AIN8_RESOLUTION_INDEX",
  97 + "AIN9_NEGATIVE_CH", "AIN9_RANGE", "AIN9_RESOLUTION_INDEX",
  98 + "AIN10_NEGATIVE_CH", "AIN10_RANGE", "AIN10_RESOLUTION_INDEX",
  99 + "AIN11_NEGATIVE_CH", "AIN11_RANGE", "AIN11_RESOLUTION_INDEX",
  100 + "AIN12_NEGATIVE_CH", "AIN12_RANGE", "AIN12_RESOLUTION_INDEX",
  101 + "AIN13_NEGATIVE_CH", "AIN13_RANGE", "AIN13_RESOLUTION_INDEX"
  102 + ]
  103 + l_names = len(names)
  104 + aValues = [1, 0.1, 12,#0
  105 + 199, 0.1, 12,#1
  106 + 3, 0.1, 12,#2
  107 + 199, 0.1, 12,#3
  108 + 5, 0.1, 12,#4
  109 + 199, 0.1, 12,#5
  110 + 7, 0.1, 12,#6
  111 + 199, 0.1, 12,#7
  112 + 199, 0.1, 12,#8
  113 + 199, 0.1, 12,#9
  114 + 199, 0.1, 12,#10
  115 + 199, 0.1, 12,#11
  116 + 199, 0.1, 12,#12
  117 + 199, 0.1, 12#13
  118 + ]
  119 + ljm.eWriteNames(self.handle, l_names, names, aValues)
  120 +
  121 +
  122 + def res2tempSensor(self, sensor, res):
  123 + if sensor==627:
  124 + K = [0.399341181655472610,
  125 + 10.8420092277810909,
  126 + -26.4597939187660813,
  127 + 245.9828566655493379,
  128 + -668.069876596331596,
  129 + 1001.69882618263364,
  130 + -267.272089680656791]
  131 + if sensor==625:
  132 + K = [0.333548856582638109,
  133 + 11.7361551595386118,
  134 + -31.32988932320903987,
  135 + 262.878643524833024,
  136 + -704.163538021035492,
  137 + 1056.6040485650301,
  138 + -307.057196729816496]
  139 + if sensor==628:
  140 + K = [0.463200932294057566,
  141 + 13.5049710820894688,
  142 + -30.5191222755238414,
  143 + 231.098593852017075,
  144 + -550.122691885568202,
  145 + 806.038547554984689,
  146 + -198.510489917360246]
  147 + if sensor==16945:
  148 + K = [3.2497, 5.1777, 2.499]
  149 + if sensor==16943:
  150 + K = [3.4738, 5.1198, 2.3681]
  151 + if sensor==16944:
  152 + K = [3.3674, 5.2874, 2.5165]
  153 + if sensor==16941:
  154 + K = [2.9486, 4.5862, 2.266]
  155 + if sensor==16947:
  156 + K = [3.4597, 5.2422, 2.4169]
  157 + if sensor==100:
  158 + K = [0.003850]
  159 + return self.res2temp(K, res)
  160 +
  161 + def res2temp(K, res):
  162 + temp = 0
  163 + tmp = 1000./res
  164 + if len(K)==7:
  165 + for i in range(len(K)):
  166 + temp += K[i]*tmp**i
  167 + if len(K)==3:
  168 + for i in range(len(K)):
  169 + temp += K[i]*numpy.log10(tmp)**(2-i)
  170 + temp = 10**temp
  171 + if len(K)==1:
  172 + temp = (res/100.-1)/K[0]+273.15
  173 + return temp
instruments/TPG261.py
  1 +from abstract_instrument import abstract_instrument
  2 +import serial
  3 +
  4 +#==============================================================================
  5 +
  6 +ALL_VAL_TYPE = ['PRE']
  7 +ALL_CHANNELS = ['1']
  8 +ADRESS = "/dev/ttyS0"
  9 +
  10 +#==============================================================================
  11 +
  12 +class TPG261(abstract_instrument):
  13 + def __init__(self, adress=ADRESS, vtype=[ALL_VAL_TYPE[0]], channels = [ALL_CHANNELS[0]]):
  14 + self.adress = adress
  15 + self.vtype = vtype
  16 +
  17 + def model(self):
  18 + return "PfeifferTPG261"
  19 +
  20 + def connect(self):
  21 + try:
  22 + print('Connecting to device @%s...' %(self.adress))
  23 + self.TPG = MaxiGauge(self.adress)
  24 + print(' --> Ok')
  25 +
  26 + print(self.model())
  27 +
  28 + if self.vtype == "PRE":
  29 + 1
  30 + else:
  31 + print("Wrong -v argument")
  32 + raise
  33 +
  34 + except Exception as er:
  35 + print("Unexpected error during connection: " + str(er))
  36 + raise
  37 +
  38 + def getValue(self):
  39 + self.read()
  40 + return "%s\n"%self.ps[0].pressure
  41 +
  42 + def read(self):
  43 + self.ps = self.TPG.pressures()
  44 +
  45 + def disconnect(self):
  46 + self.TPG.disconnect()
  47 +
  48 + def send(self, command):
  49 + pass
  50 +
  51 +
  52 +
  53 +
  54 +# from Philipp Klaus, philipp.l.klaus AT web.de PfeifferVacuum.py
  55 +
  56 +class MaxiGauge (object):
  57 + def __init__(self, serialPort, baud=9600, debug=False):
  58 + self.debug=debug
  59 + try:
  60 + self.connection = serial.Serial(serialPort, baudrate=baud, timeout=0.2)
  61 + except serial.serialutil.SerialException as se:
  62 + raise MaxiGaugeError(se)
  63 + #self.send(C['ETX']) ### We might reset the connection first, but it doesn't really matter:
  64 +
  65 + def checkDevice(self):
  66 + message = "The Display Contrast is currently set to %d (out of 20).\n" % self.displayContrast()
  67 + message += "Keys since MaxiGauge was switched on: %s (out of 1,2,3,4,5).\n" % ", ".join( map (str, self.pressedKeys()) )
  68 + return message
  69 +
  70 + def pressedKeys(self):
  71 + keys = int(self.send('TKB',1)[0])
  72 + pressedKeys = []
  73 + for i in [4,3,2,1,0]: # It's got 5 keys
  74 + if keys/2**i == 1:
  75 + pressedKeys.append(i+1)
  76 + keys = keys%2**i
  77 + pressedKeys.reverse()
  78 + return pressedKeys
  79 +
  80 + def displayContrast(self,newContrast=-1):
  81 + if newContrast == -1: return int(self.send('DCC',1)[0])
  82 + else: return int(self.send('DCC,%d' % (newContrast,) ,1)[0])
  83 +
  84 + def pressures(self):
  85 + return [self.pressure(i+1) for i in range(1)]
  86 +
  87 + def pressure(self, sensor):
  88 + if sensor < 1 or sensor >6: raise MaxiGaugeError('Sensor can only be between 1 and 6. You choose ' + str(sensor))
  89 + reading = self.send('PR%d' % sensor, 1) ## reading will have the form x,x.xxxEsx <CR><LF> (see p.88)
  90 + try:
  91 + r = reading[0].split(',')
  92 + status = int(r[0])
  93 + pressure = float(r[-1])
  94 + except:
  95 + raise MaxiGaugeError("Problem interpreting the returned line:\n%s" % reading)
  96 + return PressureReading(sensor, status, pressure)
  97 +
  98 + def debugMessage(self, message):
  99 + if self.debug: print(repr(message))
  100 +
  101 + def send(self, mnemonic, numEnquiries = 0):
  102 + self.connection.flushInput()
  103 + self.write(mnemonic+LINE_TERMINATION)
  104 + #if mnemonic != C['ETX']: self.read()
  105 + #self.read()
  106 + self.getACQorNAK()
  107 + response = []
  108 + for i in range(numEnquiries):
  109 + self.enquire()
  110 + response.append(self.read())
  111 + return response
  112 +
  113 + def write(self,what):
  114 + self.debugMessage(what)
  115 + self.connection.write(what)
  116 +
  117 + def enquire(self):
  118 + self.write(C['ENQ'])
  119 +
  120 + def read(self):
  121 + data = ""
  122 + while True:
  123 + x = self.connection.read()
  124 + self.debugMessage(x)
  125 + data += x
  126 + if len(data)>1 and data[-2:]==LINE_TERMINATION:
  127 + break
  128 + return data[:-len(LINE_TERMINATION)]
  129 +
  130 + def getACQorNAK(self):
  131 + returncode = self.connection.readline()
  132 + self.debugMessage(returncode)
  133 + ## The following is usually expected but our MaxiGauge controller sometimes forgets this parameter... That seems to be a bug with the DCC command.
  134 + #if len(returncode)<3: raise MaxiGaugeError('Only received a line termination from MaxiGauge. Was expecting ACQ or NAK.')
  135 + if len(returncode)<3: self.debugMessage('Only received a line termination from MaxiGauge. Was expecting ACQ or NAK.')
  136 + if len(returncode)>2 and returncode[-3] == C['NAK']:
  137 + self.enquire()
  138 + returnedError = self.read()
  139 + error = str(returnedError).split(',' , 1)
  140 + print repr(error)
  141 + errmsg = { 'System Error': ERR_CODES[0][int(error[0])] , 'Gauge Error': ERR_CODES[1][int(error[1])] }
  142 + raise MaxiGaugeNAK(errmsg)
  143 + #if len(returncode)>2 and returncode[-3] != C['ACQ']: raise MaxiGaugeError('Expecting ACQ or NAK from MaxiGauge but neither were sent.')
  144 + if len(returncode)>2 and returncode[-3] != C['ACQ']: self.debugMessage('Expecting ACQ or NAK from MaxiGauge but neither were sent.')
  145 + # if no exception raised so far, the interface is just fine:
  146 + return returncode[:-(len(LINE_TERMINATION)+1)]
  147 +
  148 + def disconnect(self):
  149 + #self.send(C['ETX'])
  150 + if hasattr(self, 'connection') and self.connection: self.connection.close()
  151 +
  152 + def __del__(self):
  153 + self.disconnect()
  154 +
  155 +class PressureReading(object):
  156 + def __init__(self, id, status, pressure):
  157 + if int(id) not in range(1,7): raise MaxiGaugeError('Pressure Gauge ID must be between 1-6')
  158 + self.id = int(id)
  159 + if int(status) not in PRESSURE_READING_STATUS.keys(): raise MaxiGaugeError('The Pressure Status must be in the range %s' % PRESSURE_READING_STATUS.keys())
  160 + self.status = int(status)
  161 + self.pressure = float(pressure)
  162 +
  163 + def statusMsg(self):
  164 + return PRESSURE_READING_STATUS[self.status]
  165 +
  166 + def __repr__(self):
  167 + return "Gauge #%d: Status %d (%s), Pressure: %f mbar\n" % (self.id, self.status, self.statusMsg(), self.pressure)
  168 +
  169 +
  170 +### ------ now we define the exceptions that could occur ------
  171 +
  172 +class MaxiGaugeError(Exception):
  173 + pass
  174 +
  175 +class MaxiGaugeNAK(MaxiGaugeError):
  176 + pass
  177 +
  178 +### ------- Control Symbols as defined on p. 81 of the english
  179 +### manual for the Pfeiffer Vacuum TPG256A -----------
  180 +C = {
  181 + 'ETX': "\x03", # End of Text (Ctrl-C) Reset the interface
  182 + 'CR': "\x0D", # Carriage Return Go to the beginning of line
  183 + 'LF': "\x0A", # Line Feed Advance by one line
  184 + 'ENQ': "\x05", # Enquiry Request for data transmission
  185 + 'ACQ': "\x06", # Acknowledge Positive report signal
  186 + 'NAK': "\x15", # Negative Acknowledge Negative report signal
  187 + 'ESC': "\x1b", # Escape
  188 +}
  189 +
  190 +LINE_TERMINATION=C['CR']+C['LF'] # CR, LF and CRLF are all possible (p.82)
  191 +
  192 +### Mnemonics as defined on p. 85
  193 +M = [
  194 + 'BAU', # Baud rate Baud rate 95
  195 + 'CAx', # Calibration factor Sensor x Calibration factor sensor x (1 ... 6) 92
  196 + 'CID', # Measurement point names Measurement point names 88
  197 + 'DCB', # Display control Bargraph Bargraph 89
  198 + 'DCC', # Display control Contrast Display control contrast 90
  199 + 'DCD', # Display control Digits Display digits 88
  200 + 'DCS', # Display control Screensave Display control screensave 90
  201 + 'DGS', # Degas Degas 93
  202 + 'ERR', # Error Status Error status 97
  203 + 'FIL', # Filter time constant Filter time constant 92
  204 + 'FSR', # Full scale range of linear sensors Full scale range of linear sensors 93
  205 + 'LOC', # Parameter setup lock Parameter setup lock 91
  206 + 'NAD', # Node (device) address for RS485 Node (device) address for RS485 96
  207 + 'OFC', # Offset correction Offset correction 93
  208 + 'OFC', # Offset correction Offset correction 93
  209 + 'PNR', # Program number Program number 98
  210 + 'PRx', # Status, Pressure sensor x (1 ... 6) Status, Pressure sensor x (1 ... 6) 88
  211 + 'PUC', # Underrange Ctrl Underrange control 91
  212 + 'RSX', # Interface Interface 94
  213 + 'SAV', # Save default Save default 94
  214 + 'SCx', # Sensor control Sensor control 87
  215 + 'SEN', # Sensor on/off Sensor on/off 86
  216 + 'SPx', # Set Point Control Source for Relay xThreshold value setting, Allocation 90
  217 + 'SPS', # Set Point Status A,B,C,D,E,F Set point status 91
  218 + 'TAI', # Test program A/D Identify Test A/D converter identification inputs 100
  219 + 'TAS', # Test program A/D Sensor Test A/D converter measurement value inputs 100
  220 + 'TDI', # Display test Display test 98
  221 + 'TEE', # EEPROM test EEPROM test 100
  222 + 'TEP', # EPROM test EPROM test 99
  223 + 'TID', # Sensor identification Sensor identification 101
  224 + 'TKB', # Keyboard test Keyboard test 99
  225 + 'TRA', # RAM test RAM test 99
  226 + 'UNI', # Unit of measurement (Display) Unit of measurement (pressure) 89
  227 + 'WDT', # Watchdog and System Error Control Watchdog and system error control 101
  228 +]
  229 +
  230 +
  231 +### Error codes as defined on p. 97
  232 +ERR_CODES = [
  233 + {
  234 + 0: 'No error',
  235 + 1: 'Watchdog has responded',
  236 + 2: 'Task fail error',
  237 + 4: 'IDCX idle error',
  238 + 8: 'Stack overflow error',
  239 + 16: 'EPROM error',
  240 + 32: 'RAM error',
  241 + 64: 'EEPROM error',
  242 + 128: 'Key error',
  243 + 4096: 'Syntax error',
  244 + 8192: 'Inadmissible parameter',
  245 + 16384: 'No hardware',
  246 + 32768: 'Fatal error'
  247 + } ,
  248 + {
  249 + 0: 'No error',
  250 + 1: 'Sensor 1: Measurement error',
  251 + 2: 'Sensor 2: Measurement error',
  252 + 4: 'Sensor 3: Measurement error',
  253 + 8: 'Sensor 4: Measurement error',
  254 + 16: 'Sensor 5: Measurement error',
  255 + 32: 'Sensor 6: Measurement error',
  256 + 512: 'Sensor 1: Identification error',
  257 + 1024: 'Sensor 2: Identification error',
  258 + 2048: 'Sensor 3: Identification error',
  259 + 4096: 'Sensor 4: Identification error',
  260 + 8192: 'Sensor 5: Identification error',
  261 + 16384: 'Sensor 6: Identification error',
  262 + }
  263 +]
  264 +
  265 +### pressure status as defined on p.88
  266 +PRESSURE_READING_STATUS = {
  267 + 0: 'Measurement data okay',
  268 + 1: 'Underrange',
  269 + 2: 'Overrange',
  270 + 3: 'Sensor error',
  271 + 4: 'Sensor off',
  272 + 5: 'No sensor',
  273 + 6: 'Identification error'
  274 +}
instruments/__init__.py
  1 +from os import listdir
  2 +from os.path import dirname
  3 +
  4 +for module in listdir(dirname(__file__)):
  5 + if module == '__init__.py' or module == 'abstract_instrument.py' or module[-3:] != '.py':
  6 + continue
  7 + __import__(module[:-3], locals(), globals())
  8 +
  9 +del module, listdir, dirname
instruments/abstract_instrument.py
  1 +import abc
  2 +
  3 +class abstract_instrument(object):
  4 + __metaclass__ = abc.ABCMeta
  5 +
  6 + @abc.abstractmethod
  7 + def __init__(self, adress, vtype, channel):
  8 + """Build the class"""
  9 + return
  10 +
  11 + @abc.abstractmethod
  12 + def model(self):
  13 + """return the instrument model"""
  14 + return
  15 +
  16 + @abc.abstractmethod
  17 + def connect(self):
  18 + """Create a connection with the instrument"""
  19 + return
  20 +
  21 + @abc.abstractmethod
  22 + def disconnect(self):
  23 + """Disconnect the instrument"""
  24 + return
  25 +
  26 + @abc.abstractmethod
  27 + def configure(self):
  28 + """Configure the instrument"""
  29 + return
  30 +
  31 + @abc.abstractmethod
  32 + def read(self):
  33 + """read the buffer"""
  34 + return
  35 +
  36 + @abc.abstractmethod
  37 + def send(self):
  38 + """send a command"""
  39 + return
  40 +
  41 + @abc.abstractmethod
  42 + def getValue(self):
  43 + """return the value of measurment"""
  44 + return
instruments/testDevice.py
  1 +from abstract_instrument import abstract_instrument
  2 +import numpy, time
  3 +
  4 +#==============================================================================
  5 +
  6 +ALL_VAL_TYPE = ['vtype', 'DCV', 'ACV', 'DCI', 'ACI', 'RES2W', 'RES4W', 'FREQ']
  7 +ALL_CHANNELS = ['0', '1']
  8 +ADRESS = "123.456.789.123"
  9 +
  10 +#==============================================================================
  11 +
  12 +class testDevice(abstract_instrument):
  13 + def __init__(self, channels, vtype, adress = ADRESS):
  14 + self.adress = adress
  15 + self.port = 9999
  16 + self.channels = channels
  17 + print(self.channels)
  18 + self.vtype = vtype
  19 + print(self.vtype)
  20 +
  21 + def model(self):
  22 + return 'test_device'
  23 +
  24 + def connect(self):
  25 + print('Connecting to device @%s:%s...' %(self.adress, self.port))
  26 + time.sleep(1)
  27 + print(' --> Ok')
  28 +
  29 + print(self.model())
  30 +
  31 + def getValue(self):
  32 + mes = ""
  33 + for ch in self.channels:
  34 + mes = mes + str(numpy.random.rand()) + '\t'
  35 + return mes + '\n'
  36 +
  37 + def read(self):
  38 + print('reading')
  39 + return 1
  40 +
  41 + def disconnect(self):
  42 + print('disconnect')
  43 +
  44 + def send(self, command):
  45 + print('send %s'%command)