dut = WSA() win = MainApplication(dut) win.resize(1000, 600) win.setWindowTitle("PYRF FFT Plot Example") if len(sys.argv) > 1: ip = sys.argv[1] else: ip, ok = QtGui.QInputDialog.getText(win, 'Open Device', 'Enter a hostname or IP address:') dut.connect(ip) # initialize WSA configurations dut.reset() dut.request_read_perm() dut.freq(CENTER_FREQ) dut.decimation(DECIMATION) #dut.attenuator(ATTENUATOR) dut.rfe_mode(RFE_MODE) BANDWIDTH = dut.properties.FULL_BW[RFE_MODE] # initialize plot fft_plot = win.addPlot(title="Power Vs. Frequency") # initialize x-axes limits plot_xmin = (CENTER_FREQ) - (BANDWIDTH / 2) plot_xmax = (CENTER_FREQ) + (BANDWIDTH / 2) fft_plot.setLabel('left', text='Power', units='dBm', unitPrefix=None) # initialize the y-axis of the plot
class R5500(Instrument): """ Driver for ThinkRF R5500 to run in the sweep mode. This modes allows arbitrary span instead of the native IBW of the SA. """ def __init__(self, name: str, address: str, **kwargs: Any) -> None: super().__init__(name, **kwargs) self.dut = WSA() self.addr = address self.dut.connect(address) self.dut.request_read_perm() # Basic settings self._rfemode = 'SH' self._fstart = 5e9 self._fstop = 6e9 self._rbw = 5e3 self._gain = 'high' self._attenuation = 0 self._average = 10 self._decimation = 1 self._reflevel = 0 self.triggered = False self._acquired_data = None self.add_parameter('rfe_mode', unit = '', initial_value= 'SH', label = 'Input Mode', get_cmd = self.get_rfe_mode, set_cmd = self.set_rfe_mode, get_parser = str) self.add_parameter('attenuation', unit = 'dB', initial_value = 0.0, label = 'attenuation', get_cmd = self.get_attenuation, set_cmd = self.set_attenuation, get_parser = float,) self.add_parameter('gain', unit = '', label = 'gain', get_cmd = self.get_psfm_gain, set_cmd = self.set_psfm_gain, get_parser = str) self.add_parameter('average', unit = '', label = 'average', get_cmd = self.get_average, set_cmd = self.set_average, get_parser = int) self.add_parameter('rbw', unit = 'Hz', label = 'resolution bandwidth', get_cmd = self.get_rbw, set_cmd = self.set_rbw , get_parser = float) self.add_parameter('f_start', unit='Hz', label='fstart', get_cmd= self.get_fstart, set_cmd= self.set_fstart, get_parser = float) self.add_parameter('f_stop', unit='Hz', label='fstop', get_cmd = self.get_fstop, set_cmd= self.set_fstop, get_parser = float) self.add_parameter('n_points', unit='', get_cmd= self.get_npoints, set_cmd= '', get_parser = int) self.add_parameter('freq_axis', unit='Hz', label='Frequency', parameter_class=Setpoints, startpar=self.f_start, stoppar=self.f_stop, npointspar=self.n_points, vals=Arrays(shape=(self.n_points.get_latest,))) self.add_parameter('spectrum', unit='dBm', setpoints=(self.freq_axis,), label='Noise power', parameter_class=SpectrumArray, vals=Arrays(shape=(self.n_points.get_latest,))) def get_npoints(self): ''' Configs the sweep and collects the data. Returns length of data for generating the setpoints. ''' fstart = self.f_start() fstop = self.f_stop() rbw = self.rbw() device_settings = { 'attenuator' : self.attenuation() } mode = self.rfe_mode() average = self.average() self.dut.reset() self.dut.psfm_gain(self._gain) self.dut.spp(1024) self.dut.ppb(4) self.dut.pll_reference('EXT') try: sweepdev = SweepDevice(self.dut) except TypeError: self.dut.abort() self.dut.flush() self.dut.disconnect() self.dut.connect(self.addr) self.dut.reset() self.dut.psfm_gain(self._gain) self.dut.spp(1024) self.dut.ppb(4) self.dut.pll_reference('EXT') finally: try: sweepdev = SweepDevice(self.dut) except TypeError: self.dut.connect(self.addr) self.dut.abort() self.dut.flush() self.dut.reset() self.dut.psfm_gain(self._gain) self.dut.spp(1024) self.dut.ppb(4) self.dut.pll_reference('EXT') sweepdev = SweepDevice(self.dut) sweepdev.real_device.flush_captures() fstart, fstop, spectrum = sweepdev.capture_power_spectrum(fstart=fstart, fstop=fstop, rbw=rbw, device_settings=device_settings, mode=mode, average = average) self._acquired_data = dict({'fstart':fstart, 'fstop' : fstop, 'spectrum' : spectrum, 'npts' : len(spectrum) }) self.f_start(fstart) self.f_stop(fstop) self.dut.sweep_stop() self.dut.abort() self.dut.flush_captures() return len(spectrum) def get_fstart( self ): return self._fstart def set_fstart( self, fstart ): self._fstart = fstart def get_fstop( self ): return self._fstop def set_fstop( self, fstop ): self._fstop = fstop def get_average( self ): return self._average def set_average( self, average ): self._average = average def get_rbw( self ): #TODO : update rbw from device return self._rbw def set_rbw(self, rbw): #TODO : inject rbw to device self._rbw = rbw def get_rfe_mode( self ): return self._rfemode def set_rfe_mode( self, rfemode ): self._rfemode = rfemode self.dut.rfe_mode(self._rfemode) def get_attenuation( self ): return self._attenuation def set_attenuation( self, atten ): self._attenuation = atten self.dut.attenuator( self._attenuation ) def get_psfm_gain( self ): return self._gain def set_psfm_gain( self, gain ): self._gain = gain self.dut.psfm_gain( self._gain )
def keyPressEvent(self, event): if event.text() == ';': cmd, ok = QtGui.QInputDialog.getText(win, 'Enter SCPI Command', 'Enter SCPI Command:') if ok: if '?' not in cmd: dut.scpiset(cmd) win = MainApplication(dut) win.resize(1000,600) win.setWindowTitle("PYRF FFT Plot Example") # initialize WSA configurations dut.reset() dut.request_read_perm() dut.freq(CENTER_FREQ) dut.decimation(DECIMATION) dut.attenuator(ATTENUATOR) dut.rfe_mode(RFE_MODE) BANDWIDTH = dut.properties.FULL_BW[RFE_MODE] # initialize plot fft_plot = win.addPlot(title="Power Vs. Frequency") # initialize x-axes limits plot_xmin = (CENTER_FREQ) - (BANDWIDTH / 2) plot_xmax = (CENTER_FREQ) + (BANDWIDTH / 2) fft_plot.setLabel('left', text= 'Power', units = 'dBm', unitPrefix=None) # initialize the y-axis of the plot
class R550_wrapper(Instrument): ## wrapper around the pyRF API to use R550 with QCoDes def __init__(self, name: str, address: str, **kwargs: Any) -> None: super().__init__(name, **kwargs) self.dut = WSA() self.dut.connect(address) self.dut.reset() self.dut.request_read_perm() self._span = 5e6 self._RBW = 125e6 / (32 * 512) self._average = 1 self._decimation = 1 self._reflevel = 0 self._capture_mode = 'BLOCK' self._freqlist = [] self._spectralist = [] # sweep capture is not implemented yet self.add_parameter('capture_mode', unit='', initial_value='BLOCK', vals=Enum('BLOCK', 'SWEEP'), label='Capture Mode', get_cmd=self.get_capture_mode, set_cmd=self.set_capture_mode, get_parser=str) self.add_parameter('rfe_mode', unit='', initial_value='SH', label='Input Mode', get_cmd=self.dut.rfe_mode, set_cmd=self.dut.rfe_mode, get_parser=str) self.add_parameter( 'attenuation', unit='dB', initial_value=0.0, label='attenuation', get_cmd=self.dut.attenuator, set_cmd=self.dut.attenuator, get_parser=float, ) self.add_parameter('gain', unit='', label='gain', get_cmd=self.dut.psfm_gain, set_cmd=self.dut.psfm_gain, get_parser=str) self.add_parameter('reflevel', unit='dBm', label='reference level', get_cmd=self.get_ref, set_cmd=self.set_ref, get_parser=float) self.add_parameter('average', unit='', label='average', get_cmd=self.get_avg, set_cmd=self.set_avg, get_parser=int) self.add_parameter( 'ppb', unit='', #initial_value = 1, label='packets/block', get_cmd=self.dut.ppb, set_cmd=self.dut.ppb, get_parser=int, ) self.add_parameter( 'spp', unit='', #initial_value = 32 * 512, label='samples/packet', get_cmd=self.dut.spp, set_cmd=self.dut.spp, get_parser=int, ) self.add_parameter( 'span', unit='Hz', label='span', # vals = Numbers(0,100e6), get_cmd=self.get_span, set_cmd=self.set_span, get_parser=float) #TODO : implement a function that automatically adjusts the RWB to the value closest to the one in the device properties list self.add_parameter( 'rbw', unit='Hz', # initial_value= 125e6 / (self.spp() * self.ppb), label='resolution bandwidth', # vals = Numbers(0,100e6), get_cmd=self.get_RBW, set_cmd=self.set_RBW, get_parser=float) self.add_parameter('f_center', unit='Hz', label='f center', vals=Numbers(0.1e9, 27e9), get_cmd=self.dut.freq, set_cmd=self.dut.freq, get_parser=float) self.add_parameter( 'f_start', # initial_value= 5.1e9, unit='Hz', label='f start', #vals=Numbers(0,1e3), get_cmd=lambda: self.f_center() - self.span() / 2, set_cmd='', get_parser=float) self.add_parameter( 'f_stop', unit='Hz', label='f stop', #initial_value=fstop, #vals=Numbers(1,1e3), get_cmd=lambda: self.f_center() + self.span() / 2, set_cmd='', get_parser=float) self.add_parameter( 'n_points', unit='', # initial_value=len(spectra_data), #vals=Numbers(1,1e3), get_cmd=self.get_npoints, set_cmd='', get_parser=int) self.add_parameter('freq_axis', unit='Hz', label='Frequency', parameter_class=GeneratedSetPoints, startparam=self.f_start, stopparam=self.f_stop, xpointsparam=self.n_points, vals=Arrays(shape=(self.n_points.get_latest, ))) self.add_parameter('spectrum', unit='dBm', setpoints=(self.freq_axis, ), label='Noise power', parameter_class=SpectrumArray, vals=Arrays(shape=(self.n_points.get_latest, ))) ## helper functions def filter_span(self, fullFreq, fullSpectra): ''' args: fullFreq : frequency array returned by block capture fullSpectra : power spectrum array returned by block capture returns: frequency and spectra filtered according to the start and stop frequencies set on the device ''' freqfilter = (self.f_start() < fullFreq) & (fullFreq < self.f_stop()) spectra = fullSpectra[freqfilter] freq = fullFreq[freqfilter] self._freqlist = freq self._spectra = spectra return freq, spectra ## setters and getters (maybe there's a way of avoiding these?) def get_npoints(self): ''' get the number of points by calling capture function and filtering to start/stop frequencies, if required ''' if (self._capture_mode == 'BLOCK'): fstart, fstop, spectra = capture_spectrum(self.dut, self.rbw(), self.average()) flist = np.linspace(fstart, fstop, len(spectra)) filteredFreq, filteredSpectra = self.filter_span(flist, spectra) return len(filteredSpectra) if (self._capture_mode == 'SWEEP'): #TODO : calling center frequency function (or any function that returns numeric data) after sweepdev creation gives error, find a workaround scan_startf = self.f_start() scan_stopf = self.f_stop() atten = self.attenuation() rbw = self.rbw() mode = self.rfe_mode() avg = self._average() sweepdev = SweepDevice(self.dut) fstart, fstop, spectra = sweepdev.capture_power_spectrum( scan_startf, scan_stopf, rbw, {'attenuator': atten}, mode=mode, niter=1, average=avg) self._freqlist = np.linspace(fstart, fstop, len(spectra)) self._spectra = spectra return (len(spectra)) # def set_npoints(self,n): # self._RBW = 0.81 * self._span()/n ## approximate correction to compensate for usable bins calculation def get_avg(self): return self._average def set_avg(self, avg): self._average = avg def get_span(self): return self._span def set_span(self, bw): self._span = bw def get_RBW(self): return self._RBW def set_RBW(self, rbw): self._RBW = rbw def get_ref(self): return self._reflevel def set_ref(self, ref): self._reflevel = ref def set_capture_mode(self, mode): self._capture_mode = mode def get_capture_mode(self): return self._capture_mode