# USRP spectrum sensing

**URL:** <https://www.ruby-forum.com/t/usrp-spectrum-sensing/233031>\
**Category:** GNU Radio\
**Created:** [November 12, 2014, 2:58pm UTC](https://www.ruby-forum.com/t/usrp-spectrum-sensing/233031 "2014-11-12T14:58:54Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![addis\_a](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/c4cdca/32.png) [@addis\_a](https://www.ruby-forum.com/u/addis_a)\
**Post date:** [November 12, 2014, 2:58pm UTC](https://www.ruby-forum.com/t/usrp-spectrum-sensing/233031/1 "2014-11-12T14:58:54Z")

</div>

When I implement the source code " usrp\_spectrum\_sense.py", the program  
can  
be compile but when I enter the start, end frequency and fft size it  
comes  
with a error:‘module’ object has no attribute ’stream\_to\_vector. Has  
anyone  
meet this error before.  
and I found some solution : rename the project file and delete  
filename.pyc  
if exists, but I don’t know where to find the .pyc file for the  
stream\_to\_vector, is it included in gr?  
Any direction or examples will be very helpful for me.

Thanks a lot  
Huihuang

[http://gnuradio.4.n7.nabble.com/file/n51288/error.png](http://gnuradio.4.n7.nabble.com/file/n51288/error.png)  
here I attached the program

from gnuradio import gr, eng\_notation  
from gnuradio import audio  
from gnuradio.fft import window  
from gnuradio import uhd  
from gnuradio.eng\_option import eng\_option  
from optparse import OptionParser  
import sys  
import math  
import struct  
from gnuradio import blocks  
from gnuradio import wxgui  
import threading

sys.stderr.write(“test usrp\_sense-\>huihuang.\n\n”)  
class ThreadClass(threading.Thread):  
def run(self):  
return

class tune(gr.feval\_dd):  
“”"  
This class allows C++ code to callback into python.  
“”"  
def **init** (self, tb):  
gr.feval\_dd. **init** (self)  
self.tb = tb

```
def eval(self, ignore):
    """
    This method is called from gr.bin_statistics_f when it wants to

```

change  
the center frequency. This method tunes the front end to the  
new  
center  
frequency, and returns the new frequency as its result.  
“”"  
try:  
# We use this try block so that if something goes wrong from  
here  
# down, at least we’ll have a prayer of knowing what went  
wrong.  
# Without this, you get a very mysterious:  
#  
# terminate called after throwing an instance of  
‘Swig::DirectorMethodException’  
# Aborted  
#  
# message on stderr. Not exactly helpful 😉

```
        new_freq = self.tb.set_next_freq()
        return new_freq

    except Exception, e:
        print "tune: Exception: ", e

```

class parse\_msg(object):  
def **init** (self, msg):  
self.center\_freq = msg.arg1()  
self.vlen = int(msg.arg2())  
assert(msg.length() == self.vlen \* gr.sizeof\_float)

```
    # FIXME consider using Numarray or NumPy vector
    t = msg.to_string()
    self.raw_data = t
    self.data = struct.unpack('%df' % (self.vlen,), t)

```

class my\_top\_block(gr.top\_block):

```
def __init__ (self):
    gr.top_block. __init__ (self)

    usage = "usage: %prog [options] min_freq max_freq"
    parser = OptionParser(option_class=eng_option, usage=usage)
    parser.add_option("-a","--args",type="string",default="",
                      help="UHD device device address

```

args[default=%default]“)  
parser.add\_option(”“,”–spec",type=“string”,default=None,  
help=“Subdevice of UHD device where  
appropriate”)  
parser.add\_option(“-A”,“–antenna”,type=“string”,default=None,  
help=“select RX antenna where appropriate”)  
parser.add\_option(“-s”,“–samp-rate”,type=“eng\_float”,default=1e6,  
help=“set sample rate[default=%default]”)  
parser.add\_option(“-g”,“–gain”,type=“eng\_float”,default=None,  
help=“set the gain in dB[default=%default]”)

parser.add\_option(“”,“–tune-delay”,type=“eng\_float”,default=1e-3,metavar=“SECS”,  
help=“time to delay(in seconds) after changing  
frequency[default=%default]”)

parser.add\_option(“”,“–dwell-delay”,type=“eng\_float”,default=10e-3,metavar=“SECS”,  
help=“time to dwell (in seconds) at a given  
frequency[default=%default]”)  
parser.add\_option(“-F”,“–fft-size”,type=“int”,default=256,  
help=“specify number of fft bins”)

parser.add\_option(“”,“–real-time”,action=“store\_true”,default=False,  
help=“attempt to enable real-time scheduling”)

```
    (options, args) = parser.parse_args()
    if len(args) != 2:
        parser.print_help()
        sys.exit(1)

    self.min_freq = eng_notation.str_to_num(args[0])
    self.max_freq = eng_notation.str_to_num(args[1])

    if self.min_freq > self.max_freq:
        # swap them
        self.min_freq, self.max_freq = self.max_freq, self.min_freq

    self.fft_size = options.fft_size

    if not options.real_time:
        realtime = False
    else:
        # Attempt to enable realtime scheduling
        r = gr.enable_realtime_scheduling()
        if r == gr.RT_OK:
            realtime = True
        else:
            realtime = False
            print "Note: failed to enable realtime scheduling"

    #build the graph
    self.u=uhd.usrp_source(device_addr=options.args,
                           stream_args=uhd.stream_args('fc32'))

    #set the subdevice spec
    if(options.spec):
        self.u.set_subdev_spec(options.spec,0)

    #set the antenna
    if(options.antenna):
        self.u.set_antenna(options.antenna,0)

    usrp_rate=options.samp_rate
    self.u.set_samp_rate(usrp_rate)
    dev_rate=self.u.get_samp_rate()

    s2v=gr.stream_to_vector(gr.sizeof_gr_complex,self.fft_size)

    mywindow=window.blackmanharris(self.fft_size)
    fft=gr.fft_vcc(self.fft_size,True,mywindow)
    power=0
    for tap in mywindow:
        power += tap*tap

    c2mag=gr.complex_to_mag_squared(self.fft_size)

     # FIXME the log10 primitive is dog slow
    log = gr.nlog10_ff(10, self.fft_size,

```

-20_math.log10(self.fft\_size)-10_math.log10(power/self.fft\_size))

```
    # Set the freq_step to 75% of the actual data throughput.
    # This allows us to discard the bins on both ends of the 

```

spectrum.

```
    self.freq_step = 0.75 * usrp_rate
    self.min_center_freq = self.min_freq + self.freq_step/2
    nsteps = math.ceil((self.max_freq - self.min_freq) / 

```

self.freq\_step)  
self.max\_center\_freq = self.min\_center\_freq + (nsteps \*  
self.freq\_step)

