Commit bb6b0804113cd8ab7939323f5ca3246b3c13f9f6
1 parent
ff6ac07476
Exists in
master
Add configure method
Showing 1 changed file with 11 additions and 18 deletions Inline Diff
instruments/TPG261.py
from abstract_instrument import abstract_instrument | 1 | 1 | from abstract_instrument import abstract_instrument | |
import serial | 2 | 2 | import serial | |
3 | 3 | |||
#============================================================================== | 4 | 4 | #============================================================================== | |
5 | 5 | |||
ALL_VAL_TYPE = ['PRE'] | 6 | 6 | ALL_VAL_TYPE = ['PRE'] | |
ALL_CHANNELS = ['1'] | 7 | 7 | ALL_CHANNELS = ['1'] | |
ADRESS = "/dev/ttyS0" | 8 | 8 | ADRESS = "/dev/ttyS0" | |
9 | 9 | |||
#============================================================================== | 10 | 10 | #============================================================================== | |
11 | 11 | |||
class TPG261(abstract_instrument): | 12 | 12 | class TPG261(abstract_instrument): | |
def __init__(self, adress=ADRESS, vtype=[ALL_VAL_TYPE[0]], channels = [ALL_CHANNELS[0]]): | 13 | 13 | def __init__(self, channels, vtypes, adress): | |
self.adress = adress | 14 | 14 | self.adress = adress | |
self.vtype = vtype | 15 | 15 | self.channels = channels | |
16 | self.vtypes = vtypes | |||
16 | 17 | |||
def model(self): | 17 | 18 | def model(self): | |
return "PfeifferTPG261" | 18 | 19 | return "PfeifferTPG261" | |
19 | 20 | |||
def connect(self): | 20 | 21 | def connect(self): | |
try: | 21 | 22 | print('Connecting to device @%s...' %(self.adress)) | |
print('Connecting to device @%s...' %(self.adress)) | 22 | 23 | self.TPG = MaxiGauge(self.adress) | |
self.TPG = MaxiGauge(self.adress) | 23 | 24 | print(' --> Ok') | |
print(' --> Ok') | 24 | 25 | print(self.model()) | |
26 | self.configure() | |||
25 | 27 | |||
print(self.model()) | 26 | 28 | def configure(self): | |
27 | 29 | pass | ||
if self.vtype == "PRE": | 28 | |||
1 | 29 | |||
else: | 30 | |||
print("Wrong -v argument") | 31 | |||
raise | 32 | |||
33 | ||||
except Exception as er: | 34 | |||
print("Unexpected error during connection: " + str(er)) | 35 | |||
raise | 36 | |||
37 | 30 | |||
def getValue(self): | 38 | 31 | def getValue(self): | |
self.read() | 39 | 32 | self.read() | |
return "%s\n"%self.ps[0].pressure | 40 | 33 | return "%s\n"%self.ps[0].pressure | |
41 | 34 | |||
def read(self): | 42 | 35 | def read(self): | |
self.ps = self.TPG.pressures() | 43 | 36 | self.ps = self.TPG.pressures() | |
44 | 37 | |||
def disconnect(self): | 45 | 38 | def disconnect(self): | |
self.TPG.disconnect() | 46 | 39 | self.TPG.disconnect() | |
47 | 40 | |||
def send(self, command): | 48 | 41 | def send(self, command): | |
pass | 49 | 42 | pass | |
50 | 43 | |||
51 | 44 | |||
52 | 45 | |||
53 | 46 | |||
# from Philipp Klaus, philipp.l.klaus AT web.de PfeifferVacuum.py | 54 | 47 | # from Philipp Klaus, philipp.l.klaus AT web.de PfeifferVacuum.py | |
55 | 48 | |||
class MaxiGauge (object): | 56 | 49 | class MaxiGauge (object): | |
def __init__(self, serialPort, baud=9600, debug=False): | 57 | 50 | def __init__(self, serialPort, baud=9600, debug=False): | |
self.debug=debug | 58 | 51 | self.debug=debug | |
try: | 59 | 52 | try: | |
self.connection = serial.Serial(serialPort, baudrate=baud, timeout=0.2) | 60 | 53 | self.connection = serial.Serial(serialPort, baudrate=baud, timeout=0.2) | |
except serial.serialutil.SerialException as se: | 61 | 54 | except serial.serialutil.SerialException as se: | |
raise MaxiGaugeError(se) | 62 | 55 | raise MaxiGaugeError(se) | |
#self.send(C['ETX']) ### We might reset the connection first, but it doesn't really matter: | 63 | 56 | #self.send(C['ETX']) ### We might reset the connection first, but it doesn't really matter: | |
64 | 57 | |||
def checkDevice(self): | 65 | 58 | def checkDevice(self): | |
message = "The Display Contrast is currently set to %d (out of 20).\n" % self.displayContrast() | 66 | 59 | 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()) ) | 67 | 60 | message += "Keys since MaxiGauge was switched on: %s (out of 1,2,3,4,5).\n" % ", ".join( map (str, self.pressedKeys()) ) | |
return message | 68 | 61 | return message | |
69 | 62 | |||
def pressedKeys(self): | 70 | 63 | def pressedKeys(self): | |
keys = int(self.send('TKB',1)[0]) | 71 | 64 | keys = int(self.send('TKB',1)[0]) | |
pressedKeys = [] | 72 | 65 | pressedKeys = [] | |
for i in [4,3,2,1,0]: # It's got 5 keys | 73 | 66 | for i in [4,3,2,1,0]: # It's got 5 keys | |
if keys/2**i == 1: | 74 | 67 | if keys/2**i == 1: | |
pressedKeys.append(i+1) | 75 | 68 | pressedKeys.append(i+1) | |
keys = keys%2**i | 76 | 69 | keys = keys%2**i | |
pressedKeys.reverse() | 77 | 70 | pressedKeys.reverse() | |
return pressedKeys | 78 | 71 | return pressedKeys | |
79 | 72 | |||
def displayContrast(self,newContrast=-1): | 80 | 73 | def displayContrast(self,newContrast=-1): | |
if newContrast == -1: return int(self.send('DCC',1)[0]) | 81 | 74 | if newContrast == -1: return int(self.send('DCC',1)[0]) | |
else: return int(self.send('DCC,%d' % (newContrast,) ,1)[0]) | 82 | 75 | else: return int(self.send('DCC,%d' % (newContrast,) ,1)[0]) | |
83 | 76 | |||
def pressures(self): | 84 | 77 | def pressures(self): | |
return [self.pressure(i+1) for i in range(1)] | 85 | 78 | return [self.pressure(i+1) for i in range(1)] | |
86 | 79 | |||
def pressure(self, sensor): | 87 | 80 | def pressure(self, sensor): | |
if sensor < 1 or sensor >6: raise MaxiGaugeError('Sensor can only be between 1 and 6. You choose ' + str(sensor)) | 88 | 81 | 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 <CR><LF> (see p.88) | 89 | 82 | reading = self.send('PR%d' % sensor, 1) ## reading will have the form x,x.xxxEsx <CR><LF> (see p.88) | |
try: | 90 | 83 | try: | |
r = reading[0].split(',') | 91 | 84 | r = reading[0].split(',') | |
status = int(r[0]) | 92 | 85 | status = int(r[0]) | |
pressure = float(r[-1]) | 93 | 86 | pressure = float(r[-1]) | |
except: | 94 | 87 | except: | |
raise MaxiGaugeError("Problem interpreting the returned line:\n%s" % reading) | 95 | 88 | raise MaxiGaugeError("Problem interpreting the returned line:\n%s" % reading) | |
return PressureReading(sensor, status, pressure) | 96 | 89 | return PressureReading(sensor, status, pressure) | |
97 | 90 | |||
def debugMessage(self, message): | 98 | 91 | def debugMessage(self, message): | |
if self.debug: print(repr(message)) | 99 | 92 | if self.debug: print(repr(message)) | |
100 | 93 | |||
def send(self, mnemonic, numEnquiries = 0): | 101 | 94 | def send(self, mnemonic, numEnquiries = 0): | |
self.connection.flushInput() | 102 | 95 | self.connection.flushInput() | |
self.write(mnemonic+LINE_TERMINATION) | 103 | 96 | self.write(mnemonic+LINE_TERMINATION) | |
#if mnemonic != C['ETX']: self.read() | 104 | 97 | #if mnemonic != C['ETX']: self.read() | |
#self.read() | 105 | 98 | #self.read() | |
self.getACQorNAK() | 106 | 99 | self.getACQorNAK() | |
response = [] | 107 | 100 | response = [] | |
for i in range(numEnquiries): | 108 | 101 | for i in range(numEnquiries): | |
self.enquire() | 109 | 102 | self.enquire() | |
response.append(self.read()) | 110 | 103 | response.append(self.read()) | |
return response | 111 | 104 | return response | |
112 | 105 | |||
def write(self,what): | 113 | 106 | def write(self,what): | |
self.debugMessage(what) | 114 | 107 | self.debugMessage(what) | |
self.connection.write(what) | 115 | 108 | self.connection.write(what) | |
116 | 109 | |||
def enquire(self): | 117 | 110 | def enquire(self): | |
self.write(C['ENQ']) | 118 | 111 | self.write(C['ENQ']) | |
119 | 112 | |||
def read(self): | 120 | 113 | def read(self): | |
data = "" | 121 | 114 | data = "" | |
while True: | 122 | 115 | while True: | |
x = self.connection.read() | 123 | 116 | x = self.connection.read() | |
self.debugMessage(x) | 124 | 117 | self.debugMessage(x) | |
data += x | 125 | 118 | data += x | |
if len(data)>1 and data[-2:]==LINE_TERMINATION: | 126 | 119 | if len(data)>1 and data[-2:]==LINE_TERMINATION: | |
break | 127 | 120 | break | |
return data[:-len(LINE_TERMINATION)] | 128 | 121 | return data[:-len(LINE_TERMINATION)] | |
129 | 122 | |||
def getACQorNAK(self): | 130 | 123 | def getACQorNAK(self): | |
returncode = self.connection.readline() | 131 | 124 | returncode = self.connection.readline() | |
self.debugMessage(returncode) | 132 | 125 | 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. | 133 | 126 | ## 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.') | 134 | 127 | #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.') | 135 | 128 | 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']: | 136 | 129 | if len(returncode)>2 and returncode[-3] == C['NAK']: | |
self.enquire() | 137 | 130 | self.enquire() | |
returnedError = self.read() | 138 | 131 | returnedError = self.read() | |
error = str(returnedError).split(',' , 1) | 139 | 132 | error = str(returnedError).split(',' , 1) | |
print repr(error) | 140 | 133 | print repr(error) | |
errmsg = { 'System Error': ERR_CODES[0][int(error[0])] , 'Gauge Error': ERR_CODES[1][int(error[1])] } | 141 | 134 | errmsg = { 'System Error': ERR_CODES[0][int(error[0])] , 'Gauge Error': ERR_CODES[1][int(error[1])] } | |
raise MaxiGaugeNAK(errmsg) | 142 | 135 | raise MaxiGaugeNAK(errmsg) | |
#if len(returncode)>2 and returncode[-3] != C['ACQ']: raise MaxiGaugeError('Expecting ACQ or NAK from MaxiGauge but neither were sent.') | 143 | 136 | #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.') | 144 | 137 | 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: | 145 | 138 | # if no exception raised so far, the interface is just fine: | |
return returncode[:-(len(LINE_TERMINATION)+1)] | 146 | 139 | return returncode[:-(len(LINE_TERMINATION)+1)] | |
147 | 140 | |||
def disconnect(self): | 148 | 141 | def disconnect(self): | |
#self.send(C['ETX']) | 149 | 142 | #self.send(C['ETX']) | |
if hasattr(self, 'connection') and self.connection: self.connection.close() | 150 | 143 | if hasattr(self, 'connection') and self.connection: self.connection.close() | |
151 | 144 | |||
def __del__(self): | 152 | 145 | def __del__(self): | |
self.disconnect() | 153 | 146 | self.disconnect() | |
154 | 147 | |||
class PressureReading(object): | 155 | 148 | class PressureReading(object): | |
def __init__(self, id, status, pressure): | 156 | 149 | def __init__(self, id, status, pressure): | |
if int(id) not in range(1,7): raise MaxiGaugeError('Pressure Gauge ID must be between 1-6') | 157 | 150 | if int(id) not in range(1,7): raise MaxiGaugeError('Pressure Gauge ID must be between 1-6') | |
self.id = int(id) | 158 | 151 | 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()) | 159 | 152 | 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) | 160 | 153 | self.status = int(status) | |
self.pressure = float(pressure) | 161 | 154 | self.pressure = float(pressure) | |
162 | 155 | |||
def statusMsg(self): | 163 | 156 | def statusMsg(self): | |
return PRESSURE_READING_STATUS[self.status] | 164 | 157 | return PRESSURE_READING_STATUS[self.status] | |
165 | 158 | |||
def __repr__(self): | 166 | 159 | def __repr__(self): | |
return "Gauge #%d: Status %d (%s), Pressure: %f mbar\n" % (self.id, self.status, self.statusMsg(), self.pressure) | 167 | 160 | return "Gauge #%d: Status %d (%s), Pressure: %f mbar\n" % (self.id, self.status, self.statusMsg(), self.pressure) | |
168 | 161 | |||
169 | 162 | |||
### ------ now we define the exceptions that could occur ------ | 170 | 163 | ### ------ now we define the exceptions that could occur ------ | |
171 | 164 | |||
class MaxiGaugeError(Exception): | 172 | 165 | class MaxiGaugeError(Exception): | |
pass | 173 | 166 | pass | |
174 | 167 | |||
class MaxiGaugeNAK(MaxiGaugeError): | 175 | 168 | class MaxiGaugeNAK(MaxiGaugeError): | |
pass | 176 | 169 | pass | |
177 | 170 | |||
### ------- Control Symbols as defined on p. 81 of the english | 178 | 171 | ### ------- Control Symbols as defined on p. 81 of the english | |
### manual for the Pfeiffer Vacuum TPG256A ----------- | 179 | 172 | ### manual for the Pfeiffer Vacuum TPG256A ----------- | |
C = { | 180 | 173 | C = { | |
'ETX': "\x03", # End of Text (Ctrl-C) Reset the interface | 181 | 174 | 'ETX': "\x03", # End of Text (Ctrl-C) Reset the interface | |
'CR': "\x0D", # Carriage Return Go to the beginning of line | 182 | 175 | 'CR': "\x0D", # Carriage Return Go to the beginning of line | |
'LF': "\x0A", # Line Feed Advance by one line | 183 | 176 | 'LF': "\x0A", # Line Feed Advance by one line | |
'ENQ': "\x05", # Enquiry Request for data transmission | 184 | 177 | 'ENQ': "\x05", # Enquiry Request for data transmission | |
'ACQ': "\x06", # Acknowledge Positive report signal | 185 | 178 | 'ACQ': "\x06", # Acknowledge Positive report signal | |
'NAK': "\x15", # Negative Acknowledge Negative report signal | 186 | 179 | 'NAK': "\x15", # Negative Acknowledge Negative report signal | |
'ESC': "\x1b", # Escape | 187 | 180 | 'ESC': "\x1b", # Escape | |
} | 188 | 181 | } | |
189 | 182 | |||
LINE_TERMINATION=C['CR']+C['LF'] # CR, LF and CRLF are all possible (p.82) | 190 | 183 | LINE_TERMINATION=C['CR']+C['LF'] # CR, LF and CRLF are all possible (p.82) | |
191 | 184 | |||
### Mnemonics as defined on p. 85 | 192 | 185 | ### Mnemonics as defined on p. 85 | |
M = [ | 193 | 186 | M = [ | |
'BAU', # Baud rate Baud rate 95 | 194 | 187 | 'BAU', # Baud rate Baud rate 95 | |
'CAx', # Calibration factor Sensor x Calibration factor sensor x (1 ... 6) 92 | 195 | 188 | 'CAx', # Calibration factor Sensor x Calibration factor sensor x (1 ... 6) 92 | |
'CID', # Measurement point names Measurement point names 88 | 196 | 189 | 'CID', # Measurement point names Measurement point names 88 | |
'DCB', # Display control Bargraph Bargraph 89 | 197 | 190 | 'DCB', # Display control Bargraph Bargraph 89 | |
'DCC', # Display control Contrast Display control contrast 90 | 198 | 191 | 'DCC', # Display control Contrast Display control contrast 90 | |
'DCD', # Display control Digits Display digits 88 | 199 | 192 | 'DCD', # Display control Digits Display digits 88 | |
'DCS', # Display control Screensave Display control screensave 90 | 200 | 193 | 'DCS', # Display control Screensave Display control screensave 90 | |
'DGS', # Degas Degas 93 | 201 | 194 | 'DGS', # Degas Degas 93 | |
'ERR', # Error Status Error status 97 | 202 | 195 | 'ERR', # Error Status Error status 97 | |
'FIL', # Filter time constant Filter time constant 92 | 203 | 196 | 'FIL', # Filter time constant Filter time constant 92 | |
'FSR', # Full scale range of linear sensors Full scale range of linear sensors 93 | 204 | 197 | 'FSR', # Full scale range of linear sensors Full scale range of linear sensors 93 | |
'LOC', # Parameter setup lock Parameter setup lock 91 | 205 | 198 | 'LOC', # Parameter setup lock Parameter setup lock 91 | |
'NAD', # Node (device) address for RS485 Node (device) address for RS485 96 | 206 | 199 | 'NAD', # Node (device) address for RS485 Node (device) address for RS485 96 | |
'OFC', # Offset correction Offset correction 93 | 207 | 200 | 'OFC', # Offset correction Offset correction 93 | |
'OFC', # Offset correction Offset correction 93 | 208 | 201 | 'OFC', # Offset correction Offset correction 93 | |
'PNR', # Program number Program number 98 | 209 | 202 | 'PNR', # Program number Program number 98 | |
'PRx', # Status, Pressure sensor x (1 ... 6) Status, Pressure sensor x (1 ... 6) 88 | 210 | 203 | 'PRx', # Status, Pressure sensor x (1 ... 6) Status, Pressure sensor x (1 ... 6) 88 | |
'PUC', # Underrange Ctrl Underrange control 91 | 211 | 204 | 'PUC', # Underrange Ctrl Underrange control 91 | |
'RSX', # Interface Interface 94 | 212 | 205 | 'RSX', # Interface Interface 94 | |
'SAV', # Save default Save default 94 | 213 | 206 | 'SAV', # Save default Save default 94 | |
'SCx', # Sensor control Sensor control 87 | 214 | 207 | 'SCx', # Sensor control Sensor control 87 | |
'SEN', # Sensor on/off Sensor on/off 86 | 215 | 208 | 'SEN', # Sensor on/off Sensor on/off 86 | |
'SPx', # Set Point Control Source for Relay xThreshold value setting, Allocation 90 | 216 | 209 | '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 | 217 | 210 | '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 | 218 | 211 | '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 | 219 | 212 | 'TAS', # Test program A/D Sensor Test A/D converter measurement value inputs 100 | |
'TDI', # Display test Display test 98 | 220 | 213 | 'TDI', # Display test Display test 98 | |
'TEE', # EEPROM test EEPROM test 100 | 221 | 214 | 'TEE', # EEPROM test EEPROM test 100 | |
'TEP', # EPROM test EPROM test 99 | 222 | 215 | 'TEP', # EPROM test EPROM test 99 | |
'TID', # Sensor identification Sensor identification 101 | 223 | 216 | 'TID', # Sensor identification Sensor identification 101 | |
'TKB', # Keyboard test Keyboard test 99 | 224 | 217 | 'TKB', # Keyboard test Keyboard test 99 | |
'TRA', # RAM test RAM test 99 | 225 | 218 | 'TRA', # RAM test RAM test 99 | |
'UNI', # Unit of measurement (Display) Unit of measurement (pressure) 89 | 226 | 219 | 'UNI', # Unit of measurement (Display) Unit of measurement (pressure) 89 | |
'WDT', # Watchdog and System Error Control Watchdog and system error control 101 | 227 | 220 | 'WDT', # Watchdog and System Error Control Watchdog and system error control 101 | |
] | 228 | 221 | ] | |
229 | 222 | |||
230 | 223 | |||
### Error codes as defined on p. 97 | 231 | 224 | ### Error codes as defined on p. 97 | |
ERR_CODES = [ | 232 | 225 | ERR_CODES = [ | |
{ | 233 | 226 | { | |
0: 'No error', | 234 | 227 | 0: 'No error', | |
1: 'Watchdog has responded', | 235 | 228 | 1: 'Watchdog has responded', | |
2: 'Task fail error', | 236 | 229 | 2: 'Task fail error', | |
4: 'IDCX idle error', | 237 | 230 | 4: 'IDCX idle error', | |
8: 'Stack overflow error', | 238 | 231 | 8: 'Stack overflow error', |