Blame view
instruments/TPG261.py
9.16 KB
91efd0ebc Add files via upload |
1 2 3 4 5 6 7 |
from abstract_instrument import abstract_instrument import serial #============================================================================== ALL_VAL_TYPE = ['PRE'] ALL_CHANNELS = ['1'] |
9058343c5 some minor fixes |
8 |
ADDRESS = "/dev/ttyS0" |
91efd0ebc Add files via upload |
9 10 11 12 |
#============================================================================== class TPG261(abstract_instrument): |
348049517 replace 4 spaces ... |
13 14 15 16 |
def __init__(self, channels, vtypes, address): self.address = address self.channels = channels self.vtypes = vtypes |
91efd0ebc Add files via upload |
17 |
|
348049517 replace 4 spaces ... |
18 19 |
def model(self): return "PfeifferTPG261" |
91efd0ebc Add files via upload |
20 |
|
348049517 replace 4 spaces ... |
21 22 23 24 25 26 |
def connect(self): print('Connecting to device @%s...' %(self.address)) self.TPG = MaxiGauge(self.address) print(' --> Ok') print(self.model()) self.configure() |
bb6b08041 Add configure method |
27 |
|
348049517 replace 4 spaces ... |
28 29 |
def configure(self): pass |
91efd0ebc Add files via upload |
30 |
|
348049517 replace 4 spaces ... |
31 32 33 34 |
def getValue(self): self.read() return "%s "%self.ps[0].pressure |
91efd0ebc Add files via upload |
35 |
|
348049517 replace 4 spaces ... |
36 37 |
def read(self): self.ps = self.TPG.pressures() |
91efd0ebc Add files via upload |
38 |
|
348049517 replace 4 spaces ... |
39 40 |
def disconnect(self): self.TPG.disconnect() |
91efd0ebc Add files via upload |
41 |
|
348049517 replace 4 spaces ... |
42 43 |
def send(self, command): pass |
91efd0ebc Add files via upload |
44 45 46 47 48 49 50 |
# from Philipp Klaus, philipp.l.klaus AT web.de PfeifferVacuum.py class MaxiGauge (object): |
348049517 replace 4 spaces ... |
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
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). " % self.displayContrast() message += "Keys since MaxiGauge was switched on: %s (out of 1,2,3,4,5). " % ", ".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 <CR><LF> (see p.88) try: r = reading[0].split(',') status = int(r[0]) pressure = float(r[-1]) except: raise MaxiGaugeError("Problem interpreting the returned line: %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() |
91efd0ebc Add files via upload |
151 152 |
class PressureReading(object): |
348049517 replace 4 spaces ... |
153 154 155 156 157 158 |
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) |
91efd0ebc Add files via upload |
159 |
|
348049517 replace 4 spaces ... |
160 161 |
def statusMsg(self): return PRESSURE_READING_STATUS[self.status] |
91efd0ebc Add files via upload |
162 |
|
348049517 replace 4 spaces ... |
163 164 165 |
def __repr__(self): return "Gauge #%d: Status %d (%s), Pressure: %f mbar " % (self.id, self.status, self.statusMsg(), self.pressure) |
91efd0ebc Add files via upload |
166 167 168 169 170 |
### ------ now we define the exceptions that could occur ------ class MaxiGaugeError(Exception): |
348049517 replace 4 spaces ... |
171 |
pass |
91efd0ebc Add files via upload |
172 173 |
class MaxiGaugeNAK(MaxiGaugeError): |
348049517 replace 4 spaces ... |
174 |
pass |
91efd0ebc Add files via upload |
175 176 |
### ------- Control Symbols as defined on p. 81 of the english |
348049517 replace 4 spaces ... |
177 |
### manual for the Pfeiffer Vacuum TPG256A ----------- |
91efd0ebc Add files via upload |
178 179 |
C = { 'ETX': "\x03", # End of Text (Ctrl-C) Reset the interface |
348049517 replace 4 spaces ... |
180 181 182 183 |
'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 |
91efd0ebc Add files via upload |
184 185 186 187 188 189 190 191 |
'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 = [ |
348049517 replace 4 spaces ... |
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
'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 |
91efd0ebc Add files via upload |
226 227 228 229 230 231 |
] ### Error codes as defined on p. 97 ERR_CODES = [ { |
348049517 replace 4 spaces ... |
232 233 234 235 236 237 238 239 240 241 242 243 244 |
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' |
91efd0ebc Add files via upload |
245 246 |
} , { |
348049517 replace 4 spaces ... |
247 248 249 250 251 252 253 254 255 256 257 258 259 |
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', |
91efd0ebc Add files via upload |
260 261 262 263 264 265 266 267 268 269 270 271 272 |
} ] ### 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' } |