```
    self.next_freq = self.min_center_freq

    tune_delay = max(0, int(round(options.tune_delay * usrp_rate /

```

self.fft\_size))) # in fft\_frames  
dwell\_delay = max(1, int(round(options.dwell\_delay \* usrp\_rate /  
self.fft\_size))) # in fft\_frames

```
    self.msgq = gr.msg_queue(16)
    self._tune_callback = tune(self) # hang on to this to 

```

keep it  
from being GC’d  
stats = gr.bin\_statistics\_f(self.fft\_size, self.msgq,  
self.\_tune\_callback, tune\_delay,  
dwell\_delay)

```
    self.connect(self.u, s2v, fft, c2mag, stats)

    if options.gain is None:
        # if no gain was specified, use the mid-point in dB
        g = self.u.get_gain_range()
        options.gain = float(g.start()+g.stop())/2.0

    self.set_gain(options.gain)
    print "gain =", options.gain

def set_next_freq(self):
    target_freq = self.next_freq
    self.next_freq = self.next_freq + self.freq_step
    if self.next_freq >= self.max_center_freq:
        self.next_freq = self.min_center_freq

    if not self.set_freq(target_freq):
        print "Failed to set frequency to", target_freq
        sys.exit(1)

    return target_freq

def set_freq(self,target_freq):
    r=self.u.set_center_freq(target_freq)
    if r:
        return True

    return False

def set_gain(self,gain):
    self.u.set_gain(gain)

```

