Commit 91efd0ebc5b41da7d6b45177f563eb5b40337d5e
Committed by
GitHub
1 parent
861f505391
Exists in
master
Add files via upload
Showing 9 changed files with 806 additions and 0 deletions Inline Diff
instruments/AG34461A.py
File was created | 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] |
instruments/AG34972A.py
File was created | 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): |
instruments/LS350.py
File was created | 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): |
instruments/PM100D.py
File was created | 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 |
instruments/T7Pro.py
File was created | 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] |
instruments/TPG261.py
File was created | 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 |
instruments/__init__.py
File was created | 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()) |
instruments/abstract_instrument.py
File was created | 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 |
instruments/testDevice.py
File was created | 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' |