def performGetValue(self, quant, options={}): self.log('performGetValue called: ' + quant.name) if quant.name.startswith('Measure '): #Determine which variables are being measured quantDict = {'Measure Current':'CURR', \ 'Measure Voltage':'VOLT', \ 'Measure Resistance':'RES'} reply = VISA_Driver.askAndLog(self, 'FUNC?') if quantDict[quant.name] in reply: return True else: return False elif quant.name.endswith('variable'): #Have set up format so the read or fetch command always returns values in the following order quantDict = {'Voltage variable':0, \ 'Current variable':1, \ 'Resistance variable':2} #If this is first measurement call, perform read operation and return appropriate values if self.isFirstCall(options): reply = VISA_Driver.askAndLog(self, 'READ?') #otherwise perform fetch operation and return appropriate values else: reply = VISA_Driver.askAndLog(self, 'FETCH?') value = reply.split(',') return value[quantDict[quant.name]] else: return VISA_Driver.performGetValue(self, quant, options)
def checkIfSweeping(self, quant, options={}): #Can't create quant instances from here, can only pass name of quant #Whereas system if type(quant) == str: name = quant else: name = quant.name if name == 'Source Voltage Level' or name == 'Source Current Level': #If sweeping, can't go into program edit mode #Can't see any other way of checking if program is running VISA_Driver.writeAndLog(self,'*CLS') #Clear any existing errors VISA_Driver.writeAndLog(self,'PROG:EDIT:STAR') #force an error if program running err = VISA_Driver.askAndLog(self,'SYST:ERR?') #Check if there's a 'program running' error #Separate error code and error message #error code = 0 -> no errors errCode = int(err.split(',')[0]) if errCode == -284: #There is a 'program running' error, so program must be sweeping return True elif errCode == 103: #There is a 'program being edited error' for some reason. Stop editing self.log("Program didn't stop properly") VISA_Driver.writeAndLog(self,'PROG:EDIT:END') return False else: VISA_Driver.writeAndLog(self,'PROG:EDIT:END') return False else: #Not checking one of the quants that can sweep return False
def performGetValue(self, quant, options={}): if quant.name == 'Output': value = VISA_Driver.askAndLog(self,'OUTP:STAT?') #Value will be 0 (false/off) or 1 (true/on) return int(value) elif quant.name == 'Function': value = VISA_Driver.askAndLog(self,'SOUR:FUNC?') if value == 'VOLT': return 'Voltage' elif value == 'CURR': return 'Current' return value elif quant.name == 'Source Current Range' or quant.name == 'Source Voltage Range': return VISA_Driver.askAndLog(self,'SOUR:RANG?') elif quant.name == 'Source Voltage Level' or quant.name == 'Source Current Level': returnVal = VISA_Driver.askAndLog(self,'SOUR:LEV?') return float(returnVal) else: self.log('Get quantity not listed elsewhere: '+quant.name) return VISA_Driver.performGetValue(self,quant,options)
def performGetValue(self, quant, options={}): self.log("performGetValue called: " + quant.name) if quant.name.startswith("Measure "): # Determine which variables are being measured quantDict = {"Measure Current": "CURR", "Measure Voltage": "VOLT", "Measure Resistance": "RES"} reply = VISA_Driver.askAndLog(self, "FUNC?") if quantDict[quant.name] in reply: return True else: return False elif quant.name.endswith("variable"): # Have set up format so the read or fetch command always returns values in the following order quantDict = {"Voltage variable": 0, "Current variable": 1, "Resistance variable": 2} # If this is first measurement call, perform read operation and return appropriate values if self.isFirstCall(options): reply = VISA_Driver.askAndLog(self, "READ?") # otherwise perform fetch operation and return appropriate values else: reply = VISA_Driver.askAndLog(self, "FETCH?") value = reply.split(",") return value[quantDict[quant.name]] else: return VISA_Driver.performGetValue(self, quant, options)
def performGetValue(self, quant, options={}): couplingModes = [ 'Coupling CFRQAB', 'Coupling CFRQAC', 'Coupling RFLVAB', 'Coupling RFLVAC' ] self.log('Quant.name is: ' + quant.name + ' Get value') if quant.name[-1] == ')': #quant is source specific source = quant.name[-2] #Use sourceCmd before every source specific command sourceCmd = 'SOURCE ' + source + '; :' if quant.name == 'Combiner mode': reply = VISA_Driver.askAndLog(self, 'CMODE?') #return syntax is ':CMODE <*>' reply = reply.split(' ')[1] combos = ['A', 'B', 'C', 'AB', 'BC', 'AC', 'ABC', 'OFF'] for comboValue in combos: #Need set so we get AB == BA, etc if set(reply) == set(comboValue): return comboValue self.log('Coupling mode not found: ' + reply) elif quant.name == 'Impedance': reply = VISA_Driver.askAndLog(self, 'IMPEDANCE?') if reply.split(' ')[1] == 'Z50R': return '50 Ohms' else: return '75 Ohms' elif quant.name in couplingModes: mode = quant.name.split(' ')[1] reply = VISA_Driver.askAndLog(self, 'COUPLING?') #Reply syntax: COUPLING:MODE CFRQAB,RFLVAC,... #get rid of 'COUPLING:MODE' reply = reply.split(' ')[1] #puts 2nd part into list of enabled modes reply = reply.split(',') if mode in reply: return True else: return False elif quant.name.startswith('Coupling'): cmd = quant.name.split(' ') """ cmd[0] = 'coupling' cmd[1] = one of the coupling modes cmd[2] = MODE, HARM, SUBHARM, or OFFSET """ cmdStr = 'COUPLING: ' + cmd[1] + '?' reply = VISA_Driver.askAndLog(self, cmdStr) #Reply syntax: :COUPLING:CFRQAC:MODE SUBHARM;HARM 2;SUBHARM 6;OFFSET 2 replist = reply.split(';') if cmd[2] == 'MODE': #Split MODE and SUBHARM in reply[0], return SUBHARM return replist[0].split(' ')[1] elif cmd[2] == 'HARM': #split HARM and value in reply[1] return replist[1].split(' ')[1] elif cmd[2] == 'SUBHARM': #split SUBHARM and value in reply[2] return replist[2].split(' ')[1] elif cmd[2] == 'OFFSET': #Split offset and value in reply[3] return replist[3].split(' ')[1] else: self.log('Received invalid response: ' + reply) elif quant.name.startswith('Carrier Frequency'): reply = VISA_Driver.askAndLog(self, sourceCmd + 'CFRQ?') #reply syntax: :CFRQ:VALUE 1000000000.0;INC 25000.0 reply = reply.split(';')[0] reply = reply.split(' ')[1] self.log('Carrier frequency: ' + reply) return float(reply) elif quant.name.startswith('RF'): cmd = quant.name.split(' ') #cmd[1] = Output, Level, or Type #Reply syntax: :RFLV:UNITS DBM;TYPE PD;VALUE −103.5;INC 2.0;ON reply = VISA_Driver.askAndLog(self, sourceCmd + 'RFLV?') reply = reply.split(';') if cmd[1] == 'Output': if reply[3] == 'ON': return True else: return False elif cmd[1] == 'Level': return reply[2].split(' ')[1] elif cmd[1] == 'Type': return reply[1].split(' ')[1] else: self.log('Quant not recognised: ' + quant.name) elif quant.name.startswith('Modulation Control'): reply = VISA_Driver.askAndLog(self, sourceCmd + 'MOD?') if reply.split(':')[-1] == 'ON': return True else: return False elif quant.name.startswith('Modulation mode'): reply = VISA_Driver.askAndLog(self, sourceCmd + 'MODE?') #Reply syntax: :MODE AM,FM,PULSE #Remove ':MODE' component of reply reply = reply.split(' ')[1] #Separate activated modes into list reply = reply.split(',') if 'AM' in reply: if 'FM' in reply: return 'AM & FM' elif 'PM' in reply: return 'AM & PM' else: return 'AM' elif 'FM' in reply: return 'FM' elif 'PM' in reply: return 'PM' elif 'FSK2L' in reply: return 'FSK2L' elif 'FSK4L' in reply: return 'FSK4L' else: self.log('No modulation mode active') elif quant.name[:2] in ['FM', 'PM', 'AM']: cmd = quant.name.split(' ') """ cmd[0] = FM, FM1, FM2, PM, PM1, PM2, AM, AM1, or AM2 cmd[1] = Status, Deviation, Source, Modulation, Waveform, Phase, (Depth for AM) """ if cmd[1] == 'Status': reply = VISA_Driver.askAndLog(self, sourceCmd + cmd[0] + '?') #Reply syntax: :FM1:DEVN 1000.0;INT;OFF;INC 1000.0 reply = reply.split(';') if reply[2] == 'OFF': return False else: return True elif cmd[1] == 'Deviation': reply = VISA_Driver.askAndLog(self, sourceCmd + cmd[0] + '?') #Reply syntax: :FM1:DEVN 25000.0;INT;ON;INC 1000.0 reply = reply.split(';') return reply[0].split(' ')[1] elif cmd[1] == 'Source': reply = VISA_Driver.askAndLog(self, sourceCmd + cmd[0] + '?') #Reply syntax: :FM1:DEVN 25000.0;INT;ON;INC 1000.0 reply = reply.split(';') comboDict = { 'INT': 'Internal', 'EXTAC': 'External AC', 'EXTALC': 'External ALC', 'EXTDC': 'External DC' } return comboDict[reply[1]] elif cmd[1] == 'Modulation': reply = VISA_Driver.askAndLog(self, sourceCmd + cmd[0] + ':MODF?') #Reply syntax: :FM1:MODF:VALUE 5750.00;SIN;INC 1000.00 reply = reply.split(';')[0] return reply.split(' ')[1] elif cmd[1] == 'Waveform': reply = VISA_Driver.askAndLog(self, sourceCmd + cmd[0] + ':MODF?') #Reply syntax: :FM1:MODF:VALUE 5750.00;SIN;INC 1000.00 return reply.split(';')[1] elif cmd[1] == 'Phase': return 0 #No way to get this setting elif cmd[1] == 'Depth': reply = VISA_Driver.askAndLog(self, sourceCmd + cmd[0] + '?') #Reply syntax: :FM1:DEVN 25000.0;INT;ON;INC 1000.0 reply = reply.split(';') return reply[0].split(' ')[1] else: self.log('Quant command not recognised: ' + quant.name) elif quant.name.startswith('Pulse Modulation'): reply = VISA_Driver.askAndLog(self, sourceCmd + 'PULSE?') #Reply syntax: :PULSE:ON/OFF #Remove ':MODE' component of reply if reply.endswith('ON'): return True else: return False else: self.log('quant.name not tringgered: ' + quant.name) return VISA_Driver.performGetValue(self, quant, options)
def performSetValue(self, quant, value, sweepRate=0.0, options={}): self.log('performSetValue called: ' + quant.name + ' value: ' + str(value)) if quant.name == 'Source on_off': if value == 'On': VISA_Driver.writeAndLog(self, 'OUTP:STAT 1') return 'On' else: #Sweep source to zero before turning off, to avoid sudden jumps func = self.getValue('Source function') if func == 'Voltage': self.sendValueToOther('Voltage Amplitude', 0) while self.sendValueToOther('Voltage Amplitude', 0) != 0: self.wait(0.1) elif func == 'Current': self.sendValueToOther('Current Amplitude', 0) while self.sendValueToOther('Voltage Amplitude', 0) != 0: self.wait(0.1) VISA_Driver.writeAndLog(self, 'OUTP:STAT 0') return 'Off' elif quant.name.endswith('Amplitude'): #Voltage Amplitude #Current Amplitude if quant.name.startswith('Voltage'): cmd = 'SOUR:VOLT' maxOutpDiff = 0.0005 #5mV/s #Program sets source every 0.1 seconds, so sweepRate = outpDiff/0.1 = 10*outpDiff #Note minimum output change is 5uV. else: cmd = 'SOUR:CURR' maxOutpDiff = 0.0001 initValue = float(VISA_Driver.askAndLog(self, cmd + '?')) outpDiff = value - initValue if outpDiff == 0: #Don't send if already at right value return value elif outpDiff > maxOutpDiff: #If program is trying to move to a value too far away instantly, # then override by changing value value = initValue + maxOutpDiff elif outpDiff < -maxOutpDiff: value = initValue - maxOutpDiff #Enter the (modified or unmodified) value VISA_Driver.writeAndLog(self, cmd + ' ' + str(value)) return value elif quant.name.startswith('Measure '): #Determine which variables are being measured quantDict = {'Measure Current':['CURR',False], \ 'Measure Voltage':['VOLT',False], \ 'Measure Resistance':['RES',False]} for key, list in quantDict.items(): list[1] = self.getValue(key) #If only one, turn off concurrency if sum(list[1] for list in quantDict.values()) == 1: VISA_Driver.writeAndLog(self, 'FUNC:CONC 0') else: VISA_Driver.writeAndLog(self, 'FUNC:CONC 1') #Enable appropriate functions for key, list in quantDict.items(): if list[1]: VISA_Driver.writeAndLog(self, 'FUNC:ON ' + '"' + list[0] + '"') else: VISA_Driver.writeAndLog(self, 'FUNC:OFF ' + '"' + list[0] + '"') return value elif quant.name.endswith('Range Mode'): #convert auto/manual to auto on, auto off comboDict = {'Manual': '0', 'Automatic': '1'} value = comboDict[value] #Check source mode func = self.getValue('Source function') if quant.name.startswith('Voltage'): if func == 'Voltage': #If quant matches source mode, set source range VISA_Driver.writeAndLog(self, 'SOUR:VOLT:RANG:AUTO ' + value) else: #Otherwise, set measurement range VISA_Driver.writeAndLog(self, 'SENS:VOLT:RANG:AUTO ' + value) elif quant.name.startswith('Current'): if func == 'Current': VISA_Driver.writeAndLog(self, 'SOUR:CURR:RANG:AUTO ' + value) else: VISA_Driver.writeAndLog(self, 'SENS:CURR:RANG:AUTO ' + value) elif quant.name.startswith('Resistance'): #If using manual resistance mode, do nothing if self.getValue('Resistance Measurement Mode') == 'Automatic': VISA_Driver.writeAndLog(self, 'SENS:RES:RANG:AUTO ' + value) return int(value) elif quant.name == 'Voltage Manual Range' or quant.name == 'Current Manual Range': #Check source mode func = self.getValue('Source function') if quant.name.startswith('Voltage'): if func == 'Voltage': #If quant matches source mode, set source range VISA_Driver.writeAndLog(self, 'SOUR:VOLT:RANG ' + str(value)) else: #Otherwise, set compliance rainge and measurement range VISA_Driver.writeAndLog( self, 'SENS:VOLT:PROT ' + str(value * 1.1)) VISA_Driver.writeAndLog(self, 'SENS:VOLT:RANG ' + str(value)) elif quant.name.startswith('Current'): if func == 'Current': VISA_Driver.writeAndLog(self, 'SOUR:CURR:RANG ' + str(value)) else: VISA_Driver.writeAndLog( self, 'SENS:CURR:PROT ' + str(value * 1.05)) VISA_Driver.writeAndLog(self, 'SENS:CURR:RANG ' + str(value)) return value elif quant.name == 'Averaging Time': self.log('Averaging called') NPLC = self.getValue('NPLC') self.log('NPLC: ' + str(NPLC)) repeat = self.getValue('Repeat Filter') self.log('repeat: ' + str(repeat)) medRank = self.getValue('Median Filter') self.log('medRank: ' + str(medRank)) avCount = self.getValue('Moving Filter') self.log('avCount: ' + str(avCount)) timeBase = 1.0 / 50.0 avTime = NPLC * timeBase * repeat * (2 * medRank + 1) * avCount self.setValue('Averaging Time', str(avTime)) return avTime else: return VISA_Driver.performSetValue(self, quant, value, options=options, sweepRate=sweepRate)
def performGetValue(self, quant, options={}): self.log('performGetValue called: ' + quant.name) if quant.name.startswith('Measure '): #Determine which variables are being measured quantDict = {'Measure Current':'CURR', \ 'Measure Voltage':'VOLT', \ 'Measure Resistance':'RES'} reply = VISA_Driver.askAndLog(self, 'FUNC?') if quantDict[quant.name] in reply: return True else: return False elif quant.name.endswith('variable'): #Have set up format so the read or fetch command always returns values in the following order quantDict = {'Voltage variable':0, \ 'Current variable':1, \ 'Resistance variable':2} #If this is first measurement call, perform read operation and return appropriate values if self.isFirstCall(options): reply = VISA_Driver.askAndLog(self, 'READ?') #otherwise perform fetch operation and return appropriate values else: reply = VISA_Driver.askAndLog(self, 'FETCH?') value = reply.split(',') return value[quantDict[quant.name]] elif quant.name.endswith('Range Mode'): #For converting reply to combo choice comboDict = {0: 'Manual', 1: 'Automatic'} #Check source mode func = self.getValue('Source function') if quant.name.startswith('Voltage'): if func == 'Voltage': #If quant matches source mode, get source range reply = VISA_Driver.askAndLog(self, 'SOUR:VOLT:RANG:AUTO?') else: #Otherwise, get measurement range reply = VISA_Driver.askAndLog(self, 'SENS:VOLT:RANG:AUTO?') elif quant.name.startswith('Current'): if func == 'Current': reply = VISA_Driver.askAndLog(self, 'SOUR:CURR:RANG:AUTO?') else: reply = VISA_Driver.askAndLog(self, 'SENS:CURR:RANG:AUTO?') elif quant.name.startswith('Resistance'): if self.getValue('Resistance Measurement Mode') == 'Automatic': reply = VISA_Driver.askAndLog(self, 'SENS:RES:RANG:AUTO?') else: reply = 0 return comboDict[int(reply)] elif quant.name == 'Voltage Manual Range' or quant.name == 'Current Manual Range': #Check source mode func = self.getValue('Source function') if quant.name.startswith('Voltage'): if func == 'Voltage': #If quant matches source mode, get source range reply = VISA_Driver.askAndLog(self, 'SOUR:VOLT:RANG?') else: #Otherwise, get measurement range reply = VISA_Driver.askAndLog(self, 'SENS:VOLT:RANG?') elif quant.name.startswith('Current'): if func == 'Current': reply = VISA_Driver.askAndLog(self, 'SOUR:CURR:RANG?') else: reply = VISA_Driver.askAndLog(self, 'SENS:CURR:RANG?') return reply elif quant.name == 'Averaging Time': self.log('Averaging called') NPLC = self.getValue('NPLC') self.log('NPLC: ' + str(NPLC)) repeat = self.getValue('Repeat Filter') self.log('repeat: ' + str(repeat)) medRank = self.getValue('Median Filter') self.log('medRank: ' + str(medRank)) avCount = self.getValue('Moving Filter') self.log('avCount: ' + str(avCount)) timeBase = 1.0 / 50.0 avTime = NPLC * timeBase * repeat * (2 * medRank + 1) * avCount return avTime else: return VISA_Driver.performGetValue(self, quant, options)
def performGetValue(self, quant, options ={}): couplingModes = ['Coupling CFRQAB','Coupling CFRQAC','Coupling RFLVAB','Coupling RFLVAC'] self.log('Quant.name is: '+quant.name+' Get value') if quant.name[-1] == ')': #quant is source specific source = quant.name[-2] #Use sourceCmd before every source specific command sourceCmd = 'SOURCE '+source+'; :' if quant.name == 'Combiner mode': reply = VISA_Driver.askAndLog(self,'CMODE?') #return syntax is ':CMODE <*>' reply = reply.split(' ')[1] combos = ['A','B','C','AB','BC','AC','ABC','OFF'] for comboValue in combos: #Need set so we get AB == BA, etc if set(reply) == set(comboValue): return comboValue self.log('Coupling mode not found: '+reply) elif quant.name == 'Impedance': reply = VISA_Driver.askAndLog(self,'IMPEDANCE?') if reply.split(' ')[1] == 'Z50R': return '50 Ohms' else: return '75 Ohms' elif quant.name in couplingModes: mode = quant.name.split(' ')[1] reply = VISA_Driver.askAndLog(self,'COUPLING?') #Reply syntax: COUPLING:MODE CFRQAB,RFLVAC,... #get rid of 'COUPLING:MODE' reply = reply.split(' ')[1] #puts 2nd part into list of enabled modes reply = reply.split(',') if mode in reply: return True else: return False elif quant.name.startswith('Coupling'): cmd = quant.name.split(' ') """ cmd[0] = 'coupling' cmd[1] = one of the coupling modes cmd[2] = MODE, HARM, SUBHARM, or OFFSET """ cmdStr = 'COUPLING: '+cmd[1]+'?' reply = VISA_Driver.askAndLog(self,cmdStr) #Reply syntax: :COUPLING:CFRQAC:MODE SUBHARM;HARM 2;SUBHARM 6;OFFSET 2 replist = reply.split(';') if cmd[2] == 'MODE': #Split MODE and SUBHARM in reply[0], return SUBHARM return replist[0].split(' ')[1] elif cmd[2] == 'HARM': #split HARM and value in reply[1] return replist[1].split(' ')[1] elif cmd[2] == 'SUBHARM': #split SUBHARM and value in reply[2] return replist[2].split(' ')[1] elif cmd[2] == 'OFFSET': #Split offset and value in reply[3] return replist[3].split(' ')[1] else: self.log('Received invalid response: '+reply) elif quant.name.startswith('Carrier Frequency'): reply = VISA_Driver.askAndLog(self,sourceCmd+'CFRQ?') #reply syntax: :CFRQ:VALUE 1000000000.0;INC 25000.0 reply = reply.split(';')[0] reply = reply.split(' ')[1] self.log('Carrier frequency: '+reply) return float(reply) elif quant.name.startswith('RF'): cmd = quant.name.split(' ') #cmd[1] = Output, Level, or Type #Reply syntax: :RFLV:UNITS DBM;TYPE PD;VALUE −103.5;INC 2.0;ON reply = VISA_Driver.askAndLog(self,sourceCmd+'RFLV?') reply = reply.split(';') if cmd[1] == 'Output': if reply[3] == 'ON': return True else: return False elif cmd[1] == 'Level': return reply[2].split(' ')[1] elif cmd[1] == 'Type': return reply[1].split(' ')[1] else: self.log('Quant not recognised: '+quant.name) elif quant.name.startswith('Modulation Control'): reply = VISA_Driver.askAndLog(self,sourceCmd+'MOD?') if reply.split(':')[-1] == 'ON': return True else: return False elif quant.name.startswith('Modulation mode'): reply = VISA_Driver.askAndLog(self,sourceCmd+'MODE?') #Reply syntax: :MODE AM,FM,PULSE #Remove ':MODE' component of reply reply = reply.split(' ')[1] #Separate activated modes into list reply = reply.split(',') if 'AM' in reply: if 'FM' in reply: return 'AM & FM' elif 'PM' in reply: return 'AM & PM' else: return 'AM' elif 'FM' in reply: return 'FM' elif 'PM' in reply: return 'PM' elif 'FSK2L' in reply: return 'FSK2L' elif 'FSK4L' in reply: return 'FSK4L' else: self.log('No modulation mode active') elif quant.name[:2] in ['FM','PM','AM']: cmd = quant.name.split(' ') """ cmd[0] = FM, FM1, FM2, PM, PM1, PM2, AM, AM1, or AM2 cmd[1] = Status, Deviation, Source, Modulation, Waveform, Phase, (Depth for AM) """ if cmd[1] == 'Status': reply = VISA_Driver.askAndLog(self,sourceCmd+cmd[0]+'?') #Reply syntax: :FM1:DEVN 1000.0;INT;OFF;INC 1000.0 reply = reply.split(';') if reply[2] == 'OFF': return False else: return True elif cmd[1] == 'Deviation': reply = VISA_Driver.askAndLog(self,sourceCmd+cmd[0]+'?') #Reply syntax: :FM1:DEVN 25000.0;INT;ON;INC 1000.0 reply = reply.split(';') return reply[0].split(' ')[1] elif cmd[1] == 'Source': reply = VISA_Driver.askAndLog(self,sourceCmd+cmd[0]+'?') #Reply syntax: :FM1:DEVN 25000.0;INT;ON;INC 1000.0 reply = reply.split(';') comboDict = {'INT':'Internal','EXTAC':'External AC','EXTALC':'External ALC','EXTDC':'External DC'} return comboDict[reply[1]] elif cmd[1] == 'Modulation': reply = VISA_Driver.askAndLog(self,sourceCmd+cmd[0]+':MODF?') #Reply syntax: :FM1:MODF:VALUE 5750.00;SIN;INC 1000.00 reply = reply.split(';')[0] return reply.split(' ')[1] elif cmd[1] == 'Waveform': reply = VISA_Driver.askAndLog(self,sourceCmd+cmd[0]+':MODF?') #Reply syntax: :FM1:MODF:VALUE 5750.00;SIN;INC 1000.00 return reply.split(';')[1] elif cmd[1] == 'Phase': return 0 #No way to get this setting elif cmd[1] == 'Depth': reply = VISA_Driver.askAndLog(self,sourceCmd+cmd[0]+'?') #Reply syntax: :FM1:DEVN 25000.0;INT;ON;INC 1000.0 reply = reply.split(';') return reply[0].split(' ')[1] else: self.log('Quant command not recognised: '+quant.name) elif quant.name.startswith('Pulse Modulation'): reply = VISA_Driver.askAndLog(self,sourceCmd+'PULSE?') #Reply syntax: :PULSE:ON/OFF #Remove ':MODE' component of reply if reply.endswith('ON'): return True else: return False else: self.log('quant.name not tringgered: '+quant.name) return VISA_Driver.performGetValue(self,quant,options)
def performSetValue(self, quant, value, sweepRate=0.0, options={}): self.log('performSetValue called: ' + quant.name + ' value: ' + str(value)) if quant.name == 'Voltage Mode': if value == 'Fixed': VISA_Driver.writeAndLog(self, 'SOUR:VOLT:MODE FIX') elif value == 'Ramp': #General settings for ramp function #Rtime, start:level, end:level are set when actually sweeping cmd = [] cmd.append('SOUR:VOLT:MODE ARB') cmd.append('SOUR:ARB:FUNC:SHAP RAMP') cmd.append('SOUR:ARB:COUN 1') cmd.append('SOUR:ARB:VOLT:RAMP:END:TIME 0') cmd.append('SOUR:ARB:VOLT:RAMP:STAR:TIME 0') sCmd = cmd.join('; :') VISA_Driver.writeAndLog(self, sCmd) elif quant.name.endswith('Amplitude'): #Voltage Amplitude #Current Amplitude if quant.name.startswith('Voltage'): cmd = 'SOUR:VOLT' maxOutpDiff = 0.005 #Never change by more than 5mV else: cmd = 'SOUR:CURR' maxOutpDiff = 0.001 #Never change by more than 1 mA initValue = VISA_Driver.askAndLog(self, cmd + '?') outpDiff = value - float(initValue) if outpDiff == 0: #Don't send if already at right value return value elif outpDiff > maxOutpDiff: #If program is trying to move to a value too far away instantly, # then override by changing value value = initValue + maxOutpDiff elif outpDiff < -maxOutpDiff: value = initValue - maxOutpDiff #Enter the (modified or unmodified) value VISA_Driver.writeAndLog(self, cmd + ' ' + str(value)) return value elif quant.name.endswith(' Ramp'): if quant.name.startswith('Voltage'): cmd = 'SOUR:VOLT' cmd2 = 'SOUR:ARB:VOLT:RAMP' maxSweepRate = 0.005 #Never sweep faster than 5mV/sec elif quant.name.startswith('Current'): cmd = 'SOUR:CURR' cmd2 = 'SOUR:ARB:CURR:RAMP' maxSweepRate = 0.001 #Never sweep faster than 1mA/sec self.log("getting init value for ramp") initValue = float(VISA_Driver.askAndLog(self, cmd + '?')) outpDiff = value - initValue if sweepRate == 0 or sweepRate > maxSweepRate: sweepRate = maxSweepRate rTime = abs(outpDiff) / sweepRate cmd = [] cmd.append(cmd2 + ':END:LEV ' + str(value)) cmd.append(cmd2 + ':RTIM ' + str(rTime)) cmd.append(cmd2 + ':STAR:LEV ' + str(initValue)) cmd.append( 'TRIG' ) #Sends an immediate trigger for both source and measure actions sCmd = '; :'.join(cmd) VISA_Driver.writeAndLog(self, sCmd) elif quant.name.startswith('Measure '): #Enable appropriate functions, if something has been updated if self.isConfigUpdated(): #Determine which variables are being measured quantDict = {'Measure Current':['CURR',False], \ 'Measure Voltage':['VOLT',False], \ 'Measure Resistance':['RES',False]} for key, list in quantDict.items(): list[1] = self.getValue(key) if list[1]: VISA_Driver.writeAndLog(self, 'FUNC:ON ' + list[0]) else: VISA_Driver.writeAndLog(self, 'FUNC:OFF ' + list[0]) return value elif quant.name == "Measurement Speed Method": #No commands sent to device for this quantity return value else: return VISA_Driver.performSetValue(self, quant, value, options=options, sweepRate=sweepRate)
def performSetValue(self, quant, value, sweepRate=0.0, options={}): self.log("performSetValue called: " + quant.name + " value: " + str(value)) if quant.name == "Voltage Mode": if value == "Fixed": VISA_Driver.writeAndLog(self, "SOUR:VOLT:MODE FIX") elif value == "Ramp": # General settings for ramp function # Rtime, start:level, end:level are set when actually sweeping cmd = [] cmd.append("SOUR:VOLT:MODE ARB") cmd.append("SOUR:ARB:FUNC:SHAP RAMP") cmd.append("SOUR:ARB:COUN 1") cmd.append("SOUR:ARB:VOLT:RAMP:END:TIME 0") cmd.append("SOUR:ARB:VOLT:RAMP:STAR:TIME 0") sCmd = cmd.join("; :") VISA_Driver.writeAndLog(self, sCmd) elif quant.name.endswith("Amplitude"): # Voltage Amplitude # Current Amplitude if quant.name.startswith("Voltage"): cmd = "SOUR:VOLT" maxOutpDiff = 0.005 # Never change by more than 5mV else: cmd = "SOUR:CURR" maxOutpDiff = 0.001 # Never change by more than 1 mA initValue = VISA_Driver.askAndLog(self, cmd + "?") outpDiff = value - float(initValue) if outpDiff == 0: # Don't send if already at right value return value elif outpDiff > maxOutpDiff: # If program is trying to move to a value too far away instantly, # then override by changing value value = initValue + maxOutpDiff elif outpDiff < -maxOutpDiff: value = initValue - maxOutpDiff # Enter the (modified or unmodified) value VISA_Driver.writeAndLog(self, cmd + " " + str(value)) return value elif quant.name.endswith(" Ramp"): if quant.name.startswith("Voltage"): cmd = "SOUR:VOLT" cmd2 = "SOUR:ARB:VOLT:RAMP" maxSweepRate = 0.005 # Never sweep faster than 5mV/sec elif quant.name.startswith("Current"): cmd = "SOUR:CURR" cmd2 = "SOUR:ARB:CURR:RAMP" maxSweepRate = 0.001 # Never sweep faster than 1mA/sec self.log("getting init value for ramp") initValue = float(VISA_Driver.askAndLog(self, cmd + "?")) outpDiff = value - initValue if sweepRate == 0 or sweepRate > maxSweepRate: sweepRate = maxSweepRate rTime = abs(outpDiff) / sweepRate cmd = [] cmd.append(cmd2 + ":END:LEV " + str(value)) cmd.append(cmd2 + ":RTIM " + str(rTime)) cmd.append(cmd2 + ":STAR:LEV " + str(initValue)) cmd.append("TRIG") # Sends an immediate trigger for both source and measure actions sCmd = "; :".join(cmd) VISA_Driver.writeAndLog(self, sCmd) elif quant.name.startswith("Measure "): # Enable appropriate functions, if something has been updated if self.isConfigUpdated(): # Determine which variables are being measured quantDict = { "Measure Current": ["CURR", False], "Measure Voltage": ["VOLT", False], "Measure Resistance": ["RES", False], } for key, list in quantDict.items(): list[1] = self.getValue(key) if list[1]: VISA_Driver.writeAndLog(self, "FUNC:ON " + list[0]) else: VISA_Driver.writeAndLog(self, "FUNC:OFF " + list[0]) return value elif quant.name == "Measurement Speed Method": # No commands sent to device for this quantity return value else: return VISA_Driver.performSetValue(self, quant, value, options=options, sweepRate=sweepRate)
def performSetValue(self, quant, value, sweepRate=0.0, options={}): self.log('performSetValue called: '+quant.name+' value: '+str(value)) if quant.name == 'Source on_off': if value == 'On': VISA_Driver.writeAndLog(self,'OUTP:STAT 1') return 'On' else: #Sweep source to zero before turning off, to avoid sudden jumps func = self.getValue('Source function') if func == 'Voltage': self.sendValueToOther('Voltage Amplitude',0) while self.sendValueToOther('Voltage Amplitude',0) != 0: self.wait(0.1) elif func == 'Current': self.sendValueToOther('Current Amplitude',0) while self.sendValueToOther('Voltage Amplitude',0) != 0: self.wait(0.1) VISA_Driver.writeAndLog(self,'OUTP:STAT 0') return 'Off' elif quant.name.endswith('Amplitude'): #Voltage Amplitude #Current Amplitude if quant.name.startswith('Voltage'): cmd = 'SOUR:VOLT' maxOutpDiff = 0.0005 #5mV/s #Program sets source every 0.1 seconds, so sweepRate = outpDiff/0.1 = 10*outpDiff #Note minimum output change is 5uV. else: cmd = 'SOUR:CURR' maxOutpDiff = 0.0001 initValue = float(VISA_Driver.askAndLog(self,cmd+'?')) outpDiff = value-initValue if outpDiff == 0: #Don't send if already at right value return value elif outpDiff > maxOutpDiff: #If program is trying to move to a value too far away instantly, # then override by changing value value = initValue+maxOutpDiff elif outpDiff < -maxOutpDiff: value = initValue-maxOutpDiff #Enter the (modified or unmodified) value VISA_Driver.writeAndLog(self,cmd+' '+str(value)) return value elif quant.name.startswith('Measure '): #Determine which variables are being measured quantDict = {'Measure Current':['CURR',False], \ 'Measure Voltage':['VOLT',False], \ 'Measure Resistance':['RES',False]} for key,list in quantDict.items(): list[1] = self.getValue(key) #If only one, turn off concurrency if sum(list[1] for list in quantDict.values()) == 1: VISA_Driver.writeAndLog(self,'FUNC:CONC 0') else: VISA_Driver.writeAndLog(self,'FUNC:CONC 1') #Enable appropriate functions for key,list in quantDict.items(): if list[1]: VISA_Driver.writeAndLog(self,'FUNC:ON '+'"'+list[0]+'"') else: VISA_Driver.writeAndLog(self,'FUNC:OFF '+'"'+list[0]+'"') return value elif quant.name.endswith('Range Mode'): #convert auto/manual to auto on, auto off comboDict = {'Manual':'0','Automatic':'1'} value = comboDict[value] #Check source mode func = self.getValue('Source function') if quant.name.startswith('Voltage'): if func == 'Voltage': #If quant matches source mode, set source range VISA_Driver.writeAndLog(self,'SOUR:VOLT:RANG:AUTO '+value) else: #Otherwise, set measurement range VISA_Driver.writeAndLog(self,'SENS:VOLT:RANG:AUTO '+value) elif quant.name.startswith('Current'): if func == 'Current': VISA_Driver.writeAndLog(self,'SOUR:CURR:RANG:AUTO '+value) else: VISA_Driver.writeAndLog(self,'SENS:CURR:RANG:AUTO '+value) elif quant.name.startswith('Resistance'): #If using manual resistance mode, do nothing if self.getValue('Resistance Measurement Mode') == 'Automatic': VISA_Driver.writeAndLog(self,'SENS:RES:RANG:AUTO '+value) return int(value) elif quant.name == 'Voltage Manual Range' or quant.name == 'Current Manual Range' : #Check source mode func = self.getValue('Source function') if quant.name.startswith('Voltage'): if func == 'Voltage': #If quant matches source mode, set source range VISA_Driver.writeAndLog(self,'SOUR:VOLT:RANG '+str(value)) else: #Otherwise, set compliance rainge and measurement range VISA_Driver.writeAndLog(self,'SENS:VOLT:PROT '+str(value*1.1)) VISA_Driver.writeAndLog(self,'SENS:VOLT:RANG '+str(value)) elif quant.name.startswith('Current'): if func == 'Current': VISA_Driver.writeAndLog(self,'SOUR:CURR:RANG '+str(value)) else: VISA_Driver.writeAndLog(self,'SENS:CURR:PROT '+str(value*1.05)) VISA_Driver.writeAndLog(self,'SENS:CURR:RANG '+str(value)) return value elif quant.name == 'Averaging Time': self.log('Averaging called') NPLC = self.getValue('NPLC') self.log('NPLC: '+str(NPLC)) repeat = self.getValue('Repeat Filter') self.log('repeat: '+str(repeat)) medRank = self.getValue('Median Filter') self.log('medRank: '+str(medRank)) avCount = self.getValue('Moving Filter') self.log('avCount: '+str(avCount)) timeBase = 1.0/50.0 avTime = NPLC*timeBase*repeat*(2*medRank+1)*avCount self.setValue('Averaging Time',str(avTime)) return avTime else: return VISA_Driver.performSetValue(self,quant,value,options=options,sweepRate=sweepRate)
def performGetValue(self, quant, options={}): self.log('performGetValue called: '+quant.name) if quant.name.startswith('Measure '): #Determine which variables are being measured quantDict = {'Measure Current':'CURR', \ 'Measure Voltage':'VOLT', \ 'Measure Resistance':'RES'} reply = VISA_Driver.askAndLog(self,'FUNC?') if quantDict[quant.name] in reply: return True else: return False elif quant.name.endswith('variable'): #Have set up format so the read or fetch command always returns values in the following order quantDict = {'Voltage variable':0, \ 'Current variable':1, \ 'Resistance variable':2} #If this is first measurement call, perform read operation and return appropriate values if self.isFirstCall(options): reply = VISA_Driver.askAndLog(self,'READ?') #otherwise perform fetch operation and return appropriate values else: reply = VISA_Driver.askAndLog(self,'FETCH?') value = reply.split(',') return value[quantDict[quant.name]] elif quant.name.endswith('Range Mode'): #For converting reply to combo choice comboDict = {0:'Manual',1:'Automatic'} #Check source mode func = self.getValue('Source function') if quant.name.startswith('Voltage'): if func == 'Voltage': #If quant matches source mode, get source range reply = VISA_Driver.askAndLog(self,'SOUR:VOLT:RANG:AUTO?') else: #Otherwise, get measurement range reply = VISA_Driver.askAndLog(self,'SENS:VOLT:RANG:AUTO?') elif quant.name.startswith('Current'): if func == 'Current': reply = VISA_Driver.askAndLog(self,'SOUR:CURR:RANG:AUTO?') else: reply = VISA_Driver.askAndLog(self,'SENS:CURR:RANG:AUTO?') elif quant.name.startswith('Resistance'): if self.getValue('Resistance Measurement Mode') == 'Automatic': reply = VISA_Driver.askAndLog(self,'SENS:RES:RANG:AUTO?') else: reply = 0 return comboDict[int(reply)] elif quant.name == 'Voltage Manual Range' or quant.name == 'Current Manual Range' : #Check source mode func = self.getValue('Source function') if quant.name.startswith('Voltage'): if func == 'Voltage': #If quant matches source mode, get source range reply = VISA_Driver.askAndLog(self,'SOUR:VOLT:RANG?') else: #Otherwise, get measurement range reply = VISA_Driver.askAndLog(self,'SENS:VOLT:RANG?') elif quant.name.startswith('Current'): if func == 'Current': reply = VISA_Driver.askAndLog(self,'SOUR:CURR:RANG?') else: reply = VISA_Driver.askAndLog(self,'SENS:CURR:RANG?') return reply elif quant.name == 'Averaging Time': self.log('Averaging called') NPLC = self.getValue('NPLC') self.log('NPLC: '+str(NPLC)) repeat = self.getValue('Repeat Filter') self.log('repeat: '+str(repeat)) medRank = self.getValue('Median Filter') self.log('medRank: '+str(medRank)) avCount = self.getValue('Moving Filter') self.log('avCount: '+str(avCount)) timeBase = 1.0/50.0 avTime = NPLC*timeBase*repeat*(2*medRank+1)*avCount return avTime else: return VISA_Driver.performGetValue(self,quant,options)