def main\_loop(tb):  
while 1:  
#get the next message sent from the c++ code(blocking call)  
#it contains the center frequency and the mag squared of the fft  
m=parse\_msg(tb.msgq.delete\_head())  
#print center freq so we know that something is happening  
print m.center\_freq  
#print m.data  
if **name** ==‘ **main** ’:  
t=ThreadClass()  
t.start()

```
tb=my_top_block()
try:
    tb.start()
    main_loop(tb)
except KeyboardInterrupt:
    pass

```

–  
View this message in context:  
[http://gnuradio.4.n7.nabble.com/USRP-spectrum-sensing-tp51288.html](http://gnuradio.4.n7.nabble.com/USRP-spectrum-sensing-tp51288.html)  
Sent from the GnuRadio mailing list archive at [Nabble.com](http://Nabble.com).

---

<div class="post-metadata">

**Author:** ![Leo\_Yang](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/439d5e/32.png) [@Leo\_Yang](https://www.ruby-forum.com/u/Leo_Yang)\
**Post date:** [November 12, 2014, 3:04pm UTC](https://www.ruby-forum.com/t/usrp-spectrum-sensing/233031/2 "2014-11-12T15:04:17Z")

</div>

stream to vector is a block that comes with GNU Radio. If python can’t  
find that, you have not installed GNU Radio correctly.

Best regards,  
Marcus

---

<div class="post-metadata">

**Author:** ![Leo\_Yang](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/439d5e/32.png) [@Leo\_Yang](https://www.ruby-forum.com/u/Leo_Yang)\
**Post date:** [November 12, 2014, 3:09pm UTC](https://www.ruby-forum.com/t/usrp-spectrum-sensing/233031/3 "2014-11-12T15:09:40Z")

</div>

But when i run the other programs which include stream\_to\_vector  
function,  
they all works well, it quiet confused me

–  
View this message in context:  
[http://gnuradio.4.n7.nabble.com/USRP-spectrum-sensing-tp51288p51290.html](http://gnuradio.4.n7.nabble.com/USRP-spectrum-sensing-tp51288p51290.html)  
Sent from the GnuRadio mailing list archive at [Nabble.com](http://Nabble.com).

---

<div class="post-metadata">

**Author:** ![Leo\_Yang](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/439d5e/32.png) [@Leo\_Yang](https://www.ruby-forum.com/u/Leo_Yang)\
**Post date:** [November 12, 2014, 3:37pm UTC](https://www.ruby-forum.com/t/usrp-spectrum-sensing/233031/4 "2014-11-12T15:37:08Z")

</div>

That confuses me, too 😉  
Is this the usrp\_spectrum\_sense.py from your own installed GNU Radio or  
did you get it somewhere else?

Greetings,  
Marcus

---

<div class="post-metadata">

**Author:** ![Leo\_Yang](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/439d5e/32.png) [@Leo\_Yang](https://www.ruby-forum.com/u/Leo_Yang)\
**Post date:** [November 12, 2014, 3:56pm UTC](https://www.ruby-forum.com/t/usrp-spectrum-sensing/233031/5 "2014-11-12T15:56:50Z")

</div>

-----BEGIN PGP SIGNED MESSAGE-----  
Hash: SHA1

As you can see, yes, it does really matter… that specific commit is  
_seven_ years old…  
Why would you want to use that old version of the file?

On 11/12/2014 03:39 PM, Leo Yang wrote:

> – View this message in context:  
> [http://gnuradio.4.n7.nabble.com/USRP-spectrum-sensing-tp51288p51293.html](http://gnuradio.4.n7.nabble.com/USRP-spectrum-sensing-tp51288p51293.html)

Sent from the GnuRadio mailing list archive at [Nabble.com](http://Nabble.com).

> \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_ Discuss-gnuradio  
> mailing list [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> [Discuss-gnuradio Info Page](https://lists.gnu.org/mailman/listinfo/discuss-gnuradio)

-----BEGIN PGP SIGNATURE-----  
Version: GnuPG v1

iQEcBAEBAgAGBQJUY3TIAAoJEAFxB7BbsDrLpM8H/2Ru4d//v0y78H6J2J0K/foq  
F147iHHKk2NGRYLrEf7+1oiR+S9KO4OvWTH9BOy4uS0oYenYk9IXaFYMwkp0/G7Y  
FDVsOgeEFYn6YNFVRRX0HXngkNo3OGOSNBF2rS02EfaM1GAuTeK9lMWrGS/o9fi2  
6nzuL22F8+xNe1YyMBaa32fOkjIqseX2/e+MF+e1888W3BJOqvbeZMc2rP1OLFpb  
82vR701Y7n6OXFGVLyqX8eJRCUxN+075k0YV0kJXI/wpwItM56+DjIQtV3yGxNqr  
UKus7bULRbZvYCRt8V5erwP6ttdz9E8kVKncsx2Dqx0sibVQUykLTlepJvP91Gg=  
=O6YR  
-----END PGP SIGNATURE-----

---

<div class="post-metadata">

**Author:** ![Leo\_Yang](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/439d5e/32.png) [@Leo\_Yang](https://www.ruby-forum.com/u/Leo_Yang)\
**Post date:** [November 12, 2014, 3:52pm UTC](https://www.ruby-forum.com/t/usrp-spectrum-sensing/233031/6 "2014-11-12T15:52:03Z")

</div>

Thanks a lot for ur replay first,  
i got the source code from

[http://gnuradio.org/redmine/projects/gnuradio/repository/revisions/9880e7bb383054aa43681b52ebd33c8fd4cb8fcb/entry/gnuradio-examples/python/usrp/usrp\_spectrum\_sense.py](http://gnuradio.org/redmine/projects/gnuradio/repository/revisions/9880e7bb383054aa43681b52ebd33c8fd4cb8fcb/entry/gnuradio-examples/python/usrp/usrp_spectrum_sense.py)

and a bit modified has been made. u said “get it somewhere”, u mean  
download and run the program directly  
, does it really matter ? do u have the USRP device beside u now, it  
may be  
helpful to figure out.

–  
View this message in context:  
[http://gnuradio.4.n7.nabble.com/USRP-spectrum-sensing-tp51288p51293.html](http://gnuradio.4.n7.nabble.com/USRP-spectrum-sensing-tp51288p51293.html)  
Sent from the GnuRadio mailing list archive at [Nabble.com](http://Nabble.com).

---

<div class="post-metadata">

**Author:** ![Leo\_Yang](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/439d5e/32.png) [@Leo\_Yang](https://www.ruby-forum.com/u/Leo_Yang)\
**Post date:** [November 12, 2014, 4:09pm UTC](https://www.ruby-forum.com/t/usrp-spectrum-sensing/233031/7 "2014-11-12T16:09:58Z")

</div>

I do have modified the code, and I made this program based on the  
tutorial  
video in Youtube

[![](https://img.youtube.com/vi/DiVvnMJsVBg/maxresdefault.jpg "GNURADIO : Spectrum sensing with USRP part-1") ](https://www.youtube.com/watch?v=DiVvnMJsVBg)

which seems like two years ago stuff. I’m not sure whether it fit the  
latest  
version of gnuradio.  
I just found there are some head file difference and  
flow\_graph-\>top\_block,  
is there anything else i should consider?  
sorry for my ignorance

–  
View this message in context:  
[http://gnuradio.4.n7.nabble.com/USRP-spectrum-sensing-tp51288p51295.html](http://gnuradio.4.n7.nabble.com/USRP-spectrum-sensing-tp51288p51295.html)  
Sent from the GnuRadio mailing list archive at [Nabble.com](http://Nabble.com).

---

<div class="post-metadata">

**Author:** ![Leo\_Yang](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/439d5e/32.png) [@Leo\_Yang](https://www.ruby-forum.com/u/Leo_Yang)\
**Post date:** [November 12, 2014, 4:12pm UTC](https://www.ruby-forum.com/t/usrp-spectrum-sensing/233031/8 "2014-11-12T16:12:57Z")

</div>

-----BEGIN PGP SIGNED MESSAGE-----  
Hash: SHA1

Don’t worry, the things you’ll have to change to make your code work  
with current GNU Radio aren’t so big, but I think you will notice  
yourself when reading the current version of the file.

However, I’d wonder how you ended up with a link to a version from 7  
years ago, would you mind telling us?

Greetings,  
Marcus  
On 11/12/2014 04:02 PM, Leo Yang wrote:

> – View this message in context:  
> [http://gnuradio.4.n7.nabble.com/USRP-spectrum-sensing-tp51288p51295.html](http://gnuradio.4.n7.nabble.com/USRP-spectrum-sensing-tp51288p51295.html)

Sent from the GnuRadio mailing list archive at [Nabble.com](http://Nabble.com).

> \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_ Discuss-gnuradio  
> mailing list [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> [Discuss-gnuradio Info Page](https://lists.gnu.org/mailman/listinfo/discuss-gnuradio)

-----BEGIN PGP SIGNATURE-----  
Version: GnuPG v1

iQEcBAEBAgAGBQJUY3iyAAoJEAFxB7BbsDrLO1cH/AzPp/y3mRIP5rCh+B0W0z24  
mYxic97eHYGaOUt2dGUScCRsClBYDRb8MW9/U6OcqTHaBbo39UempCO8rndUR4Yq  
mXjevba/DrTeN6zbWOiPtybB887x+6CvOSkqOQTVcKMCutjuOagsgZHBcgBNa/7i  
7yKbTQKx8X8Zn5j/9xdSlBvT+S/ZS44Wt9l+GftZPQQsx/G32GaQzTwwWBUT1DUF  
uIk6Wr/yMIJ0pc3vyLReNYuxVvj+52YdYjfntnkwV73wQJeZXPZYx7enl7gUSVcP  
hJkLehPWKxxxSHy72+RRLe1pvL10xs4RspxhLl1+cae7vUTfjpRQsDvVo4RsybM=  
=e1K5  
-----END PGP SIGNATURE-----

---

<div class="post-metadata">

**Author:** ![Leo\_Yang](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/439d5e/32.png) [@Leo\_Yang](https://www.ruby-forum.com/u/Leo_Yang)\
**Post date:** [November 12, 2014, 4:40pm UTC](https://www.ruby-forum.com/t/usrp-spectrum-sensing/233031/9 "2014-11-12T16:40:25Z")

</div>

When i search the usrp spectrum sensing stuff, this source code is first  
comes out, and there is some relative explanation of this program, and  
I  
just met gnuradio few weeks ago.  
btw, where to find the current version file of gnuradio

–  
View this message in context:  
[http://gnuradio.4.n7.nabble.com/USRP-spectrum-sensing-tp51288p51297.html](http://gnuradio.4.n7.nabble.com/USRP-spectrum-sensing-tp51288p51297.html)  
Sent from the GnuRadio mailing list archive at [Nabble.com](http://Nabble.com).

---

<div class="post-metadata">

**Author:** ![Leo\_Yang](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/439d5e/32.png) [@Leo\_Yang](https://www.ruby-forum.com/u/Leo_Yang)\
**Post date:** [November 12, 2014, 4:43pm UTC](https://www.ruby-forum.com/t/usrp-spectrum-sensing/233031/10 "2014-11-12T16:43:24Z")

</div>

-----BEGIN PGP SIGNED MESSAGE-----  
Hash: SHA1

> **[GitHub - gnuradio/gnuradio: GNU Radio – the Free and Open Software Radio...](https://github.com/gnuradio/gnuradio)**
>
> GNU Radio – the Free and Open Software Radio Ecosystem

Information like that can always be found on the GNU Radio project  
website, [http://gnuradio.org](http://gnuradio.org).

On 11/12/2014 04:33 PM, Leo Yang wrote:

> 

Sent from the GnuRadio mailing list archive at [Nabble.com](http://Nabble.com).

> \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_ Discuss-gnuradio  
> mailing list [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> [Discuss-gnuradio Info Page](https://lists.gnu.org/mailman/listinfo/discuss-gnuradio)

-----BEGIN PGP SIGNATURE-----  
Version: GnuPG v1

iQEcBAEBAgAGBQJUY3/eAAoJEAFxB7BbsDrLslkH/2iD0Ii2wziunq4pTRXFTfKS  
9hMBHn+Nfu+K2l2MoE4CrC4up7DW0VurqpV1/QGaK4bRwwx9MkuXhCL/ql7QMgF7  
3ff+nb+3JI4q45VRFoNWdHeMbw2Ffrx2O2bcHcddnMDYOZb2c3EJnOFSR6FKMZuT  
l0gZZUghySniBH7pvkcB9GXVa7QwgmBtZsquk/3baOMv8kq01vWoaGD6w+yRxBR6  
zSkpmi5POKfVTfYqxMlwMJARJ4j/OObcKa0ipk/XjgQ/rwcwvlIq/ksO3KaDrC/p  
T8bstICOfXT6yOkltUZEncgoOErzgBAvALodJ0ZdQxAcyU5d5lVTn7HM7ko6CgM=  
=0Y4e  
-----END PGP SIGNATURE-----

---

<div class="post-metadata">

**Author:** ![Leo\_Yang](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/439d5e/32.png) [@Leo\_Yang](https://www.ruby-forum.com/u/Leo_Yang)\
**Post date:** [November 12, 2014, 6:02pm UTC](https://www.ruby-forum.com/t/usrp-spectrum-sensing/233031/11 "2014-11-12T18:02:48Z")

</div>

Thanks very mush sir, the program now is working.

–  
View this message in context:  
[http://gnuradio.4.n7.nabble.com/USRP-spectrum-sensing-tp51288p51300.html](http://gnuradio.4.n7.nabble.com/USRP-spectrum-sensing-tp51288p51300.html)  
Sent from the GnuRadio mailing list archive at [Nabble.com](http://Nabble.com).

---

<div class="post-metadata">

**Author:** ![Leo\_Yang](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/439d5e/32.png) [@Leo\_Yang](https://www.ruby-forum.com/u/Leo_Yang)\
**Post date:** [November 12, 2014, 5:32pm UTC](https://www.ruby-forum.com/t/usrp-spectrum-sensing/233031/12 "2014-11-12T17:32:21Z")

</div>

Thanks again, I found the problem where it comes, it seems in latest  
version,  
I did not import Blocks in the begin, hence the program seems can find  
stream\_to\_vector function 😉  
But a same error comes with fft\_vcc which is included in fft,which has  
already imported

[http://gnuradio.org/doc/doxygen/classgr\_1\_1fft\_1\_1fft\_\_vcc.html](http://gnuradio.org/doc/doxygen/classgr_1_1fft_1_1fft__vcc.html)

I tried “from gnuradio.fft import fft\_vcc” and it failed, it seems the  
program can’t find the fft\_vcc ☹

–  
View this message in context:  
[http://gnuradio.4.n7.nabble.com/USRP-spectrum-sensing-tp51288p51299.html](http://gnuradio.4.n7.nabble.com/USRP-spectrum-sensing-tp51288p51299.html)  
Sent from the GnuRadio mailing list archive at [Nabble.com](http://Nabble.com).
