3 # Copyright 2009 Free Software Foundation, Inc.
5 # This file is part of GNU Radio
7 # GNU Radio is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3, or (at your option)
12 # GNU Radio is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with GNU Radio; see the file COPYING. If not, write to
19 # the Free Software Foundation, Inc., 51 Franklin Street,
20 # Boston, MA 02110-1301, USA.
23 from gnuradio import gr
24 from gnuradio import usrp
25 from gnuradio import eng_notation
26 from gnuradio.eng_option import eng_option
27 from gnuradio.qtgui import qtgui
28 from optparse import OptionParser
32 from gnuradio.qtgui import qtgui
33 from PyQt4 import QtGui, QtCore
36 print "Please install gr-qtgui."
40 from usrp_display_qtgui import Ui_MainWindow
42 print "Error: could not find usrp_display_qtgui.py:"
43 print "\t\"pyuic4 usrp_display_qtgui.ui -o usrp_display_qtgui.py\""
48 # ////////////////////////////////////////////////////////////////////
49 # Define the QT Interface and Control Dialog
50 # ////////////////////////////////////////////////////////////////////
53 class main_window(QtGui.QMainWindow):
54 def __init__(self, snk, fg, parent=None):
56 QtGui.QWidget.__init__(self, parent)
57 self.gui = Ui_MainWindow()
58 self.gui.setupUi(self)
62 # Add the qtsnk widgets to the layout box
63 self.gui.sinkLayout.addWidget(snk)
65 # Connect up some signals
66 self.connect(self.gui.pauseButton, QtCore.SIGNAL("clicked()"),
68 self.connect(self.gui.frequencyEdit, QtCore.SIGNAL("editingFinished()"),
69 self.frequencyEditText)
70 self.connect(self.gui.gainEdit, QtCore.SIGNAL("editingFinished()"),
72 self.connect(self.gui.bandwidthEdit, QtCore.SIGNAL("editingFinished()"),
73 self.bandwidthEditText)
74 self.connect(self.gui.amplifierEdit, QtCore.SIGNAL("editingFinished()"),
75 self.amplifierEditText)
77 self.connect(self.gui.actionSaveData, QtCore.SIGNAL("activated()"),
79 self.gui.actionSaveData.setShortcut(QtGui.QKeySequence.Save)
82 if(self.gui.pauseButton.text() == "Pause"):
85 self.gui.pauseButton.setText("Unpause")
88 self.gui.pauseButton.setText("Pause")
91 # Functions to set the values in the GUI
92 def set_frequency(self, freq):
94 sfreq = eng_notation.num_to_str(self.freq)
95 self.gui.frequencyEdit.setText(QtCore.QString("%1").arg(sfreq))
97 def set_gain(self, gain):
99 self.gui.gainEdit.setText(QtCore.QString("%1").arg(self.gain))
101 def set_bandwidth(self, bw):
103 sbw = eng_notation.num_to_str(self.bw)
104 self.gui.bandwidthEdit.setText(QtCore.QString("%1").arg(sbw))
106 def set_amplifier(self, amp):
108 self.gui.amplifierEdit.setText(QtCore.QString("%1").arg(self.amp))
111 # Functions called when signals are triggered in the GUI
112 def frequencyEditText(self):
114 freq = eng_notation.str_to_num(self.gui.frequencyEdit.text().toAscii())
115 self.fg.set_frequency(freq)
120 def gainEditText(self):
122 gain = float(self.gui.gainEdit.text())
123 self.fg.set_gain(gain)
128 def bandwidthEditText(self):
130 bw = eng_notation.str_to_num(self.gui.bandwidthEdit.text().toAscii())
131 self.fg.set_bandwidth(bw)
136 def amplifierEditText(self):
138 amp = float(self.gui.amplifierEdit.text())
139 self.fg.set_amplifier_gain(amp)
145 fileName = QtGui.QFileDialog.getSaveFileName(self, "Save data to file", ".");
147 self.fg.save_to_file(str(fileName))
150 def pick_subdevice(u):
152 The user didn't specify a subdevice on the command line.
153 If there's a daughterboard on A, select A.
154 If there's a daughterboard on B, select B.
157 if u.db(0, 0).dbid() >= 0: # dbid is < 0 if there's no d'board or a problem
159 if u.db(0, 0).dbid() >= 0:
163 class my_top_block(gr.top_block):
165 gr.top_block.__init__(self)
167 parser = OptionParser(option_class=eng_option)
168 parser.add_option("-w", "--which", type="int", default=0,
169 help="select which USRP (0, 1, ...) default is %default",
171 parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
172 help="select USRP Rx side A or B (default=first one with a daughterboard)")
173 parser.add_option("-A", "--antenna", default=None,
174 help="select Rx Antenna (only on RFX-series boards)")
175 parser.add_option("-W", "--bw", type="float", default=1e6,
176 help="set bandwidth of receiver [default=%default]")
177 parser.add_option("-f", "--freq", type="eng_float", default=None,
178 help="set frequency to FREQ", metavar="FREQ")
179 parser.add_option("-g", "--gain", type="eng_float", default=None,
180 help="set gain in dB [default is midpoint]")
181 parser.add_option("-8", "--width-8", action="store_true", default=False,
182 help="Enable 8-bit samples across USB")
183 parser.add_option( "--no-hb", action="store_true", default=False,
184 help="don't use halfband filter in usrp")
185 parser.add_option("-S", "--oscilloscope", action="store_true", default=False,
186 help="Enable oscilloscope display")
187 parser.add_option("", "--avg-alpha", type="eng_float", default=1e-1,
188 help="Set fftsink averaging factor, [default=%default]")
189 parser.add_option("", "--ref-scale", type="eng_float", default=13490.0,
190 help="Set dBFS=0dB input value, [default=%default]")
191 parser.add_option("", "--fft-size", type="int", default=2048,
192 help="Set FFT frame size, [default=%default]");
194 (options, args) = parser.parse_args()
198 self.options = options
199 self.show_debug_info = True
201 # Call this before creating the Qt sink
202 self.qapp = QtGui.QApplication(sys.argv)
204 self._fftsize = options.fft_size
206 self.u = usrp.source_c(which=options.which)
207 self._adc_rate = self.u.converter_rate()
208 self.set_bandwidth(options.bw)
210 if options.rx_subdev_spec is None:
211 options.rx_subdev_spec = pick_subdevice(self.u)
212 self._rx_subdev_spec = options.rx_subdev_spec
213 self.u.set_mux(usrp.determine_rx_mux_value(self.u, self._rx_subdev_spec))
214 self.subdev = usrp.selected_subdev(self.u, self._rx_subdev_spec)
216 self._gain_range = self.subdev.gain_range()
217 if options.gain is None:
218 # if no gain was specified, use the mid-point in dB
220 options.gain = float(g[0]+g[1])/2
221 self.set_gain(options.gain)
223 if options.freq is None:
224 # if no frequency was specified, use the mid-point of the subdev
225 f = self.subdev.freq_range()
226 options.freq = float(f[0]+f[1])/2
227 self.set_frequency(options.freq)
229 self.snk = qtgui.sink_c(self._fftsize, gr.firdes.WIN_BLACKMAN_hARRIS,
230 self._freq, self._bandwidth,
232 True, True, False, True, False)
234 # Set up internal amplifier
235 self.amp = gr.multiply_const_cc(0.0)
236 self.set_amplifier_gain(0.001)
238 # Connect the flow graph
239 self.connect(self.u, self.amp, self.snk)
242 # Get the reference pointer to the SpectrumDisplayForm QWidget
243 # Wrap the pointer as a PyQt SIP object
244 # This can now be manipulated as a PyQt4.QtGui.QWidget
245 self.pysink = sip.wrapinstance(self.snk.pyqwidget(), QtGui.QWidget)
247 self.main_win = main_window(self.pysink, self)
249 self.main_win.set_frequency(self._freq)
250 self.main_win.set_gain(self._gain)
251 self.main_win.set_bandwidth(self._bandwidth)
252 self.main_win.set_amplifier(self._amp_value)
256 def save_to_file(self, name):
257 # Pause the flow graph
261 # Add file sink to save data
262 self.file_sink = gr.file_sink(gr.sizeof_gr_complex, name)
263 self.connect(self.amp, self.file_sink)
268 def set_gain(self, gain):
270 self.subdev.set_gain(self._gain)
272 def set_frequency(self, freq):
274 self.u.tune(0, self.subdev, self._freq)
277 self.snk.set_frequency_range(self._freq, self._bandwidth)
281 def set_bandwidth(self, bw):
283 self._decim = int(self._adc_rate / self._bandwidth)
284 self.u.set_decim_rate(self._decim)
287 self.snk.set_frequency_range(self._freq, self._bandwidth)
291 def set_amplifier_gain(self, amp):
292 self._amp_value = amp
293 self.amp.set_k(self._amp_value)
296 if __name__ == "__main__":