On 28/09/2011 4:50 PM, Phelps Williams wrote:
I have a usrp and computer in a remote location without much network
bandwidth available to the system and I'm using it as a spectrum
analyzer. I'd like to run the fft on the remote system and then send
the results to a connected client for display. This would allow me to
get greater fidelity than xwindows forwarding or the ascii dft example
while also using less bandwidth. I would imagine the client side
would potentially reuse some of the existing wx or qt interfaces for
display and control.
This seems like a pretty useful / simple use of this hardware. Does
anybody know of any implementations floating around that does this?
I'd prefer not to reinvent the wheel.
-Phelps
Because I'm such an insanely nice guy, I quickly implemented something
like what you'd need. Attached.
It uses a UHD source, computes a (default 2048-point) 10*log10-scaled
FFT, then outputs the resulting float-vector to a file-sink at a 5Hz rate.
Everything is pretty-much parameterized on the command line, including:
frequency (100M)
gain (20)
srate (1.0e6)
fifoname ("fft_output_fifo")
devicecfg ("addr=192.168.10.2")
xmlport (6060)
I've included the ability to change parameters on-the-fly using the
XMLRPC server, which would allow you to, for example, change
run-time parameters from some external interface, such as a WEB gui
or similar.
If this were my problem, I'd start this thing in a script which creates
the fifo file, starts some program that reads the FIFO (left as an
exercise for the proverbial reader) in the background, then calls the
Gnu Radio program.
<?xml version='1.0' encoding='ASCII'?>
<flow_graph>
<timestamp>Wed Sep 28 17:33:19 2011</timestamp>
<block>
<key>variable</key>
<param>
<key>id</key>
<value>samp_rate</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>value</key>
<value>srate</value>
</param>
<param>
<key>_coordinate</key>
<value>(9, 170)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>variable</key>
<param>
<key>id</key>
<value>fft_size</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>value</key>
<value>2048</value>
</param>
<param>
<key>_coordinate</key>
<value>(12, 90)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>parameter</key>
<param>
<key>id</key>
<value>frequency</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>label</key>
<value></value>
</param>
<param>
<key>value</key>
<value>100e6</value>
</param>
<param>
<key>type</key>
<value>eng_float</value>
</param>
<param>
<key>short_id</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(229, 14)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>parameter</key>
<param>
<key>id</key>
<value>gain</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>label</key>
<value></value>
</param>
<param>
<key>value</key>
<value>20</value>
</param>
<param>
<key>type</key>
<value>eng_float</value>
</param>
<param>
<key>short_id</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(338, 14)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>gr_file_sink</key>
<param>
<key>id</key>
<value>gr_file_sink_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>file</key>
<value>fifoname</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>vlen</key>
<value>fft_size</value>
</param>
<param>
<key>unbuffered</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(623, 268)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>parameter</key>
<param>
<key>id</key>
<value>srate</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>label</key>
<value></value>
</param>
<param>
<key>value</key>
<value>1.0e6</value>
</param>
<param>
<key>type</key>
<value>eng_float</value>
</param>
<param>
<key>short_id</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(434, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>xmlrpc_server</key>
<param>
<key>id</key>
<value>xmlrpc_server_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>addr</key>
<value>localhost</value>
</param>
<param>
<key>port</key>
<value>xmlport</value>
</param>
<param>
<key>_coordinate</key>
<value>(241, 134)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>blks2_logpwrfft_x</key>
<param>
<key>id</key>
<value>blks2_logpwrfft_x_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>sample_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>fft_size</key>
<value>fft_size</value>
</param>
<param>
<key>ref_scale</key>
<value>2</value>
</param>
<param>
<key>frame_rate</key>
<value>5</value>
</param>
<param>
<key>average</key>
<value>True</value>
</param>
<param>
<key>avg_alpha</key>
<value>0.1</value>
</param>
<param>
<key>_coordinate</key>
<value>(337, 247)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>uhd_usrp_source</key>
<param>
<key>id</key>
<value>uhd_usrp_source_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>dev_addr</key>
<value>devicefg</value>
</param>
<param>
<key>sync</key>
<value></value>
</param>
<param>
<key>clock_rate</key>
<value>0.0</value>
</param>
<param>
<key>num_mboards</key>
<value>1</value>
</param>
<param>
<key>ref_source0</key>
<value></value>
</param>
<param>
<key>sd_spec0</key>
<value></value>
</param>
<param>
<key>ref_source1</key>
<value></value>
</param>
<param>
<key>sd_spec1</key>
<value></value>
</param>
<param>
<key>ref_source2</key>
<value></value>
</param>
<param>
<key>sd_spec2</key>
<value></value>
</param>
<param>
<key>ref_source3</key>
<value></value>
</param>
<param>
<key>sd_spec3</key>
<value></value>
</param>
<param>
<key>ref_source4</key>
<value></value>
</param>
<param>
<key>sd_spec4</key>
<value></value>
</param>
<param>
<key>ref_source5</key>
<value></value>
</param>
<param>
<key>sd_spec5</key>
<value></value>
</param>
<param>
<key>ref_source6</key>
<value></value>
</param>
<param>
<key>sd_spec6</key>
<value></value>
</param>
<param>
<key>ref_source7</key>
<value></value>
</param>
<param>
<key>sd_spec7</key>
<value></value>
</param>
<param>
<key>nchan</key>
<value>1</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>center_freq0</key>
<value>frequency</value>
</param>
<param>
<key>gain0</key>
<value>gain</value>
</param>
<param>
<key>ant0</key>
<value></value>
</param>
<param>
<key>bw0</key>
<value>0</value>
</param>
<param>
<key>center_freq1</key>
<value>0</value>
</param>
<param>
<key>gain1</key>
<value>0</value>
</param>
<param>
<key>ant1</key>
<value></value>
</param>
<param>
<key>bw1</key>
<value>0</value>
</param>
<param>
<key>center_freq2</key>
<value>0</value>
</param>
<param>
<key>gain2</key>
<value>0</value>
</param>
<param>
<key>ant2</key>
<value></value>
</param>
<param>
<key>bw2</key>
<value>0</value>
</param>
<param>
<key>center_freq3</key>
<value>0</value>
</param>
<param>
<key>gain3</key>
<value>0</value>
</param>
<param>
<key>ant3</key>
<value></value>
</param>
<param>
<key>bw3</key>
<value>0</value>
</param>
<param>
<key>center_freq4</key>
<value>0</value>
</param>
<param>
<key>gain4</key>
<value>0</value>
</param>
<param>
<key>ant4</key>
<value></value>
</param>
<param>
<key>bw4</key>
<value>0</value>
</param>
<param>
<key>center_freq5</key>
<value>0</value>
</param>
<param>
<key>gain5</key>
<value>0</value>
</param>
<param>
<key>ant5</key>
<value></value>
</param>
<param>
<key>bw5</key>
<value>0</value>
</param>
<param>
<key>center_freq6</key>
<value>0</value>
</param>
<param>
<key>gain6</key>
<value>0</value>
</param>
<param>
<key>ant6</key>
<value></value>
</param>
<param>
<key>bw6</key>
<value>0</value>
</param>
<param>
<key>center_freq7</key>
<value>0</value>
</param>
<param>
<key>gain7</key>
<value>0</value>
</param>
<param>
<key>ant7</key>
<value></value>
</param>
<param>
<key>bw7</key>
<value>0</value>
</param>
<param>
<key>center_freq8</key>
<value>0</value>
</param>
<param>
<key>gain8</key>
<value>0</value>
</param>
<param>
<key>ant8</key>
<value></value>
</param>
<param>
<key>bw8</key>
<value>0</value>
</param>
<param>
<key>center_freq9</key>
<value>0</value>
</param>
<param>
<key>gain9</key>
<value>0</value>
</param>
<param>
<key>ant9</key>
<value></value>
</param>
<param>
<key>bw9</key>
<value>0</value>
</param>
<param>
<key>center_freq10</key>
<value>0</value>
</param>
<param>
<key>gain10</key>
<value>0</value>
</param>
<param>
<key>ant10</key>
<value></value>
</param>
<param>
<key>bw10</key>
<value>0</value>
</param>
<param>
<key>center_freq11</key>
<value>0</value>
</param>
<param>
<key>gain11</key>
<value>0</value>
</param>
<param>
<key>ant11</key>
<value></value>
</param>
<param>
<key>bw11</key>
<value>0</value>
</param>
<param>
<key>center_freq12</key>
<value>0</value>
</param>
<param>
<key>gain12</key>
<value>0</value>
</param>
<param>
<key>ant12</key>
<value></value>
</param>
<param>
<key>bw12</key>
<value>0</value>
</param>
<param>
<key>center_freq13</key>
<value>0</value>
</param>
<param>
<key>gain13</key>
<value>0</value>
</param>
<param>
<key>ant13</key>
<value></value>
</param>
<param>
<key>bw13</key>
<value>0</value>
</param>
<param>
<key>center_freq14</key>
<value>0</value>
</param>
<param>
<key>gain14</key>
<value>0</value>
</param>
<param>
<key>ant14</key>
<value></value>
</param>
<param>
<key>bw14</key>
<value>0</value>
</param>
<param>
<key>center_freq15</key>
<value>0</value>
</param>
<param>
<key>gain15</key>
<value>0</value>
</param>
<param>
<key>ant15</key>
<value></value>
</param>
<param>
<key>bw15</key>
<value>0</value>
</param>
<param>
<key>center_freq16</key>
<value>0</value>
</param>
<param>
<key>gain16</key>
<value>0</value>
</param>
<param>
<key>ant16</key>
<value></value>
</param>
<param>
<key>bw16</key>
<value>0</value>
</param>
<param>
<key>center_freq17</key>
<value>0</value>
</param>
<param>
<key>gain17</key>
<value>0</value>
</param>
<param>
<key>ant17</key>
<value></value>
</param>
<param>
<key>bw17</key>
<value>0</value>
</param>
<param>
<key>center_freq18</key>
<value>0</value>
</param>
<param>
<key>gain18</key>
<value>0</value>
</param>
<param>
<key>ant18</key>
<value></value>
</param>
<param>
<key>bw18</key>
<value>0</value>
</param>
<param>
<key>center_freq19</key>
<value>0</value>
</param>
<param>
<key>gain19</key>
<value>0</value>
</param>
<param>
<key>ant19</key>
<value></value>
</param>
<param>
<key>bw19</key>
<value>0</value>
</param>
<param>
<key>center_freq20</key>
<value>0</value>
</param>
<param>
<key>gain20</key>
<value>0</value>
</param>
<param>
<key>ant20</key>
<value></value>
</param>
<param>
<key>bw20</key>
<value>0</value>
</param>
<param>
<key>center_freq21</key>
<value>0</value>
</param>
<param>
<key>gain21</key>
<value>0</value>
</param>
<param>
<key>ant21</key>
<value></value>
</param>
<param>
<key>bw21</key>
<value>0</value>
</param>
<param>
<key>center_freq22</key>
<value>0</value>
</param>
<param>
<key>gain22</key>
<value>0</value>
</param>
<param>
<key>ant22</key>
<value></value>
</param>
<param>
<key>bw22</key>
<value>0</value>
</param>
<param>
<key>center_freq23</key>
<value>0</value>
</param>
<param>
<key>gain23</key>
<value>0</value>
</param>
<param>
<key>ant23</key>
<value></value>
</param>
<param>
<key>bw23</key>
<value>0</value>
</param>
<param>
<key>center_freq24</key>
<value>0</value>
</param>
<param>
<key>gain24</key>
<value>0</value>
</param>
<param>
<key>ant24</key>
<value></value>
</param>
<param>
<key>bw24</key>
<value>0</value>
</param>
<param>
<key>center_freq25</key>
<value>0</value>
</param>
<param>
<key>gain25</key>
<value>0</value>
</param>
<param>
<key>ant25</key>
<value></value>
</param>
<param>
<key>bw25</key>
<value>0</value>
</param>
<param>
<key>center_freq26</key>
<value>0</value>
</param>
<param>
<key>gain26</key>
<value>0</value>
</param>
<param>
<key>ant26</key>
<value></value>
</param>
<param>
<key>bw26</key>
<value>0</value>
</param>
<param>
<key>center_freq27</key>
<value>0</value>
</param>
<param>
<key>gain27</key>
<value>0</value>
</param>
<param>
<key>ant27</key>
<value></value>
</param>
<param>
<key>bw27</key>
<value>0</value>
</param>
<param>
<key>center_freq28</key>
<value>0</value>
</param>
<param>
<key>gain28</key>
<value>0</value>
</param>
<param>
<key>ant28</key>
<value></value>
</param>
<param>
<key>bw28</key>
<value>0</value>
</param>
<param>
<key>center_freq29</key>
<value>0</value>
</param>
<param>
<key>gain29</key>
<value>0</value>
</param>
<param>
<key>ant29</key>
<value></value>
</param>
<param>
<key>bw29</key>
<value>0</value>
</param>
<param>
<key>center_freq30</key>
<value>0</value>
</param>
<param>
<key>gain30</key>
<value>0</value>
</param>
<param>
<key>ant30</key>
<value></value>
</param>
<param>
<key>bw30</key>
<value>0</value>
</param>
<param>
<key>center_freq31</key>
<value>0</value>
</param>
<param>
<key>gain31</key>
<value>0</value>
</param>
<param>
<key>ant31</key>
<value></value>
</param>
<param>
<key>bw31</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(45, 271)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>parameter</key>
<param>
<key>id</key>
<value>xmlport</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>label</key>
<value></value>
</param>
<param>
<key>value</key>
<value>6060</value>
</param>
<param>
<key>type</key>
<value>intx</value>
</param>
<param>
<key>short_id</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(669, 9)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>parameter</key>
<param>
<key>id</key>
<value>fifoname</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>label</key>
<value></value>
</param>
<param>
<key>value</key>
<value>fft_output_fifo</value>
</param>
<param>
<key>type</key>
<value>string</value>
</param>
<param>
<key>short_id</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(530, 8)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>parameter</key>
<param>
<key>id</key>
<value>devicecfg</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>label</key>
<value></value>
</param>
<param>
<key>value</key>
<value>addr=192.168.10.2</value>
</param>
<param>
<key>type</key>
<value>string</value>
</param>
<param>
<key>short_id</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(757, 8)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>options</key>
<param>
<key>id</key>
<value>uhd_fft_to_file</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>title</key>
<value></value>
</param>
<param>
<key>author</key>
<value></value>
</param>
<param>
<key>description</key>
<value></value>
</param>
<param>
<key>window_size</key>
<value>1280, 1024</value>
</param>
<param>
<key>generate_options</key>
<value>no_gui</value>
</param>
<param>
<key>category</key>
<value>Custom</value>
</param>
<param>
<key>run_options</key>
<value>run</value>
</param>
<param>
<key>run</key>
<value>True</value>
</param>
<param>
<key>realtime_scheduling</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(10, 10)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<connection>
<source_block_id>uhd_usrp_source_0</source_block_id>
<sink_block_id>blks2_logpwrfft_x_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blks2_logpwrfft_x_0</source_block_id>
<sink_block_id>gr_file_sink_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
</flow_graph>
#!/usr/bin/env python
##################################################
# Gnuradio Python Flow Graph
# Title: Uhd Fft To File
# Generated: Wed Sep 28 17:33:21 2011
##################################################
from gnuradio import blks2
from gnuradio import eng_notation
from gnuradio import gr
from gnuradio import uhd
from gnuradio.eng_option import eng_option
from gnuradio.gr import firdes
from optparse import OptionParser
import SimpleXMLRPCServer
import threading
class uhd_fft_to_file(gr.top_block):
def __init__(self, frequency=100e6, gain=20, srate=1.0e6, xmlport=6060,
fifoname="fft_output_fifo", devicecfg="addr=192.168.10.2"):
gr.top_block.__init__(self, "Uhd Fft To File")
##################################################
# Parameters
##################################################
self.frequency = frequency
self.gain = gain
self.srate = srate
self.xmlport = xmlport
self.fifoname = fifoname
self.devicecfg = devicecfg
##################################################
# Variables
##################################################
self.samp_rate = samp_rate = srate
self.fft_size = fft_size = 2048
##################################################
# Blocks
##################################################
self.xmlrpc_server_0 =
SimpleXMLRPCServer.SimpleXMLRPCServer(("localhost", xmlport), allow_none=True)
self.xmlrpc_server_0.register_instance(self)
threading.Thread(target=self.xmlrpc_server_0.serve_forever).start()
self.uhd_usrp_source_0 = uhd.usrp_source(
device_addr="devicefg",
io_type=uhd.io_type.COMPLEX_FLOAT32,
num_channels=1,
)
self.uhd_usrp_source_0.set_samp_rate(samp_rate)
self.uhd_usrp_source_0.set_center_freq(frequency, 0)
self.uhd_usrp_source_0.set_gain(gain, 0)
self.gr_file_sink_0 = gr.file_sink(gr.sizeof_float*fft_size,
fifoname)
self.gr_file_sink_0.set_unbuffered(True)
self.blks2_logpwrfft_x_0 = blks2.logpwrfft_c(
sample_rate=samp_rate,
fft_size=fft_size,
ref_scale=2,
frame_rate=5,
avg_alpha=0.1,
average=True,
)
##################################################
# Connections
##################################################
self.connect((self.uhd_usrp_source_0, 0),
(self.blks2_logpwrfft_x_0, 0))
self.connect((self.blks2_logpwrfft_x_0, 0),
(self.gr_file_sink_0, 0))
def get_frequency(self):
return self.frequency
def set_frequency(self, frequency):
self.frequency = frequency
self.uhd_usrp_source_0.set_center_freq(self.frequency, 0)
def get_gain(self):
return self.gain
def set_gain(self, gain):
self.gain = gain
self.uhd_usrp_source_0.set_gain(self.gain, 0)
def get_srate(self):
return self.srate
def set_srate(self, srate):
self.srate = srate
self.set_samp_rate(self.srate)
def get_xmlport(self):
return self.xmlport
def set_xmlport(self, xmlport):
self.xmlport = xmlport
def get_fifoname(self):
return self.fifoname
def set_fifoname(self, fifoname):
self.fifoname = fifoname
def get_devicecfg(self):
return self.devicecfg
def set_devicecfg(self, devicecfg):
self.devicecfg = devicecfg
def get_samp_rate(self):
return self.samp_rate
def set_samp_rate(self, samp_rate):
self.samp_rate = samp_rate
self.blks2_logpwrfft_x_0.set_sample_rate(self.samp_rate)
self.uhd_usrp_source_0.set_samp_rate(self.samp_rate)
def get_fft_size(self):
return self.fft_size
def set_fft_size(self, fft_size):
self.fft_size = fft_size
if __name__ == '__main__':
parser = OptionParser(option_class=eng_option, usage="%prog: [options]")
parser.add_option("", "--frequency", dest="frequency",
type="eng_float", default=eng_notation.num_to_str(100e6),
help="Set frequency [default=%default]")
parser.add_option("", "--gain", dest="gain", type="eng_float",
default=eng_notation.num_to_str(20),
help="Set gain [default=%default]")
parser.add_option("", "--srate", dest="srate", type="eng_float",
default=eng_notation.num_to_str(1.0e6),
help="Set srate [default=%default]")
parser.add_option("", "--xmlport", dest="xmlport", type="intx",
default=6060,
help="Set xmlport [default=%default]")
parser.add_option("", "--fifoname", dest="fifoname", type="string",
default="fft_output_fifo",
help="Set fifoname [default=%default]")
parser.add_option("", "--devicecfg", dest="devicecfg", type="string",
default="addr=192.168.10.2",
help="Set devicecfg [default=%default]")
(options, args) = parser.parse_args()
tb = uhd_fft_to_file(frequency=options.frequency, gain=options.gain,
srate=options.srate, xmlport=options.xmlport, fifoname=options.fifoname,
devicecfg=options.devicecfg)
tb.run()
_______________________________________________
Discuss-gnuradio mailing list
Discuss-gnuradio@gnu.org
https://lists.gnu.org/mailman/listinfo/discuss-gnuradio