az-dev
az-dev

Reputation: 25

How to receive a finite number of samples at a future time using UHD/GNURadio?

I'm using the GNURadio python interface to UHD, and I'm trying to set a specific time to start collecting samples and either collect a specific number of samples or stop the collection of samples at a specific time. Essentially, creating a timed snapshot of samples. This is something similar to the C++ Ettus UHD example 'rx_timed_sample'.

I can get a flowgraph to start at a specific time, but I can't seem to get it to stop at a specific time (at least without causing overflows). I've also tried doing a finite aquisition, which works, but I can't get it to start at a specific time. So I'm kind of lost at what to do next.

Here is my try at the finite acquisition (seems to just ignore the start time and collects 0 samples):

num_samples = 1000

usrp = uhd.usrp_source(
    ",".join(("", "")),
    uhd.stream_args(
        cpu_format="fc32",
        channels=range(1),
    ),
)

...

usrp.set_start_time(absolute_start_time)
samples = usrp.finite_acquisition(num_samples)

I've also tried some combinations of following without success (TypeError: in method 'usrp_source_sptr_issue_stream_cmd', argument 2 of type '::uhd::stream_cmd_t const &'):

usrp.set_command_time(absolute_start_time)
usrp.issue_stream_cmd(uhd.stream_cmd.STREAM_MODE_NUM_SAMPS_AND_DONE)

I also tried the following in a flowgraph:

...
usrp = flowgrah.uhd_usrp_source_0
absolute_start_time = uhd.uhd_swig.time_spec_t(start_time)
usrp.set_start_time(absolute_start_time)

flowgrah.start()

stop_cmd = uhd.stream_cmd(uhd.stream_cmd.STREAM_MODE_STOP_CONTINUOUS)
absolute_stop_time = absolute_start_time + uhd.uhd_swig.time_spec_t(collection_time)

usrp.set_command_time(absolute_stop_time)
usrp.issue_stream_cmd(stop_cmd)

For whatever reason the flowgraph one generated overflows consistently for anything greater than a .02s collection time.

Upvotes: 2

Views: 1934

Answers (1)

Evidlo
Evidlo

Reputation: 334

I was running into a similar issue and solved it by using the head block.

Here's a simple example which saves 10,000 samples from a sine wave source then exits.

#!/usr/bin/env python
# Evan Widloski - 2017-09-03
# Logging test in gnuradio

from gnuradio import gr
from gnuradio import blocks
from gnuradio import analog

class top_block(gr.top_block):
    def __init__(self, output):
        gr.top_block.__init__(self)

        sample_rate = 32e3
        num_samples = 10000
        ampl = 1

        source = analog.sig_source_f(sample_rate, analog.GR_SIN_WAVE, 100, ampl)
        head = blocks.head(4, num_samples)
        sink = blocks.file_sink(4, output)

        self.connect(source, head)
        self.connect(head, sink)

if __name__ == '__main__':
    try:
        top_block('/tmp/out').run()
    except KeyboardInterrupt:
        pass

Upvotes: 1

Related Questions