Unfortunately, Python is the only programming language I know. And I somehow difficult to imagine how without delay delays frequency tuning and continuous reading. I think that the NUM_AND_DONE mode will help me, but I do not know how to insist on it correctly and whether my reasoning on this is correct. Can you tell me some way out of this situation? I think I'm not the first to want to implement such a project on Ettus boards.
ср, 29 мая 2019 г. в 22:56, Marcus D. Leech via USRP-users < usrp-users@lists.ettus.com>: > On 05/29/2019 03:29 AM, Ivan Zahartchuk via USRP-users wrote: > > > > Yes, I expanded the buffer as suggested in the driver. I made a test file > for working with the board, here is its code. > > import uhdimport numpy as npfrom uhd import libpyuhd as libimport timeimport > scipy.signal as signalimport pyqtgraph as pg > pw = pg.plot()import time > > num_samps=363*5usrp = uhd.usrp.MultiUSRP('') > usrp.set_rx_subdev_spec(uhd.usrp.SubdevSpec('A:0'))print(usrp.get_pp_string()) > usrp.set_rx_rate(25e6)print(usrp.get_rx_rate()/1e6) > > stream_args=uhd.usrp.StreamArgs("fc32",'sc16') > stream_args.channels=[0] > rx_streamer=usrp.get_rx_stream(stream_args) > stream_cmd=uhd.types.StreamCMD(uhd.types.StreamMode.start_cont) > stream_cmd.num_samps=num_samps > stream_cmd.stream_now=Falseusrp.set_time_now(uhd.types.TimeSpec(0.0)) > stream_cmd.time_spec=uhd.types.TimeSpec(0.001) > rx_streamer.issue_stream_cmd(stream_cmd) > md = uhd.types.RXMetadata() > buffer_samps = rx_streamer.get_max_num_samps() > recv_buffer = np.zeros((len([0]), buffer_samps), dtype=np.complex64) > result = np.empty((len([0]), num_samps), dtype=np.complex64) > > def fft_slices(x): > # x = self.butter_bandpass_filter(x, -12.5e6, 12.5e6, 100e6, > order=6) window = signal.hanning(363*5) > fx = np.fft.fftshift(np.fft.fft(window[np.newaxis, :] * x, axis=1)) > > Pxx = np.abs(fx) ** 2 / (np.abs(window) ** 2).sum() > Pxx[:, 1:-1] *= 2 Pxx = 20 * np.log10(Pxx ** 0.5) > return Pxxdef fft_test(x): > > sample_freq,power=signal.welch(x,fs=25e6,window="hamm", > nperseg=num_samps,scaling="spectrum") > power=np.fft.fftshift(power)/1.5 return 10 * np.log10(power) > > > > while True: > > result = np.empty((len([0]), num_samps), dtype=np.complex64) > k = uhd.types.TuneRequest(np.random.randint(900e6, 1000e6)) > usrp.set_rx_freq(k) > while usrp.get_rx_sensor("lo_locked").to_bool() != True: > continue #print(usrp.get_rx_freq()) recv_samps = 0 while > recv_samps < num_samps: > > samps = rx_streamer.recv(recv_buffer, md) > time.sleep(0.001) > > if md.error_code != lib.types.rx_metadata_error_code.none: > print(md.strerror()) > if samps: > real_samps = min(num_samps - recv_samps, samps) > result[:, recv_samps:recv_samps + real_samps] = recv_buffer[:, > 0:real_samps] > recv_samps += real_samps > usrp.set_time_now(uhd.types.TimeSpec(0.0)) > stream_cmd.time_spec = uhd.types.TimeSpec(0.001) > rx_streamer.issue_stream_cmd(stream_cmd) > > k1=fft_test(result).ravel() > > if str(k1[0]) == 'nan': > print(k1[0]) > else: > pw.plot(k1, clear=True) > pg.QtGui.QApplication.processEvents() > > But as far as I still understand, in this case I open a continuous stream of > reading. And I would like to read samples on request since I need to tune the > frequency and type an array with several subranges. > > def test_reciev_2(self, freq, bandwich): > #complex_buffs = np.empty((len([0]), self.samples * len(freq))) buffs > = np.empty((len([0]), self.samples * len(freq))) > result = np.empty((len([0]), self.samples), dtype=np.complex64) > > for i, freqq in enumerate(freq): > > > # self.usrp.set_rx_rate(bandwich[i]) k = > uhd.types.TuneRequest(freqq) > # k.args(uhd.types.device_addr("mode_n=integer")) > self.usrp.set_rx_freq(k,0) > > self.streamer_rx.issue_stream_cmd(self.stream_cmd) > while self.usrp.get_rx_sensor("lo_locked").to_bool() != True: > continue recv_samps = 0 while recv_samps < > self.samples: > > samps = self.streamer_rx.recv(self.recv_buff, self.metadata_rx) > if self.metadata_rx.error_code != > lib.types.rx_metadata_error_code.none: > print(self.metadata_rx.strerror()) > if samps: > real_samps = min(self.samples - recv_samps, samps) > result[:, recv_samps:recv_samps + real_samps] = > self.recv_buff[:, 0:real_samps] > recv_samps += real_samps > # print (self.usrp.get_rx_sensor('rssi')) # > print(self.streamer_rx.get_max_num_samps()) # > self.stream_cmd.time_spec = lib.types.time_spec(0) > #self.stream_cmd.stream_now = False #self.stream_cmd = > lib.types.stream_cmd(lib.types.stream_mode.stop_cont) > #self.streamer_rx.issue_stream_cmd(self.stream_cmd) while samps: > samps = self.streamer_rx.recv(self.recv_buff, self.metadata_rx) > > #complex_buffs = np.append(complex_buffs, result).ravel() # > correct_result=result #correct_result_1 = result - > (np.mean(result.real) + np.mean(result.imag) * 1j) # > correct_result.real=result.real-np.mean(result.real) # > correct_result.imag = result.imag - np.mean(result.imag) PSD = > self.fft_test(result) > > # PSD[8188:8202]=np.mean(PSD[8180:8188]) buffs[:, i * > value.samples:value.samples * i + value.samples] = PSD[:, 0:value.samples] > > return complex_buffs, buffs.ravel() # > np.append(buffs[value.samples:],buffs[:value.samples]) > > > You are going to need to reconsider your code structure. > > > (A) The Python API is *NOT* the way to process high-sample-rate data (and > 25Msps is high-sample-rate in this context) > (B) You intermingle tuning and (continuous) streaming in the same thread, > AND, insert small sleeps after receiving samples--at > 25Msps, every 1millisecond you aren't "paying attention" to the > receive stream, there's 25,000 samples building up. > Tuning takes a finite amount of time--it's a fundamentally analog > process, so several milliseconds of latency for tuning > is not unusual. > > > _______________________________________________ > USRP-users mailing list > USRP-users@lists.ettus.com > http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com >
_______________________________________________ USRP-users mailing list USRP-users@lists.ettus.com http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com