def open_device(self, name, ok): if not ok: self._main_window.show() return if self.dut: self.dut.disconnect() self._main_window.show() dut = WSA(connector=TwistedConnector(self._reactor)) yield dut.connect(name) self.dev_set = { 'attenuator': 0, 'freq': 2450e6, 'decimation': 1, 'fshift': 0, 'rfe_mode': 'SH', 'iq_output_path': 'DIGITIZER' } self.dut = dut self.dut_prop = self.dut.properties self.bandwidth = self.dut_prop.FULL_BW[self.dev_set['rfe_mode']] self.rbw = 125000000 / SAMPLE_VALUES[3] self.enable_mhold = False self.mhold = [] self.cap_dut = CaptureDevice(dut, async_callback=self.receive_capture, device_settings=self.dev_set) self.initUI() self.enable_controls() self.read_block()
def open_device(self, name): if self.dut: self.dut.disconnect() dut = WSA(connector=TwistedConnector(self._reactor)) yield dut.connect(name) if hasattr(dut.properties, 'MINIMUM_FW_VERSION') and parse_version( dut.fw_version) < parse_version(dut.properties.MINIMUM_FW_VERSION): too_old = QtGui.QMessageBox() too_old.setText('Your device firmware version is {0}' ' but this application is expecting at least version' ' {1}. Some features may not work properly'.format( dut.fw_version, dut.properties.MINIMUM_FW_VERSION)) too_old.exec_() if self._output_file: dut.set_capture_output(self._output_file) self.dut = dut self.plot_state = gui_config.PlotState(dut.properties) self.dut_prop = self.dut.properties self.sweep_dut = SweepDevice(dut, self.receive_sweep) self.cap_dut = CaptureDevice(dut, async_callback=self.receive_capture, device_settings=self.plot_state.dev_set) self._dev_group.configure(self.dut.properties) self.enable_controls() cu._select_center_freq(self) self._rbw_box.setCurrentIndex(3) self._plot.const_window.show() self._plot.iq_window.show() self.plot_state.enable_block_mode(self) self.read_block()
def open_device(self, name, ok): if not ok: self.show() return self.show() dut = WSA(connector=TwistedConnector(self._get_reactor())) yield dut.connect(name) self._device_address = name self.setWindowTitle('PyRF RTSA %s Connected To: %s' % (__version__, name)) if hasattr(dut.properties, 'MINIMUM_FW_VERSION') and parse_version( dut.fw_version) < parse_version( dut.properties.MINIMUM_FW_VERSION): too_old = QtGui.QMessageBox() too_old.setText( 'Your device firmware version is {0}' ' but this application is expecting at least version' ' {1}. Some features may not work properly'.format( dut.fw_version, dut.properties.MINIMUM_FW_VERSION)) too_old.exec_() self.controller.set_device(dut) self.record_action.setDisabled(False) self.stop_action.setDisabled(True) self.device_info.setDisabled(False)
def open_device(self, name, ok): if not ok: self._main_window.show() return if self.dut: self.dut.disconnect() self._main_window.show() dut = WSA(connector=TwistedConnector(self._reactor)) yield dut.connect(name) self.dev_set = { 'attenuator': 1, 'freq':2450e6, 'decimation': 1, 'fshift': 0, 'rfe_mode': 'SH', 'iq_output_path': 'DIGITIZER'} self.rbw = RBW_VALUES[4] self.enable_mhold = False self.mhold = [] self.dut = dut self.dut_prop = self.dut.properties self.cap_dut = CaptureDevice(dut, async_callback=self.receive_capture, device_settings=self.dev_set) self.initUI() self.enable_controls() self.read_block()
def open_device(self, name, ok): if not ok: self.show() return self.show() dut = WSA(connector=TwistedConnector(self._get_reactor())) yield dut.connect(name) self.setWindowTitle('PyRF RTSA %s Connected To: %s' % (__version__ , name)) if hasattr(dut.properties, 'MINIMUM_FW_VERSION') and parse_version( dut.fw_version) < parse_version(dut.properties.MINIMUM_FW_VERSION): too_old = QtGui.QMessageBox() too_old.setText('Your device firmware version is {0}' ' but this application is expecting at least version' ' {1}. Some features may not work properly'.format( dut.fw_version, dut.properties.MINIMUM_FW_VERSION)) too_old.exec_() self.controller.set_device(dut) self.record_action.setDisabled(False) self.stop_action.setDisabled(True)
def __init__(self, ip_address): self._driver = WSA() self._driver.connect(ip_address) self._numpts = 4096 self._center_MHz = 2447. self._span_MHz = 125. self._start_MHz = self._center_MHz - (self._span_MHz / 2) self._stop_MHz = self._center_MHz + (self._span_MHz / 2) self._frequencies_MHz = np.linspace(self._start_MHz, self._stop_MHz, self._numpts) self._last_power_spectrum_dBm = None self._capture_history_len = 2000 self.capture_history = WaterfallModel(self._frequencies_MHz, self._capture_history_len) self._capture_count = 0 self._capture_timer = QtCore.QTimer( ) #for app-side acquisition control self._capture_timer.timeout.connect(self._on_capture_timer) self.capturing = False self.reset()
def __init__(self, ip_address): self._driver = WSA() self._driver.connect(ip_address) self._numpts = 4096 self._center_MHz = 2447. self._span_MHz = 125. self._start_MHz = self._center_MHz - (self._span_MHz / 2) self._stop_MHz = self._center_MHz + (self._span_MHz / 2) self._frequencies_MHz = np.linspace(self._start_MHz, self._stop_MHz, self._numpts) self._last_power_spectrum_dBm = None self._capture_history_len = 2000 self.capture_history = WaterfallModel(self._frequencies_MHz, self._capture_history_len) self._capture_count = 0 self._capture_timer = QtCore.QTimer() #for app-side acquisition control self._capture_timer.timeout.connect(self._on_capture_timer) self.capturing = False self.reset()
#!/usr/bin/env python import sys from pyrf.devices.thinkrf import WSA # connect to wsa dut = WSA() dut.connect(sys.argv[1]) # setup test conditions dut.reset() dut.freq(2450e6) peak_lost = dut.peakfind(n = 5) for peak in peak_lost : print peak
# return peak frequency and amplitude return (pfreq, pamp) # open faillog if log_errors: fp = open("mcfail.log", "a") # connect to siggen sg = N5183("10.126.110.19") sg.freq(2400e6) sg.amplitude(pin) sg.output(1) # connect to wsa dut = WSA() dut.connect(sys.argv[1]) dut.scpiset("*RST") dut.flush() # create sweep device sd = SweepDevice(dut) # test for a long time t = 0 while t < numtrials: # choose random fstart req_fstart = int(random.random() * 8e9) # choose random fstop
from pyrf.sweep_device import SweepDevice import sys import time import math import numpy as np # declare sweep constants START_FREQ = 2300e6 STOP_FREQ = 2400e6 RBW = 10e3 # connect to WSA, and initialize device init_time = time.time() dut = WSA() dut.connect(sys.argv[1]) dut.flush() dut.abort() dut.request_read_perm() dut.reset() sd = SweepDevice(dut) init_time = time.time() - init_time # capture the sweep data while True: capture_time = time.time() fstart, fstop, spectra_data = sd.capture_power_spectrum(START_FREQ,
#!/usr/bin/env python import sys from pyrf.devices.thinkrf import WSA from pyrf.config import SweepEntry from pyrf.numpy_util import compute_fft from pyrf.util import collect_data_and_context import time SAMPLES = 2**20 M = 1000000 # connect to wsa dut = WSA() dut.connect(sys.argv[1]) if len(sys.argv) > 2: ppb = int(sys.argv[2]) else: ppb = 1 # setup test conditions dut.reset() dut.request_read_perm() for spp in [min(2**i, 2**16-16) for i in range(7, 17)]: dut.abort() dut.flush() dut.sweep_clear() s = SweepEntry( fstart=100 * M,
class MyWifiWSA(object): """A cheap/simple/incomplete WSA instrument abstraction. Hides driver internals that people using the device as a spectrum analyzer may not care about. """ def __init__(self, ip_address): super(MyWifiWSA, self).__init__() self._init_hardware(ip_address) self._numpts = 4096 self._center_MHz = 2447. self._span_MHz = 125. self._start_MHz = self._center_MHz - (self._span_MHz / 2) self._stop_MHz = self._center_MHz + (self._span_MHz / 2) self._frequencies_MHz = np.linspace(self._start_MHz, self._stop_MHz, self._numpts) self._last_power_spectrum_dBm = None self._capture_history_len = 2000 self.capture_history = WaterfallModel(self._frequencies_MHz, self._capture_history_len) self._capture_count = 0 self._capture_timer = QtCore.QTimer() #for app-side acquisition control self._capture_timer.timeout.connect(self._on_capture_timer) self.capturing = False self.reset() def _init_hardware(self, ip_address): self._driver = WSA() self._driver.connect(ip_address) def reset(self): """Sets a known start state.""" #Set our app-specific reset state (802.11 range) center_frequency_MHz = 2447 self._reset_hardware() def _reset_hardware(self): drv = self._driver drv.reset() drv.request_read_perm() drv.freq(self._center_MHz) drv.decimation(1) # do decimate drv.attenuator(0) # don't attenuate def start_continuous_capture(self, capture_interval_s): #It would be nice to be able to set the capture interval on the #device itself so that we aren't slave to lagging issues on the OS. #We could also just calculate the number of pts required to achieve #the required capture interval (or close enough), and have the #resulting frequiency grid, res bw, et al adjust accordingly. But... #clearly out of scope for this cheap abstraction. #Timing will be managed by a QTimer in this case. As a result, #capture_interval_s is really done on best effort (although the #QTimer drivign it does make reasonable efforts to sync timing). self._capture_timer.stop() self._capture_timer.start(1000 * capture_interval_s) self.capturing = True def stop_continuous_capture(self): self.capturing = False self._capture_timer.stop() def acquire_single_power_spectrum(self): STAIRS_MODE = False self._capture_count += 1 if STAIRS_MODE: STAIR_WIDTH = 50 stair_start = self._capture_count % self._numpts stair_start = np.floor(stair_start / STAIR_WIDTH) * STAIR_WIDTH stair_stop = stair_start + STAIR_WIDTH ps_dBm = np.zeros(self._numpts) - 80 ps_dBm[stair_start:stair_stop] = -20 timestamp_s = self._capture_count else: drv = self._driver vrt_data, context = read_data_and_context(drv, self._numpts) assert isinstance(vrt_data, pyrf.vrt.DataPacket) ps_dBm = compute_fft(drv, vrt_data, context, convert_to_dbm=True) #Accumulate history... timestamp_s = calc_vrt_sample_time_s(vrt_data) self.capture_history.add_row(ps_dBm, timestamp_s = timestamp_s) self._last_power_spectrum_dBm = ps_dBm return ps_dBm def _on_capture_timer(self): #grab a spectrum! The historical model will be updated and events can #be driven from that directly. self.acquire_single_power_spectrum()
if event.text() == ';': cmd, ok = QtGui.QInputDialog.getText(win, 'Enter SCPI Command', 'Enter SCPI Command:') if ok: if '?' not in cmd: dut.scpiset(cmd) # get RTSA device IP if len(sys.argv) > 1: ip = sys.argv[1] else: ip, ok = QtGui.QInputDialog.getText(win, 'Open Device', 'Enter a hostname or IP address:') # connect to an RTSA device dut = WSA() dut.connect(ip) # initialize RTSA configurations dut.reset() dut.request_read_perm() dut.freq(CENTER_FREQ) dut.decimation(DECIMATION) dut.attenuator(ATTENUATOR) dut.rfe_mode(RFE_MODE) # initialize plot win = MainApplication(dut) win.resize(1000,600) win.setWindowTitle("PYRF FFT Plot Example - " + ip) fft_plot = win.addPlot(title="Power Vs. Frequency")
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, )))
#!/usr/bin/env python import sys from pyrf.devices.thinkrf import WSA # connect to wsa dut = WSA() dut.connect(sys.argv[1]) # setup test conditions # dut.reset() # dut.freq(2450e6) # dut.spp(32768) print dut.measure_noisefloor(rbw = 100e3, average = 130)
class MyWifiWSA(object): """A cheap/simple/incomplete WSA instrument abstraction. Hides driver internals that people using the device as a spectrum analyzer may not care about. """ def __init__(self, ip_address): super(MyWifiWSA, self).__init__() self._init_hardware(ip_address) self._numpts = 4096 self._center_MHz = 2447. self._span_MHz = 125. self._start_MHz = self._center_MHz - (self._span_MHz / 2) self._stop_MHz = self._center_MHz + (self._span_MHz / 2) self._frequencies_MHz = np.linspace(self._start_MHz, self._stop_MHz, self._numpts) self._last_power_spectrum_dBm = None self._capture_history_len = 2000 self.capture_history = WaterfallModel(self._frequencies_MHz, self._capture_history_len) self._capture_count = 0 self._capture_timer = QtCore.QTimer( ) #for app-side acquisition control self._capture_timer.timeout.connect(self._on_capture_timer) self.capturing = False self.reset() def _init_hardware(self, ip_address): self._driver = WSA() self._driver.connect(ip_address) def reset(self): """Sets a known start state.""" #Set our app-specific reset state (802.11 range) center_frequency_MHz = 2447 self._reset_hardware() def _reset_hardware(self): drv = self._driver drv.reset() drv.request_read_perm() drv.freq(self._center_MHz) drv.decimation(1) # do decimate drv.attenuator(0) # don't attenuate def start_continuous_capture(self, capture_interval_s): #It would be nice to be able to set the capture interval on the #device itself so that we aren't slave to lagging issues on the OS. #We could also just calculate the number of pts required to achieve #the required capture interval (or close enough), and have the #resulting frequiency grid, res bw, et al adjust accordingly. But... #clearly out of scope for this cheap abstraction. #Timing will be managed by a QTimer in this case. As a result, #capture_interval_s is really done on best effort (although the #QTimer drivign it does make reasonable efforts to sync timing). self._capture_timer.stop() self._capture_timer.start(1000 * capture_interval_s) self.capturing = True def stop_continuous_capture(self): self.capturing = False self._capture_timer.stop() def acquire_single_power_spectrum(self): STAIRS_MODE = False self._capture_count += 1 if STAIRS_MODE: STAIR_WIDTH = 50 stair_start = self._capture_count % self._numpts stair_start = np.floor(stair_start / STAIR_WIDTH) * STAIR_WIDTH stair_stop = stair_start + STAIR_WIDTH ps_dBm = np.zeros(self._numpts) - 80 ps_dBm[stair_start:stair_stop] = -20 timestamp_s = self._capture_count else: drv = self._driver vrt_data, context = read_data_and_context(drv, self._numpts) assert isinstance(vrt_data, pyrf.vrt.DataPacket) ps_dBm = compute_fft(drv, vrt_data, context, convert_to_dbm=True) #Accumulate history... timestamp_s = calc_vrt_sample_time_s(vrt_data) self.capture_history.add_row(ps_dBm, timestamp_s=timestamp_s) self._last_power_spectrum_dBm = ps_dBm return ps_dBm def _on_capture_timer(self): #grab a spectrum! The historical model will be updated and events can #be driven from that directly. self.acquire_single_power_spectrum()
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
def _init_hardware(self, ip_address): self._driver = WSA() self._driver.connect(ip_address)
# setup my graph fig = figure(1) xvalues = np.linspace(fstart, fstop, len(bins)) xlabel("Frequency") ylabel("Amplitude") # plot something plot(xvalues, bins, color='blue') # show graph show() reactor.callLater(2**-4, reactor.stop) @defer.inlineCallbacks def start_sweep(v): global sd sd = SweepDevice(dut, plot_sweep) fstart, fstop, spectral_data = sd.capture_power_spectrum( START_FREQ, STOP_FREQ, RBW, {'attenuator': 0}) # configure RTSA to use twisted dut = WSA(connector=TwistedConnector(reactor)) # connect to RTSA and configure d = dut.connect(sys.argv[1]) d.addCallbacks(start_sweep, twisted.python.log.err) reactor.run()
PPB = 1 RBW = 125e6 / (SPP * PPB * 2) # 125 MHz is the sampling rate AVERAGE = 100 DECIMATION = 1 # no decimation ATTENUATION = 0 GAIN = 'HIGH' TRIGGER_SETTING = { 'type': 'NONE', 'fstart': (CENTER_FREQ - 0e6), # some value 'fstop': (CENTER_FREQ + 0e6), # some value 'amplitude': -100 } REFLEVEL = None # initialize an RTSA (aka WSA) device handle dut = WSA() dut.connect('169.254.16.253') #%% initialize RTSA configurations dut.reset() dut.request_read_perm() dut.rfe_mode(RFE_MODE) dut.freq(CENTER_FREQ) dut.attenuator(ATTENUATION) dut.psfm_gain(GAIN) dut.trigger(TRIGGER_SETTING) startT = time.time() fstart, fstop, pow_data = capture_spectrum(dut, RBW, AVERAGE, DECIMATION) freq_range = np.linspace(fstart, fstop, len(pow_data))
from pyrf.sweep_device import SweepDevice import sys import time import math import numpy as np # declare sweep constants START_FREQ = 2300e6 STOP_FREQ = 2400e6 RBW = 10e3 # connect to WSA, and initialize device init_time = time.time() dut = WSA() dut.connect('10.126.110.107') dut.flush() dut.abort() dut.request_read_perm() dut.reset() dut.var_attenuator(0) sd = SweepDevice(dut) init_time = time.time() - init_time # capture the sweep data while True: capture_time = time.time()
import numpy as np from pyrf.devices.thinkrf import WSA from pyrf.sweep_device import SweepDevice # plot constants ATTENUATOR = 0 DECIMATION = 1 RFE_MODE = 'SH' # declare sweep constants START_FREQ = 150e6 STOP_FREQ = 200e6 RBW = 48e3 # connect to WSA device dut = WSA() win = pg.GraphicsWindow() win.resize(1000, 600) win.setWindowTitle("PYRF FFT Plot Example") ip = '10.126.110.103' dut.connect(ip) # initialize WSA configurations dut.flush() dut.abort() dut.request_read_perm() dut.reset() sd = SweepDevice(dut)
class MainApplication(pg.GraphicsWindow): def __init__(self, dut): super(MainApplication, self).__init__() self.dut = dut 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) # connect to WSA device 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()
def __init__(self, dut): super(MainApplication, self).__init__() self.dut = dut # use ';' to do SCPI command on the run 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) # initialize an RTSA (aka WSA) device handle dut = WSA() win = MainApplication(dut) # get device's IP and connect 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 RTSA configurations dut.reset() dut.request_read_perm() dut.psfm_gain(GAIN)
# Freq: Provide the WSA with a centre frequency in GHz (eg 1.3) # File: Give a file name (eg Test) # Deg: Increments in degrees so that you know what the file is doing # # If connected directly to PC, no IP argument is required # ########################################################################## import sys import time from pyrf.sweep_device import SweepDevice from pyrf.devices.thinkrf import WSA from pyrf.devices.thinkrf import discover_wsa from datetime import datetime dut = WSA() IP_found = 0 # Read command line for IP (WSA5000 hostname: thinkrf.uct.ac.za) # Used to discover the IP of the device if directly connected try: wsas_on_network = discover_wsa() for wsa in wsas_on_network: findIP = wsa["HOST"] IP_found = 1 # Find the device on network given user inputted IP except: if IP_found == 1: dut.connect(findIP) print "Connected to: ", findIP
if len(sys.argv) >= 2: fstart = float(sys.argv[2]) if len(sys.argv) >= 3: fstop = float(sys.argv[3]) if len(sys.argv) >= 4: rbw = float(sys.argv[4]) if len(sys.argv) >= 5: fin = float(sys.argv[5]) if save_data: reqstart = fstart reqstop = fstop reqrbw = rbw # connect to wsa dut = WSA() dut.connect(ip) dut.scpiset("*RST") dut.flush() # create sweep device sd = SweepDevice(dut) sd.logtype = 'PRINT' # setup siggen if fin: sg = N5183("10.126.110.19") sg.amplitude(pin) sg.freq(fin) sg.output(1) time.sleep(0.05)
#%% RFE_MODE = 'SH' START_FREQ = 5.5e9 STOP_FREQ = 6.5e9 CENTER_FREQ = 6e9 SPP = 32 * 512 PPB = 1 RBW = 125e6 / (SPP * PPB * 24) # 125 MHz is the sampling rate ATTENUATION = 20 GAIN = 'HIGH' AVERAGE = 50 DECIMATION = 1 # no decimation span = STOP_FREQ - START_FREQ #%% dut = WSA() dut.connect('169.254.16.253') dut.reset() #dut.request_read_perm() dut.psfm_gain(GAIN) #%% sweepdev = SweepDevice( dut ) ## numeric values start being gibberish after this point, but the spectrum capture works fine #%% #avglist = [1,5,10,50,100,500,1000,5000,10000] #timelist = [] #for avg in avglist: startT = time() fstart, fstop, spectra_data = sweepdev.capture_power_spectrum(
points = list[start:stop] if list[n] > list_average: new_list.append(list[n]) else: new_list.append(np.mean(points)) return new_list # declare sweep constants START_FREQ = 50e6 STOP_FREQ = 27e9 RBW = 100e3 VBW = 30e3 # connect to wsa dut = WSA() dut.connect(sys.argv[1]) dut.request_read_perm() # declare sweep device sd = SweepDevice(dut) # read the spectral data fstart, fstop, spectra_data = sd.capture_power_spectrum(START_FREQ, STOP_FREQ, RBW, {'attenuator':0}) # apply the VBW algorith spectra_data = smooth(spectra_data, max(1, RBW/VBW)) # calculate the channel power linear = np.power(10, np.divide(spectra_data,20)) channel_power = 10 * np.log10(np.sum(np.square(linear)))
#!/usr/bin/env python import sys from pyrf.devices.thinkrf import WSA # connect to wsa dut = WSA() dut.connect(sys.argv[1]) # setup test conditions # dut.reset() # dut.freq(2450e6) # dut.spp(32768) print dut.measure_noisefloor(rbw=100e3, average=130)
import pyqtgraph as pg import sys import numpy as np from pyrf.devices.thinkrf import WSA from pyrf.util import read_data_and_context from pyrf.numpy_util import compute_fft # plot constants CENTER_FREQ = 2450 * 1e6 SAMPLE_SIZE = 1024 ATTENUATOR = 1 DECIMATION = 1 RFE_MODE = 'ZIF' # connect to WSA device dut = WSA() ip = sys.argv[1] dut.connect(ip) class MainApplication(pg.GraphicsWindow): def __init__(self, dut): super(MainApplication, self).__init__() self.dut = dut 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:
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 )
#!/usr/bin/env python import sys from pyrf.devices.thinkrf import WSA # connect to wsa dut = WSA() dut.connect(sys.argv[1]) # setup test conditions dut.reset() dut.request_read_perm() dut.freq(2450e6) # capture 1 packet dut.capture(1024, 1) # read until I get 1 data packet while not dut.eof(): pkt = dut.read() if pkt.is_data_packet(): break # print I/Q data into i and q for i, q in pkt.data: print "%d,%d" % (i, q)
from pyrf.sweep_device import SweepDevice import sys import time import math import numpy as np # declare sweep constants START_FREQ = 50e6 STOP_FREQ = 27000e6 RBW = 10e3 # connect to WSA, and initialize device init_time = time.time() dut = WSA() dut.connect(sys.argv[1]) dut.request_read_perm() dut.reset() dut.var_attenuator(0) sd = SweepDevice(dut) init_time = time.time() - init_time # capture the sweep data while True: capture_time = time.time() fstart, fstop, spectra_data = sd.capture_power_spectrum(START_FREQ, STOP_FREQ, RBW,
points = list[start:stop] if list[n] > list_average: new_list.append(list[n]) else: new_list.append(np.mean(points)) return new_list # declare sweep constants START_FREQ = 50e6 STOP_FREQ = 8e9 RBW = 100e3 VBW = 100e3 # connect to wsa dut = WSA() dut.connect(sys.argv[1]) dut.request_read_perm() # declare sweep device sd = SweepDevice(dut) # read the spectral data fstart, fstop, spectra_data = sd.capture_power_spectrum(START_FREQ, STOP_FREQ, RBW, {'attenuator':0}) # apply the VBW algorith spectra_data = smooth(spectra_data, max(1, RBW/VBW)) # calculate the channel power linear = np.power(10, np.divide(spectra_data,20)) channel_power = 10 * np.log10(np.sum(np.square(linear)))
xlabel("Frequency") ylabel("Amplitude") # plot something plot(xvalues, bins, color='blue') # show graph show() reactor.callLater(2 ** -4, reactor.stop) def start_sweep(v): global sd sd = SweepDevice(dut, plot_sweep) sd.capture_power_spectrum(0e6, 20000e6, 5e6, {'attenuator': 0 }) # connect to wsa dut = WSA(connector=TwistedConnector(reactor)) d = dut.connect(sys.argv[1]) d.addCallbacks(start_sweep, twisted.python.log.err) reactor.run() print 'context_bytes_received', sd.context_bytes_received print 'data_bytes_received', sd.data_bytes_received print 'data_bytes_processed', sd.data_bytes_processed print 'martian_bytes_discarded', sd.martian_bytes_discarded print 'past_end_bytes_discarded', sd.past_end_bytes_discarded print 'fft_calculation_seconds', sd.fft_calculation_seconds print 'bin_collection_seconds', sd.bin_collection_seconds
from pyrf.util import capture_spectrum, collect_data_and_context from time import time import matplotlib.pyplot as plt from pyrf.vrt import vrt_packet_reader import time #%% RFE_MODE = 'ZIF' CENTER_FREQ = 5.7000e9 + 0.000e6 SPP = int(2**8) PPB = 1 ATTENUATION = 0 GAIN = 'HIGH' DECIMATION = 0 # no decimation dut = WSA() dut.connect('169.254.16.253') dut.reset() dut.request_read_perm() dut.flush() dut.pll_reference('EXT') dut.rfe_mode(RFE_MODE) dut.freq(CENTER_FREQ) dut.decimation(DECIMATION) dut.spp(SPP) dut.ppb(PPB) dut.flush()
#!/usr/bin/env python import sys from pyrf.devices.thinkrf import WSA from pyrf.config import SweepEntry from pyrf.numpy_util import compute_fft from pyrf.util import collect_data_and_context import time SAMPLES = 2**20 M = 1000000 # connect to wsa dut = WSA() dut.connect(sys.argv[1]) if len(sys.argv) > 2: ppb = int(sys.argv[2]) else: ppb = 1 # setup test conditions dut.reset() dut.request_read_perm() for spp in [min(2**i, 2**16-16) for i in range(9, 17)]: dut.abort() dut.flush() dut.sweep_clear() s = SweepEntry( fstart=100 * M, fstop=7900 * M, fstep=100 * M,
RFE_MODE = 'SH' frange = 100e3 START_FREQ = 5.70e9 - frange STOP_FREQ = 5.70e9 + frange # CENTER_FREQ = 6e9 SPP = 32 * 512 PPB = 32 RBW = 125e6 / (SPP * PPB) # 125 MHz is the sampling rate ATTENUATION = 0 GAIN = 'HIGH' AVERAGE = 10 DECIMATION = 1 # no decimation span = STOP_FREQ - START_FREQ dut = WSA() addr = '169.254.16.253' dut.connect(addr) # dut.reset() #%% dut.request_read_perm() dut.psfm_gain(GAIN) dut.spp(SPP) dut.ppb(PPB) dut.pll_reference('EXT') #%% sweepdev = SweepDevice( dut ) ## numeric values start being gibberish after this point, but the spectrum capture works fine
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,)))
#!/usr/bin/env python import sys from pyrf.devices.thinkrf import WSA from pyrf.connectors.twisted_async import TwistedConnector from twisted.internet import reactor, defer import twisted.python.log # connect to wsa dut = WSA(connector=TwistedConnector(reactor)) @defer.inlineCallbacks def show_i_q(): yield dut.connect(sys.argv[1]) # setup test conditions yield dut.reset() yield dut.request_read_perm() yield dut.freq(2450e6) yield dut.decimation(0) dut.connector.vrt_callback = receive_vrt # capture 1 packet yield dut.capture(1024, 1) def receive_vrt(packet): # read until I get 1 data packet if not packet.is_data_packet(): return
import numpy as np from pyrf.devices.thinkrf import WSA from pyrf.util import read_data_and_context from pyrf.numpy_util import compute_fft # plot constants CENTER_FREQ = 2450 * 1e6 SAMPLE_SIZE = 1024 ATTENUATOR = 1 DECIMATION = 1 RFE_MODE = 'ZIF' # connect to WSA device dut = WSA() ip = sys.argv[1] dut.connect(ip) class MainApplication(pg.GraphicsWindow): def __init__(self, dut): super(MainApplication, self).__init__() self.dut = dut 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:
# # This script takes in 3 arguments, namely: IP, Freq, File # IP: Provide the IP for the WSA5000 (eg 137.258.131.247) # Freq: Provide the WSA with a centre frequency in GHz (eg 1.3) # File: Give a file name (eg Test) # ########################################################################## #Used to run the ThinkRF import sys import time from pyrf.sweep_device import SweepDevice from pyrf.devices.thinkrf import WSA from datetime import datetime from pyrf.devices.thinkrf import discover_wsa dut = WSA() #Used to run GUI import os from Tkinter import * import tkMessageBox,tkFileDialog #Declare global variables global counter counter = 0 global newName newName = "" fail = 0 global success success = "Connected!" global errorMessage
def __init__(self, dut): super(MainApplication, self).__init__() self.dut = dut # to do SCPI command on the run 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) # initialize an RTSA (aka WSA) device handle dut = WSA() win = MainApplication(dut) # get device's IP and connect 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 RTSA configurations dut.reset() dut.request_read_perm() dut.rfe_mode(RFE_MODE) dut.freq(CENTER_FREQ)