class Driver(visaDriver): __log__ = log support_models = ['DPO4104B'] quants = [ QReal('X Scale', set_cmd='HOR:SCA %(value)e', get_cmd='HOR:SCA?'), QInteger('Bytes per Point', set_cmd='WFMI:BYT_N?', get_cmd='WFMI:BYT_N?'), QReal('X Step', set_cmd=':WFMI:XIN %(value)e', get_cmd=':WFMI:XIN?'), QReal('X Zero', set_cmd=':WFMI:XZER %(value)e', get_cmd=':WFMI:XZER?'), QReal('Y Scale', set_cmd=':CH%(ch)d:SCA %(value)e', get_cmd=':CH%(ch)d:SCA?'), QReal('Y Position', set_cmd=':CH%(ch)d:POS %(value)e', get_cmd=':CH%(ch)d:POS?'), QReal('Y Mult', set_cmd=':WFMI:YMU %(value)e', get_cmd=':WFMI:YMU?'), QReal('Y Offset', set_cmd=':WFMI:YOF %(value)e', get_cmd=':WFMI:YOF?'), QReal('Y Zero', set_cmd=':WFMI:YZER %(value)e', get_cmd=':WFMI:YZER?'), QVector('Histogram', get_cmd='HIStogram:DATa?'), QReal('Histogram Start', get_cmd='HIStogram:STARt?'), QReal('Histogram End', get_cmd='HIStogram:END?') ] def resetHist(self): self.write('HIStogram:COUNt RESET') def get_Trace(self, ch=1, start=1, stop=100000): self.write(':DAT:SOU CH%d' % ch) self.write(':DAT:START %d' % start) self.write(':DAT:STOP %d' % stop) y = np.array(self.query_ascii_values('CURV?')) y_offset = self.getValue('Y Offset') y_scale = self.getValue('Y Mult') y_zero = self.getValue('Y Zero') y = (y - y_offset) * y_scale + y_zero x = np.arange(start - 1, stop, 1) * self.getValue('X Step') + self.getValue('X Zero') return x, (y * 10 - self.getValue( 'Y Position', ch=ch)) * self.getValue('Y Scale', ch=ch)
class Driver(visaDriver): __log__ = log error_command = '' support_models = ['SR620'] quants = [ QVector('Data', unit=''), QReal('Ext Level', unit='V', set_cmd='LEVL 0,%(value)f', get_cmd='LEVL? 0'), QReal('A Level', unit='V', set_cmd='LEVL 1,%(value)f', get_cmd='LEVL? 1'), QReal('B Level', unit='V', set_cmd='LEVL 2,%(value)f', get_cmd='LEVL? 2'), QOption('Ext Term', set_cmd='TERM 0,%(option)s', get_cmd='TERM? 0', options=[('50 Ohm', '0'), ('1 MOhm', '1')]), QOption('A Term', set_cmd='TERM 1,%(option)s', get_cmd='TERM? 1', options=[('50 Ohm', '0'), ('1 MOhm', '1')]), QOption('B Term', set_cmd='TERM 2,%(option)s', get_cmd='TERM? 2', options=[('50 Ohm', '0'), ('1 MOhm', '1')]), QOption('Ext Slope', set_cmd='TSLP 0,%(option)s', get_cmd='TSLP? 0', options=[('Positive', '0'), ('Negative', '1')]), QOption('A Slope', set_cmd='TSLP 1,%(option)s', get_cmd='TSLP? 1', options=[('Positive', '0'), ('Negative', '1')]), QOption('B Slope', set_cmd='TSLP 2,%(option)s', get_cmd='TSLP? 2', options=[('Positive', '0'), ('Negative', '1')]), QOption('A Coupling', set_cmd='TCPL 1,%(option)s', get_cmd='TCPL? 1', options=[('DC', '0'), ('AC', '1')]), QOption('B Coupling', set_cmd='TCPL 2,%(option)s', get_cmd='TCPL? 2', options=[('DC', '0'), ('AC', '1')]), QOption('Mode', set_cmd='MODE %(option)s', get_cmd='MODE?', options=[ ('time', '0'), ('width', '1'), ('tr/tf', '2'), ('freq', '3'), ('period', '4'), ('phase', '5'), ('count', '6'), ]), QOption('Arming Mode', set_cmd='ARMM %s', get_cmd='ARMM?', options=[ ('+- time', '0'), ('+ time', '1'), ('1 period', '2'), ('0.01 s gate', '3'), ('0.1 s gate', '4'), ('1.0 s gate', '5'), ('ext trig +- time', '6'), ('ext trig + time', '7'), ('ext gate/trig holdoff', '8'), ('ext 1 period', '9'), ('ext 0.01 s gate', '10'), ('ext 0.1 s gate', '11'), ('ext 1.0 s gate', '12'), ]), ] def performGetValue(self, quant, **kw): if quant.name == 'Data': if 'count' in kw.keys(): count = kw['count'] else: count = 100 return self.get_Data(count) else: return super(Driver, self).performGetValue(self, quant, **kw) def get_Data(self, count=100): block = b'' max = 5000 loop = int(count / max) last = count % max self.write('*CLS') try: if last < count: for i in range(loop): self.write('BDMP %d' % max) block += self.__read(8 * max) self.write('BDMP %d' % last) block += self.__read(8 * last) except: raise mode = int(self.query('MODE?')) expd = int(self.query('EXPD?')) self.write('AUTM 1') factors = [ 1.05963812934E-14, 1.05963812934E-14, 1.05963812934E-14, 1.24900090270331E-9, 1.05963812934E-14, 8.3819032E-8, 0.00390625 ] ret = np.array(list(struct.unpack('<%dq' % count, block))) * factors[mode] if expd != 0: ret = ret * 1e-3 return ret def __read(self, size): try: buff = self.ins.visalib.read(self.ins.session, size)[0] except VisaIOWarning: pass return buff
class Driver(visaDriver): __log__ = log support_models = [ 'E8363B', 'E8363C', 'E5071C', 'E5080A', 'ZNB20-2Port', 'N5232A' ] quants = [ QReal('Power', value=-20, unit='dBm', set_cmd='SOUR:POW %(value)e%(unit)s', get_cmd='SOUR:POW?'), # QOption('PowerMode', # value='OFF', # ch=1, # set_cmd='SOUR%(ch)s:POW:MODE %(option)s', # get_cmd='SOUR%(ch)s:POW:MODE?', # options=[('OFF', 'OFF'), ('ON', 'ON')]), QReal('Bandwidth', value=1000, unit='Hz', ch=1, set_cmd='SENS%(ch)d:BAND %(value)e%(unit)s', get_cmd='SENS%(ch)d:BAND?'), QReal('Frequency center', value=5e9, ch=1, unit='Hz', set_cmd='SENS%(ch)d:FREQ:CENT %(value)e%(unit)s', get_cmd='SENS%(ch)d:FREQ:CENT?'), QReal('Frequency span', value=2e9, ch=1, unit='Hz', set_cmd='SENS%(ch)d:FREQ:SPAN %(value)e%(unit)s', get_cmd='SENS%(ch)d:FREQ:SPAN?'), QReal('Frequency start', value=4e9, ch=1, unit='Hz', set_cmd='SENS%(ch)d:FREQ:STAR %(value)e%(unit)s', get_cmd='SENS%(ch)d:FREQ:STAR?'), QReal('Frequency stop', value=6e9, ch=1, unit='Hz', set_cmd='SENS%(ch)d:FREQ:STOP %(value)e%(unit)s', get_cmd='SENS%(ch)d:FREQ:STOP?'), QVector('Frequency', unit='Hz', ch=1), QVector('Trace', ch=1), QVector('S', ch=1), QOption('Sweep', value='ON', set_cmd='INIT:CONT %(option)s', options=[('OFF', 'OFF'), ('ON', 'ON')]), QInteger('Number of points', value=201, ch=1, unit='', set_cmd='SENS%(ch)d:SWE:POIN %(value)d', get_cmd='SENS%(ch)d:SWE:POIN?'), QOption('Format', value='MLOG', set_cmd='CALC:FORM %(option)s', get_cmd='CALC:FORM?', options=[('Mlinear', 'MLIN'), ('Mlog', 'MLOG'), ('Phase', 'PHAS'), ('Unwrapped phase', 'UPH'), ('Imag', 'IMAG'), ('Real', 'REAL'), ('Polar', 'POL'), ('Smith', 'SMIT'), ('SWR', 'SWR'), ('Group Delay', 'GDEL')]), QOption('SweepType', value='', ch=1, set_cmd='SENS%(ch)d:SWE:TYPE %(option)s', get_cmd='SENS%(ch)d:SWE:TYPE?', options=[('Linear', 'LIN'), ('Log', 'LOG'), ('Power', 'POW'), ('CW', 'CW'), ('Segment', 'SEGM'), ('Phase', 'PHAS')]) ] ''' def performSetValue(self, quant, value, **kw): if quant.name == 'Power': self.setValue('Power:Start', value) self.setValue('Power:Center', value) self.setValue('Power:Stop', value) else: super(Driver, self).performSetValue(quant, value, **kw) ''' def performOpen(self): super().performOpen() self.set_timeout(15) self.pna_select(ch=1) def performGetValue(self, quant, **kw): get_vector_methods = { 'Frequency': self.get_Frequency, 'Trace': self.get_Trace, 'S': self.get_S, } if quant.name in get_vector_methods.keys(): return get_vector_methods[quant.name](ch=kw.get('ch', 1)) else: return super(Driver, self).performGetValue(quant, **kw) def get_Trace(self, ch=1): '''Get trace''' return self.get_S(ch, formated=True) def get_S(self, ch=1, formated=False): '''Get the complex value of S paramenter or formated data''' #Select the measurement #self.pna_select(ch) #Stop the sweep self.setValue('Sweep', 'OFF') #Begin a measurement self.write('INIT:IMM') self.write('*WAI') #Get the data self.write('FORMAT:BORD NORM') if self.model in ['E5071C']: self.write(':FORM:DATA ASC') cmd = ("CALC%d:DATA:FDATA?" % ch) if formated else ("CALC%d:DATA:SDATA?" % ch) else: #self.write('FORMAT ASCII') self.write(':FORM:DATA REAL,32') cmd = ("CALC%d:DATA? FDATA" % ch) if formated else ("CALC%d:DATA? SDATA" % ch) #data = np.asarray(self.query_ascii_values(cmd)) data = np.asarray(self.query_binary_values(cmd, is_big_endian=True)) self.write('FORMAT ASCII') if formated: if self.model in ['E5071C']: data = data[::2] else: data = data[::2] + 1j * data[1::2] #Start the sweep self.setValue('Sweep', 'ON') return data def S(self, i=1, j=1, ch=1, mname="MyMeas"): self.create_measurement(name=mname, param=f"S{i}{j}", ch=ch) self.write('CALC%d:PAR:SEL "%s"' % (ch, mname)) #Stop the sweep self.setValue('Sweep', 'OFF') #Begin a measurement self.write('INIT:IMM') self.write('*WAI') #Get the data self.write('FORMAT:BORD NORM') if self.model in ['E5071C']: self.write(':FORM:DATA ASC') cmd = ("CALC%d:DATA:SDATA?" % ch) else: self.write('FORMAT ASCII') cmd = ("CALC%d:DATA? SDATA" % ch) #Start the sweep self.setValue('Sweep', 'ON') data = np.asarray(self.query_ascii_values(cmd)) data = data[::2] + 1j * data[1::2] return data def get_measurements(self, ch=1): if self.model in ['E5071C']: return if self.model in ['E8363C', 'E8363B', 'E5080A', 'N5232A']: quote = '" ' elif self.model in ['ZNB20-2Port']: quote = "' " msg = self.query('CALC%d:PAR:CAT?' % ch).strip(quote) meas = msg.split(',') return meas[::2], meas[1::2] def create_measurement(self, name='MyMeas', param='S11', ch=1): mname, params = self.get_measurements(ch=ch) if name in mname: self.write('CALC%d:PAR:DEL "%s"' % (ch, name)) self.write('CALC%d:PAR:DEF "%s",%s' % (ch, "MyMeas", param)) def pna_select(self, ch=1): '''Select the measurement''' if self.model in ['E5071C']: return mname, params = self.get_measurements(ch=ch) measname = mname[0] self.write('CALC%d:PAR:SEL "%s"' % (ch, measname)) def get_Frequency(self, ch=1): """Return the frequency of pna measurement""" #Select the measurement #self.pna_select(ch) if self.model in ['E8363C', 'E5080A']: cmd = 'CALC%d:X?' % ch self.write(':FORM:DATA REAL,32') data = self.query_binary_values(cmd, is_big_endian=True) # self.write('FORMAT ASCII') return np.asarray(data) if self.model in ['E8363B', 'N5232A']: freq_star = self.getValue('Frequency start', ch=1) freq_stop = self.getValue('Frequency stop', ch=1) num_of_point = self.getValue('Number of points', ch=1) return np.array(np.linspace(freq_star, freq_stop, num_of_point)) elif self.model in ['ZNB20-2Port']: cmd = 'CALC%d:DATA:STIM?' % ch return np.asarray(self.query_ascii_values(cmd)) def set_segments(self, segments=[], form='Start Stop'): self.write('SENS:SEGM:DEL:ALL') if form == 'Start Stop': cmd = ['SENS:SEGM:LIST SSTOP,%d' % len(segments)] for kw in segments: data = '1,%(num)d,%(start)g,%(stop)g,%(IFBW)g,0,%(power)g' % kw cmd.append(data) else: cmd = ['SENS:SEGM:LIST CSPAN,%d' % len(segments)] for kw in segments: data = '1,%(num)d,%(center)g,%(span)g,%(IFBW)g,0,%(power)g' % kw cmd.append(data) self.write('FORMAT ASCII') self.write(','.join(cmd))
class Driver(visaDriver): error_command = '' support_models = ['33120A', '33220A'] quants = [ QReal('Frequency', unit='Hz', set_cmd='FREQ %(value).11E %(unit)s', get_cmd='FREQ?'), QReal('Vpp', unit='VPP', set_cmd='VOLT %(value).5E %(unit)s', get_cmd='VOLT?'), QReal('Offset', unit='V', set_cmd='VOLT:OFFS %(value).5E %(unit)s', get_cmd='VOLT:OFFS?'), QVector('Waveform', unit='V'), QString('Trigger', set_cmd='TRIG:SOUR %(value)s', get_cmd='TRIG:SOUR?') ] def performOpen(self): super(Driver,self).performOpen() self.write('FORM:BORD NORM') self.waveform_list = self.query('DATA:CAT?')[1:-1].split('","') self.current_waveform = self.query('FUNC:SHAP?') if self.current_waveform == 'USER': self.current_waveform = self.query('FUNC:USER?') self.arb_waveforms = self.query('DATA:NVOL:CAT?')[1:-1].split('","') self.trigger_source = self.query('TRIG:SOUR?') self.inner_waveform = ["SINC","NEG_RAMP","EXP_RISE","EXP_FALL","CARDIAC"] if self.model == '33120A': self.max_waveform_size = 16000 self.trigger_count = int(float(self.query('BM:NCYC?'))) elif self.model == '33220A': self.max_waveform_size = 16384 self.trigger_count = int(float(self.query("BURS:NCYC?"))) def performSetValue(self, quant, value, **kw): if quant.name == 'Waveform': if len(value) > self.max_waveform_size: value = value[:self.max_waveform_size] value = np.array(value) vpp = value.max() - value.min() offs = (value.max() + value.min())/2.0 if vpp == 0: self.DC(offs) return name = kw['name'] if 'name' in kw.keys() else 'ABS' freq = kw['freq'] if 'freq' in kw.keys() else None self.update_waveform(2*(value-offs)/vpp, name=name) self.use_waveform(name, vpp=vpp, offs=offs, freq=freq) else: super(Driver,self).performSetValue(self, quant, value, **kw) def __del_func(self, name): if name in self.arb_waveforms: if name == self.current_waveform: self.DC(0) self.write('DATA:DEL %s' % name) self.arb_waveforms.remove(name) self.waveform_list.remove(name) def update_waveform(self, values, name='ABS'): if self.model == '33120A': clip = lambda x: (2047*x).clip(-2047,2047).astype(int) elif self.model == '33220A': clip = lambda x: (8191*x).clip(-8191,8191).astype(int) values = clip(values) self.write_binary_values('DATA:DAC VOLATILE,', values, datatype='h', is_big_endian=True) if len(name) > 8: name = name[:8] name = name.upper() if len(self.arb_waveforms) >= 4: for wf in self.arb_waveforms: if wf != self.current_waveform: self.__del_func(wf) self.write('DATA:COPY %s,VOLATILE' % name) def use_waveform(self, name, freq=None, vpp=None, offs=None, ch=1): freq_s = ("%.11E" % freq) if freq != None else "DEF" vpp_s = ("%.5E" % vpp) if vpp != None else "DEF" offs_s = ("%.5E" % offs) if offs != None else "DEF" name = name.upper() if name in self.inner_waveform: self.write('APPL:%s %s,%s,%s' % (name, freq_s, vpp_s, offs_s)) else: self.write('FUNC:USER %s' % name) self.write('APPL:USER %s,%s,%s' % (freq_s, vpp_s, offs_s)) if self.trigger_source != 'IMM': self.set_trigger(source = self.trigger_source, count = self.trigger_count) self.current_waveform = name time.sleep(1) def DC(self, v): """输出直流电压""" self.write('APPL:DC DEF,DEF,%.5E' % v) self.current_waveform = 'DC' def off(self): self.DC(0) def set_trigger(self, source='IMM', count=1): """设置触发 source : 触发源,可设为'IMM', 'EXT' 或 'BUS' count : 脉冲串的个数 """ if source not in ['IMM', 'EXT', 'BUS']: return if count < 1 or count > 50000: return self.trigger_source = source self.write("TRIG:SOUR %s" % source) self.trigger_count = count if count != 1: self.write("BM:NCYC %d" % count) if source != 'IMM': self.write("BM:STAT ON") def refresh(self): """刷新波形""" if self.current_waveform == "DC": return if self.current_waveform not in self.inner_waveform: self.write("FUNC:SHAP USER") else: self.write("FUNC:SHAP %s" % self.current_waveform)