Example #1
0
 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)
Example #6
0
    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)
Example #7
0
 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)
Example #9
0
 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)