diff --git a/instruments/AG34461A.py b/instruments/AG34461A.py new file mode 100644 index 0000000..87987a4 --- /dev/null +++ b/instruments/AG34461A.py @@ -0,0 +1,72 @@ +from abstract_instrument import abstract_instrument +import socket + +#============================================================================== + +ALL_VAL_TYPE = ['DCV', 'ACV', 'DCI', 'ACI', 'RES2W', 'RES4W', 'FREQ'] +ALL_CHANNELS = ['1'] + +ADRESS = "192.168.0.61" +CONF_VAL_TYPE = ['CONF:VOLT:DC', 'CONF:VOLT:AC', 'CONF:CURR:DC', 'CONF:CURR:AC', 'CONF:RES', 'CONF:FRES', 'CONF:FREQ'] + +#============================================================================== + +class AG34461A(abstract_instrument): + def __init__(self, channels, vtypes, adress=ADRESS): + self.adress = adress + self.port = 5025 + self.channels = channels + self.vtypes = vtypes + + def model(self): + #self.send("*IDN?") + #return self.read() + return "AG34461A" + + def connect(self): + print('Connecting to device @%s:%s...' %(self.adress, self.port)) + self.sock = socket.socket(socket.AF_INET, + socket.SOCK_STREAM, + socket.IPPROTO_TCP) + self.sock.settimeout(10.0) # Don't hang around forever + self.sock.connect((self.adress, self.port)) + self.send("SYST:BEEP") + print(' --> Ok') + print(self.model()) + self.configure() + + def configure(self): + for ch in self.channels: + self.send(CONF_VAL_TYPE[ALL_VAL_TYPE.index(self.vtypes[self.channels.index(ch)])]) + + def getValue(self): + mes = '' + for ch in self.channels: + self.send("READ?") + mesTemp = self.read() + mes = mes + '\t' + mesTemp + return mes + + def read(self): + ans = '' + nb_data_list = [] + nb_data = '' + try: + while ans != '\n': + ans = self.sock.recv(1) + nb_data_list.append(ans) # Return the number of data + list_size = len(nb_data_list) + for j in range (0, list_size): + nb_data = nb_data+nb_data_list[j] + return nb_data + except socket.timeout: + print "Socket timeout error when reading." + raise + + def disconnect(self): + self.send('*RST') + self.send("SYST:BEEP") + self.sock.close() + + def send(self, command): + self.sock.send("%s\n"%command) diff --git a/instruments/AG34972A.py b/instruments/AG34972A.py new file mode 100644 index 0000000..803cdba --- /dev/null +++ b/instruments/AG34972A.py @@ -0,0 +1,73 @@ +from abstract_instrument import abstract_instrument +import socket + +#============================================================================== + +ALL_VAL_TYPE = ['DCV', 'ACV', 'DCI', 'ACI', 'RES2W', 'RES4W', 'FREQ'] +ALL_CHANNELS = ['101', '102', '103', '104', '105'] + +ADRESS = "192.168.0.72" +CONF_VAL_TYPE = ['CONF:VOLT:DC', 'CONF:VOLT:AC', 'CONF:CURR:DC', 'CONF:CURR:AC', 'CONF:RES', 'CONF:FRES', 'CONF:FREQ'] + +#============================================================================== + +class AG34972A(abstract_instrument): + def __init__(self, channels, vtypes, adress): + self.adress = adress + self.port = 5025 + self.channels = channels + self.vtypes = vtypes + + def model(self): + #self.send("*IDN?") + #return self.read() + return "AG34972A" + + def connect(self): + print('Connecting to device @%s:%s...' %(self.adress, self.port)) + self.sock = socket.socket(socket.AF_INET, + socket.SOCK_STREAM, + socket.IPPROTO_TCP) + self.sock.settimeout(2.0) # Don't hang around forever + self.sock.connect((self.adress, self.port)) + self.send("SYST:BEEP") + print(' --> Ok') + print(self.model()) + self.configure() + + def configure(self): + self.strCh = '' + for ch in self.channels: + self.send('%s (@%s)'%(CONF_VAL_TYPE[ALL_VAL_TYPE.index(self.vtypes[self.channels.index(ch)])], ch)) + self.strCh = self.strCh + ch + ',' + self.strCh = self.strCh[0:-1] + self.send("ROUT:SCAN (@%s)"%self.strCh) + self.send("TRIG:COUN 1") + + def getValue(self): + self.send("INIT") + self.send("FETC?") + return self.read() + + def read(self): + ans = '' + nb_data_list = [] + nb_data = '' + try: + while ans != '\n': + ans = self.sock.recv(1) + nb_data_list.append(ans) # Return the number of data + list_size = len(nb_data_list) + for j in range (0, list_size): + nb_data = nb_data+nb_data_list[j] + return nb_data + except socket.timeout: + print "Socket timeout error when reading." + raise + + def disconnect(self): + self.send('*RST') + self.sock.close() + + def send(self, command): + self.sock.send("%s\n"%command) diff --git a/instruments/LS350.py b/instruments/LS350.py new file mode 100644 index 0000000..210aa00 --- /dev/null +++ b/instruments/LS350.py @@ -0,0 +1,70 @@ +from abstract_instrument import abstract_instrument +import socket + +#============================================================================== + +ALL_VAL_TYPE = ['TEMP', 'RES'] +ALL_CHANNELS = ['a', 'b', 'c', 'd'] + +ADRESS = "192.168.0.12" +CONF_VAL_TYPE = ['krdg?', 'srdg?'] + +#============================================================================== + +class LS350(abstract_instrument): + def __init__(self, channels, vtypes, adress): + self.adress = adress + self.port = 7777 + self.channels = channels + self.vtypes = vtypes + + def model(self): + #self.send("*IDN?") + #return self.read() + return "LS350" + + def connect(self): + print('Connecting to device @%s:%s...' %(self.adress, self.port)) + self.sock = socket.socket(socket.AF_INET, + socket.SOCK_STREAM, + socket.IPPROTO_TCP) + self.sock.settimeout(10.0) # Don't hang around forever + self.sock.connect((self.adress, self.port)) + print(' --> Ok') + print(self.model()) + self.configure() + + def configure(self): + self.strCh = '' + for ch in self.channels: + self.strCh = self.strCh + '%s %s;'%(CONF_VAL_TYPE[ALL_VAL_TYPE.index(self.vtypes[self.channels.index(ch)])], ch) + self.strCh = self.strCh[0:-1] + print(self.strCh) + + def getValue(self): + self.send(self.strCh) + return self.read() + + def read(self): + self.send("++read eoi") + ans = '' + nb_data_list = [] + nb_data = '' + try: + while ans != '\n': + ans = self.sock.recv(1) + nb_data_list.append(ans) # Return the number of data + list_size = len(nb_data_list) + for j in range (0, list_size): + nb_data = nb_data+nb_data_list[j] + return nb_data + except socket.timeout: + print "Socket timeout error when reading." + raise + + def disconnect(self): + self.send('MODE0') + self.sock.close() + + def send(self, command): + self.sock.send("%s\n"%command) diff --git a/instruments/PM100D.py b/instruments/PM100D.py new file mode 100644 index 0000000..dafca66 --- /dev/null +++ b/instruments/PM100D.py @@ -0,0 +1,46 @@ +from abstract_instrument import abstract_instrument +import os + +#============================================================================== + +ALL_VAL_TYPE = ['PWR'] +ALL_CHANNELS = ['1'] + +ADRESS = "/dev/usbtmc0" +CONF_VAL_TYPE = ['PWR'] + +#============================================================================== + +class PM100D(abstract_instrument): + def __init__(self, channels, vtypes, adress): + self.adress = adress + self.channels = channels + self.vtypes = vtypes + + def model(self): + #self.send("*IDN?") + #return self.read() + return "PM100D" + + def connect(self): + print('Connecting to device @%s...' %(self.adress)) + self.FILE = os.open(self.adress, os.O_RDWR) + print(' --> Ok') + print(self.model()) + self.configure() + + def configure(self): + pass + + def getValue(self): + self.send("READ?") + return self.read() + + def read(self): + return os.read(self.FILE, 300) + + def disconnect(self): + self.send('*RST') + + def send(self, command): + os.write(self.FILE, command) diff --git a/instruments/T7Pro.py b/instruments/T7Pro.py new file mode 100644 index 0000000..c903264 --- /dev/null +++ b/instruments/T7Pro.py @@ -0,0 +1,173 @@ +from abstract_instrument import abstract_instrument +from labjack import ljm +import numpy + +#============================================================================== + +ALL_VAL_TYPE = ['TEMP', 'RES'] +ALL_CHANNELS = ['TEMP', '1', '2', '3', '4'] +ADRESS = "192.168.0.25" + +#============================================================================== + +class T7Pro(abstract_instrument): + def __init__(self, adress=ADRESS, vtype=[ALL_VAL_TYPE[0]], channels = [ALL_CHANNELS[0]]): + self.adress = adress + self.vtype = vtype + self.tempName = ["TEMPERATURE_AIR_K"] + self.res1Name = ["AIN0", "AIN10"] + self.res2Name = ["AIN2", "AIN11"] + self.res3Name = ["AIN4", "AIN12"] + self.res4Name = ["AIN6", "AIN13"] + + def model(self): + return 'T7Pro' + + def connect(self): + try: + print('Connecting to device @%s...' %(self.adress)) + self.handle = ljm.openS("T7", "ETHERNET", self.adress) + self.configureAINs() + print(' --> Ok') + + print(self.model()) + + if self.vtype == "TEMP": + 1 + elif self.vtype == "RES": + 1 + else: + print("Wrong -v argument") + raise + + except Exception as er: + print("Unexpected error during connection: " + str(er)) + raise + + def getValue(self): + mesTemp = self.read(self.tempName) + mesRes1 = self.read(self.res1Name) + mesRes2 = self.read(self.res2Name) + mesRes3 = self.read(self.res3Name) + mesRes4 = self.read(self.res4Name) +# mesRes4 = [1, 1] +# print("~~~~~~~~~~~~~~~~~~~~~~\n" + str(results) + "~~~~~~~~~~~~~~~~~~~~~~\n") + temp = mesTemp[0] + res1 = 100.*mesRes1[0]/mesRes1[1] + res2 = 100.*mesRes2[0]/mesRes2[1] + res3 = 100.*mesRes3[0]/mesRes3[1] + res4 = 100.*mesRes4[0]/mesRes4[1] + + if self.vtype == 'TEMP': + # Temperature calculation + temp1 = self.res2tempSensor(628, res1) + temp2 = self.res2tempSensor(16947, res2) + temp3 = self.res2tempSensor(625, res3) + temp4 = self.res2tempSensor(100, res4) + string = '%f\t%f\t%f\t%f\t%f\n'%(temp, temp1, temp2, temp3, temp4) +# string = '%f\t%f\n'%(temp, temp1) + elif self.vtype == 'RES': + string = '%f\t%f\t%f\t%f\t%f\n'%(temp, res1, res2, res3, res4) +# string = '%f\t%f\n'%(temp, res1) + else: + string = '' + + return string + + def read(self, names): + return ljm.eReadNames(self.handle, len(names), names) + + def disconnect(self): + ljm.close(self.handle) + + def send(self, command): + pass + + def configureAINs(self): + # Setup and call eWriteNames to configure AINs on the LabJack. + names = ["AIN0_NEGATIVE_CH", "AIN0_RANGE", "AIN0_RESOLUTION_INDEX", + "AIN1_NEGATIVE_CH", "AIN1_RANGE", "AIN1_RESOLUTION_INDEX", + "AIN2_NEGATIVE_CH", "AIN2_RANGE", "AIN2_RESOLUTION_INDEX", + "AIN3_NEGATIVE_CH", "AIN3_RANGE", "AIN3_RESOLUTION_INDEX", + "AIN4_NEGATIVE_CH", "AIN4_RANGE", "AIN4_RESOLUTION_INDEX", + "AIN5_NEGATIVE_CH", "AIN5_RANGE", "AIN5_RESOLUTION_INDEX", + "AIN6_NEGATIVE_CH", "AIN6_RANGE", "AIN6_RESOLUTION_INDEX", + "AIN7_NEGATIVE_CH", "AIN7_RANGE", "AIN7_RESOLUTION_INDEX", + "AIN8_NEGATIVE_CH", "AIN8_RANGE", "AIN8_RESOLUTION_INDEX", + "AIN9_NEGATIVE_CH", "AIN9_RANGE", "AIN9_RESOLUTION_INDEX", + "AIN10_NEGATIVE_CH", "AIN10_RANGE", "AIN10_RESOLUTION_INDEX", + "AIN11_NEGATIVE_CH", "AIN11_RANGE", "AIN11_RESOLUTION_INDEX", + "AIN12_NEGATIVE_CH", "AIN12_RANGE", "AIN12_RESOLUTION_INDEX", + "AIN13_NEGATIVE_CH", "AIN13_RANGE", "AIN13_RESOLUTION_INDEX" + ] + l_names = len(names) + aValues = [1, 0.1, 12,#0 + 199, 0.1, 12,#1 + 3, 0.1, 12,#2 + 199, 0.1, 12,#3 + 5, 0.1, 12,#4 + 199, 0.1, 12,#5 + 7, 0.1, 12,#6 + 199, 0.1, 12,#7 + 199, 0.1, 12,#8 + 199, 0.1, 12,#9 + 199, 0.1, 12,#10 + 199, 0.1, 12,#11 + 199, 0.1, 12,#12 + 199, 0.1, 12#13 + ] + ljm.eWriteNames(self.handle, l_names, names, aValues) + + + def res2tempSensor(self, sensor, res): + if sensor==627: + K = [0.399341181655472610, + 10.8420092277810909, + -26.4597939187660813, + 245.9828566655493379, + -668.069876596331596, + 1001.69882618263364, + -267.272089680656791] + if sensor==625: + K = [0.333548856582638109, + 11.7361551595386118, + -31.32988932320903987, + 262.878643524833024, + -704.163538021035492, + 1056.6040485650301, + -307.057196729816496] + if sensor==628: + K = [0.463200932294057566, + 13.5049710820894688, + -30.5191222755238414, + 231.098593852017075, + -550.122691885568202, + 806.038547554984689, + -198.510489917360246] + if sensor==16945: + K = [3.2497, 5.1777, 2.499] + if sensor==16943: + K = [3.4738, 5.1198, 2.3681] + if sensor==16944: + K = [3.3674, 5.2874, 2.5165] + if sensor==16941: + K = [2.9486, 4.5862, 2.266] + if sensor==16947: + K = [3.4597, 5.2422, 2.4169] + if sensor==100: + K = [0.003850] + return self.res2temp(K, res) + + def res2temp(K, res): + temp = 0 + tmp = 1000./res + if len(K)==7: + for i in range(len(K)): + temp += K[i]*tmp**i + if len(K)==3: + for i in range(len(K)): + temp += K[i]*numpy.log10(tmp)**(2-i) + temp = 10**temp + if len(K)==1: + temp = (res/100.-1)/K[0]+273.15 + return temp diff --git a/instruments/TPG261.py b/instruments/TPG261.py new file mode 100644 index 0000000..d259383 --- /dev/null +++ b/instruments/TPG261.py @@ -0,0 +1,274 @@ +from abstract_instrument import abstract_instrument +import serial + +#============================================================================== + +ALL_VAL_TYPE = ['PRE'] +ALL_CHANNELS = ['1'] +ADRESS = "/dev/ttyS0" + +#============================================================================== + +class TPG261(abstract_instrument): + def __init__(self, adress=ADRESS, vtype=[ALL_VAL_TYPE[0]], channels = [ALL_CHANNELS[0]]): + self.adress = adress + self.vtype = vtype + + def model(self): + return "PfeifferTPG261" + + def connect(self): + try: + print('Connecting to device @%s...' %(self.adress)) + self.TPG = MaxiGauge(self.adress) + print(' --> Ok') + + print(self.model()) + + if self.vtype == "PRE": + 1 + else: + print("Wrong -v argument") + raise + + except Exception as er: + print("Unexpected error during connection: " + str(er)) + raise + + def getValue(self): + self.read() + return "%s\n"%self.ps[0].pressure + + def read(self): + self.ps = self.TPG.pressures() + + def disconnect(self): + self.TPG.disconnect() + + def send(self, command): + pass + + + + +# from Philipp Klaus, philipp.l.klaus AT web.de PfeifferVacuum.py + +class MaxiGauge (object): + def __init__(self, serialPort, baud=9600, debug=False): + self.debug=debug + try: + self.connection = serial.Serial(serialPort, baudrate=baud, timeout=0.2) + except serial.serialutil.SerialException as se: + raise MaxiGaugeError(se) + #self.send(C['ETX']) ### We might reset the connection first, but it doesn't really matter: + + def checkDevice(self): + message = "The Display Contrast is currently set to %d (out of 20).\n" % self.displayContrast() + message += "Keys since MaxiGauge was switched on: %s (out of 1,2,3,4,5).\n" % ", ".join( map (str, self.pressedKeys()) ) + return message + + def pressedKeys(self): + keys = int(self.send('TKB',1)[0]) + pressedKeys = [] + for i in [4,3,2,1,0]: # It's got 5 keys + if keys/2**i == 1: + pressedKeys.append(i+1) + keys = keys%2**i + pressedKeys.reverse() + return pressedKeys + + def displayContrast(self,newContrast=-1): + if newContrast == -1: return int(self.send('DCC',1)[0]) + else: return int(self.send('DCC,%d' % (newContrast,) ,1)[0]) + + def pressures(self): + return [self.pressure(i+1) for i in range(1)] + + def pressure(self, sensor): + if sensor < 1 or sensor >6: raise MaxiGaugeError('Sensor can only be between 1 and 6. You choose ' + str(sensor)) + reading = self.send('PR%d' % sensor, 1) ## reading will have the form x,x.xxxEsx (see p.88) + try: + r = reading[0].split(',') + status = int(r[0]) + pressure = float(r[-1]) + except: + raise MaxiGaugeError("Problem interpreting the returned line:\n%s" % reading) + return PressureReading(sensor, status, pressure) + + def debugMessage(self, message): + if self.debug: print(repr(message)) + + def send(self, mnemonic, numEnquiries = 0): + self.connection.flushInput() + self.write(mnemonic+LINE_TERMINATION) + #if mnemonic != C['ETX']: self.read() + #self.read() + self.getACQorNAK() + response = [] + for i in range(numEnquiries): + self.enquire() + response.append(self.read()) + return response + + def write(self,what): + self.debugMessage(what) + self.connection.write(what) + + def enquire(self): + self.write(C['ENQ']) + + def read(self): + data = "" + while True: + x = self.connection.read() + self.debugMessage(x) + data += x + if len(data)>1 and data[-2:]==LINE_TERMINATION: + break + return data[:-len(LINE_TERMINATION)] + + def getACQorNAK(self): + returncode = self.connection.readline() + self.debugMessage(returncode) + ## The following is usually expected but our MaxiGauge controller sometimes forgets this parameter... That seems to be a bug with the DCC command. + #if len(returncode)<3: raise MaxiGaugeError('Only received a line termination from MaxiGauge. Was expecting ACQ or NAK.') + if len(returncode)<3: self.debugMessage('Only received a line termination from MaxiGauge. Was expecting ACQ or NAK.') + if len(returncode)>2 and returncode[-3] == C['NAK']: + self.enquire() + returnedError = self.read() + error = str(returnedError).split(',' , 1) + print repr(error) + errmsg = { 'System Error': ERR_CODES[0][int(error[0])] , 'Gauge Error': ERR_CODES[1][int(error[1])] } + raise MaxiGaugeNAK(errmsg) + #if len(returncode)>2 and returncode[-3] != C['ACQ']: raise MaxiGaugeError('Expecting ACQ or NAK from MaxiGauge but neither were sent.') + if len(returncode)>2 and returncode[-3] != C['ACQ']: self.debugMessage('Expecting ACQ or NAK from MaxiGauge but neither were sent.') + # if no exception raised so far, the interface is just fine: + return returncode[:-(len(LINE_TERMINATION)+1)] + + def disconnect(self): + #self.send(C['ETX']) + if hasattr(self, 'connection') and self.connection: self.connection.close() + + def __del__(self): + self.disconnect() + +class PressureReading(object): + def __init__(self, id, status, pressure): + if int(id) not in range(1,7): raise MaxiGaugeError('Pressure Gauge ID must be between 1-6') + self.id = int(id) + if int(status) not in PRESSURE_READING_STATUS.keys(): raise MaxiGaugeError('The Pressure Status must be in the range %s' % PRESSURE_READING_STATUS.keys()) + self.status = int(status) + self.pressure = float(pressure) + + def statusMsg(self): + return PRESSURE_READING_STATUS[self.status] + + def __repr__(self): + return "Gauge #%d: Status %d (%s), Pressure: %f mbar\n" % (self.id, self.status, self.statusMsg(), self.pressure) + + +### ------ now we define the exceptions that could occur ------ + +class MaxiGaugeError(Exception): + pass + +class MaxiGaugeNAK(MaxiGaugeError): + pass + +### ------- Control Symbols as defined on p. 81 of the english +### manual for the Pfeiffer Vacuum TPG256A ----------- +C = { + 'ETX': "\x03", # End of Text (Ctrl-C) Reset the interface + 'CR': "\x0D", # Carriage Return Go to the beginning of line + 'LF': "\x0A", # Line Feed Advance by one line + 'ENQ': "\x05", # Enquiry Request for data transmission + 'ACQ': "\x06", # Acknowledge Positive report signal + 'NAK': "\x15", # Negative Acknowledge Negative report signal + 'ESC': "\x1b", # Escape +} + +LINE_TERMINATION=C['CR']+C['LF'] # CR, LF and CRLF are all possible (p.82) + +### Mnemonics as defined on p. 85 +M = [ + 'BAU', # Baud rate Baud rate 95 + 'CAx', # Calibration factor Sensor x Calibration factor sensor x (1 ... 6) 92 + 'CID', # Measurement point names Measurement point names 88 + 'DCB', # Display control Bargraph Bargraph 89 + 'DCC', # Display control Contrast Display control contrast 90 + 'DCD', # Display control Digits Display digits 88 + 'DCS', # Display control Screensave Display control screensave 90 + 'DGS', # Degas Degas 93 + 'ERR', # Error Status Error status 97 + 'FIL', # Filter time constant Filter time constant 92 + 'FSR', # Full scale range of linear sensors Full scale range of linear sensors 93 + 'LOC', # Parameter setup lock Parameter setup lock 91 + 'NAD', # Node (device) address for RS485 Node (device) address for RS485 96 + 'OFC', # Offset correction Offset correction 93 + 'OFC', # Offset correction Offset correction 93 + 'PNR', # Program number Program number 98 + 'PRx', # Status, Pressure sensor x (1 ... 6) Status, Pressure sensor x (1 ... 6) 88 + 'PUC', # Underrange Ctrl Underrange control 91 + 'RSX', # Interface Interface 94 + 'SAV', # Save default Save default 94 + 'SCx', # Sensor control Sensor control 87 + 'SEN', # Sensor on/off Sensor on/off 86 + 'SPx', # Set Point Control Source for Relay xThreshold value setting, Allocation 90 + 'SPS', # Set Point Status A,B,C,D,E,F Set point status 91 + 'TAI', # Test program A/D Identify Test A/D converter identification inputs 100 + 'TAS', # Test program A/D Sensor Test A/D converter measurement value inputs 100 + 'TDI', # Display test Display test 98 + 'TEE', # EEPROM test EEPROM test 100 + 'TEP', # EPROM test EPROM test 99 + 'TID', # Sensor identification Sensor identification 101 + 'TKB', # Keyboard test Keyboard test 99 + 'TRA', # RAM test RAM test 99 + 'UNI', # Unit of measurement (Display) Unit of measurement (pressure) 89 + 'WDT', # Watchdog and System Error Control Watchdog and system error control 101 +] + + +### Error codes as defined on p. 97 +ERR_CODES = [ + { + 0: 'No error', + 1: 'Watchdog has responded', + 2: 'Task fail error', + 4: 'IDCX idle error', + 8: 'Stack overflow error', + 16: 'EPROM error', + 32: 'RAM error', + 64: 'EEPROM error', + 128: 'Key error', + 4096: 'Syntax error', + 8192: 'Inadmissible parameter', + 16384: 'No hardware', + 32768: 'Fatal error' + } , + { + 0: 'No error', + 1: 'Sensor 1: Measurement error', + 2: 'Sensor 2: Measurement error', + 4: 'Sensor 3: Measurement error', + 8: 'Sensor 4: Measurement error', + 16: 'Sensor 5: Measurement error', + 32: 'Sensor 6: Measurement error', + 512: 'Sensor 1: Identification error', + 1024: 'Sensor 2: Identification error', + 2048: 'Sensor 3: Identification error', + 4096: 'Sensor 4: Identification error', + 8192: 'Sensor 5: Identification error', + 16384: 'Sensor 6: Identification error', + } +] + +### pressure status as defined on p.88 +PRESSURE_READING_STATUS = { + 0: 'Measurement data okay', + 1: 'Underrange', + 2: 'Overrange', + 3: 'Sensor error', + 4: 'Sensor off', + 5: 'No sensor', + 6: 'Identification error' +} diff --git a/instruments/__init__.py b/instruments/__init__.py new file mode 100644 index 0000000..fbbc134 --- /dev/null +++ b/instruments/__init__.py @@ -0,0 +1,9 @@ +from os import listdir +from os.path import dirname + +for module in listdir(dirname(__file__)): + if module == '__init__.py' or module == 'abstract_instrument.py' or module[-3:] != '.py': + continue + __import__(module[:-3], locals(), globals()) + +del module, listdir, dirname \ No newline at end of file diff --git a/instruments/abstract_instrument.py b/instruments/abstract_instrument.py new file mode 100644 index 0000000..25f819b --- /dev/null +++ b/instruments/abstract_instrument.py @@ -0,0 +1,44 @@ +import abc + +class abstract_instrument(object): + __metaclass__ = abc.ABCMeta + + @abc.abstractmethod + def __init__(self, adress, vtype, channel): + """Build the class""" + return + + @abc.abstractmethod + def model(self): + """return the instrument model""" + return + + @abc.abstractmethod + def connect(self): + """Create a connection with the instrument""" + return + + @abc.abstractmethod + def disconnect(self): + """Disconnect the instrument""" + return + + @abc.abstractmethod + def configure(self): + """Configure the instrument""" + return + + @abc.abstractmethod + def read(self): + """read the buffer""" + return + + @abc.abstractmethod + def send(self): + """send a command""" + return + + @abc.abstractmethod + def getValue(self): + """return the value of measurment""" + return diff --git a/instruments/testDevice.py b/instruments/testDevice.py new file mode 100644 index 0000000..74a3dca --- /dev/null +++ b/instruments/testDevice.py @@ -0,0 +1,45 @@ +from abstract_instrument import abstract_instrument +import numpy, time + +#============================================================================== + +ALL_VAL_TYPE = ['vtype', 'DCV', 'ACV', 'DCI', 'ACI', 'RES2W', 'RES4W', 'FREQ'] +ALL_CHANNELS = ['0', '1'] +ADRESS = "123.456.789.123" + +#============================================================================== + +class testDevice(abstract_instrument): + def __init__(self, channels, vtype, adress = ADRESS): + self.adress = adress + self.port = 9999 + self.channels = channels + print(self.channels) + self.vtype = vtype + print(self.vtype) + + def model(self): + return 'test_device' + + def connect(self): + print('Connecting to device @%s:%s...' %(self.adress, self.port)) + time.sleep(1) + print(' --> Ok') + + print(self.model()) + + def getValue(self): + mes = "" + for ch in self.channels: + mes = mes + str(numpy.random.rand()) + '\t' + return mes + '\n' + + def read(self): + print('reading') + return 1 + + def disconnect(self): + print('disconnect') + + def send(self, command): + print('send %s'%command)