I want to retune the frequency of my USRP in Python during runtime. I
understand from usrp_spectrum_sense.py that I can just retune the USRP
during runtime, and that I need to allow for some tune_delay to make
that the samples corresponding to the old center frequency are
Is there any way to get a good estimate of tune_delay value? I want to
this as short as possible. (btw I’m using a USRP-N210 with WBX
daughterboard) Some trial and error gave me values around 50ms, but this
seems rather high compared to what I’ve read online.
Any hints are welcome!
yes, that seems rather high; but maybe you’re seeing the effects of the
DC offset removal filter. You can try to use use
set_auto_dc_offset(False) to make that faster .
However, usrp_spectrum_sense is pretty old, and hence can’t even make
use of stream tags on the GNU Radio side and timed commands on the USRP
side, so the lower boundary for delay is the two-way latency between
host and device – which can easily be in the order of tens of
I’d personally recommend just going ahead and reimplementing this:
- Use the USRP source as usual
- use set_time_now (if you don’t have a time/PPS source),
- issue two or three timed tuning commands right at the start
(set_command_time, set_rx_freq, clear_command_time)
- write a python block that waits for rx_time tags (which automatically
get added by the USRP source nowadays)
- that block would, upon detection of such a tag, issue “the next tune
request in line” (set_command_time(rx_time+delay), set_rx_freq,
- that block would, after detection of such a tag, first discard a few
samples and then calculate your metrics based on the following N samples
yes, N210 and later have timed commands abilities, which comes with the
feature of metadata containing time stamps; the GNU Radio USRP source is
able to evaluate that metadata coming from UHD, and adds stream tags at
the right position.
Thanks for your comments, as usual, you’re being a life-saver (I wasn’t
aware of the existence of set_command_time/clear_command_time functions,
these will be immensely helpfull). From your suggestions, I understand
that the USRP will always re-attach a rx_time tag after being re-tuned?
I’ve implemented Marcus’ solutions, and it works fine. I thought I would
just mention some detail that threw me off at first so that other people
do not stumble on the same problems I did:
- when you issue a set_command_time/tune_freq/clear_command_time
(scheduled for 2 sec in the future for example), the UHD prints out the
message that it has re-tuned the USRP right away (not after 2 seconds).
Additionally, the USRP will generate a time-tag right away when
receiving the command, not after 2 seconds. But the effective change of
frequency will indeed only happen after 2 seconds. So you need to
implement a time-counter/sample-counter that will be able to detect when
2 seconds have passed.
- when the command_time arrives too late at the USRP (after the
scheduled time), the USRP will retune asap. But no alert is given to the
UHD, and it is hard to detect from the software side when this happens.
This might happen in particular when you get a lot of overflows, and
your tuning commands are scheduled for a short time in the future. To
get over this, it is recommended to send several tuning commands in
advance (if you know the successive tuning times) so that the USRP
always has several commands in its pipeline (I read somewhere you can go
up to 16 timed commands). In that case, if the host processor lags a bit
to send the latest tuning command, it will be OK since the USRP will
have some instructions in its command buffer.
Cheers (and thanks again to Marcus)