Imported Upstream version 3.2.2
[debian/gnuradio] / gr-qtgui / src / python / usrp_display.py
1 #!/usr/bin/env python
2 #
3 # Copyright 2009 Free Software Foundation, Inc.
4
5 # This file is part of GNU Radio
6
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)
10 # any later version.
11
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.
16
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.
21
22
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
29 import sys
30
31 try:
32     from gnuradio.qtgui import qtgui
33     from PyQt4 import QtGui, QtCore
34     import sip
35 except ImportError:
36     print "Please install gr-qtgui."
37     sys.exit(1)
38
39 try:
40     from usrp_display_qtgui import Ui_MainWindow
41 except ImportError:
42     print "Error: could not find usrp_display_qtgui.py:"
43     print "\t\"pyuic4 usrp_display_qtgui.ui -o usrp_display_qtgui.py\""
44     sys.exit(1)
45
46
47
48 # ////////////////////////////////////////////////////////////////////
49 #        Define the QT Interface and Control Dialog
50 # ////////////////////////////////////////////////////////////////////
51
52
53 class main_window(QtGui.QMainWindow):
54     def __init__(self, snk, fg, parent=None):
55
56         QtGui.QWidget.__init__(self, parent)
57         self.gui = Ui_MainWindow()
58         self.gui.setupUi(self)
59
60         self.fg = fg
61
62         # Add the qtsnk widgets to the layout box
63         self.gui.sinkLayout.addWidget(snk)
64
65         # Connect up some signals
66         self.connect(self.gui.pauseButton, QtCore.SIGNAL("clicked()"),
67                      self.pauseFg)
68         self.connect(self.gui.frequencyEdit, QtCore.SIGNAL("editingFinished()"),
69                      self.frequencyEditText)
70         self.connect(self.gui.gainEdit, QtCore.SIGNAL("editingFinished()"),
71                      self.gainEditText)
72         self.connect(self.gui.bandwidthEdit, QtCore.SIGNAL("editingFinished()"),
73                      self.bandwidthEditText)
74         self.connect(self.gui.amplifierEdit, QtCore.SIGNAL("editingFinished()"),
75                      self.amplifierEditText)
76
77         self.connect(self.gui.actionSaveData, QtCore.SIGNAL("activated()"),
78                      self.saveData)
79         self.gui.actionSaveData.setShortcut(QtGui.QKeySequence.Save)
80
81     def pauseFg(self):
82         if(self.gui.pauseButton.text() == "Pause"):
83             self.fg.stop()
84             self.fg.wait()
85             self.gui.pauseButton.setText("Unpause")
86         else:
87             self.fg.start()
88             self.gui.pauseButton.setText("Pause")
89       
90
91     # Functions to set the values in the GUI
92     def set_frequency(self, freq):
93         self.freq = freq
94         sfreq = eng_notation.num_to_str(self.freq)
95         self.gui.frequencyEdit.setText(QtCore.QString("%1").arg(sfreq))
96         
97     def set_gain(self, gain):
98         self.gain = gain
99         self.gui.gainEdit.setText(QtCore.QString("%1").arg(self.gain))
100
101     def set_bandwidth(self, bw):
102         self.bw = bw
103         sbw = eng_notation.num_to_str(self.bw)
104         self.gui.bandwidthEdit.setText(QtCore.QString("%1").arg(sbw))
105
106     def set_amplifier(self, amp):
107         self.amp = amp
108         self.gui.amplifierEdit.setText(QtCore.QString("%1").arg(self.amp))
109
110
111     # Functions called when signals are triggered in the GUI
112     def frequencyEditText(self):
113         try:
114             freq = eng_notation.str_to_num(self.gui.frequencyEdit.text().toAscii()) 
115             self.fg.set_frequency(freq)
116             self.freq = freq
117         except RuntimeError:
118             pass
119
120     def gainEditText(self):
121         try:
122             gain = float(self.gui.gainEdit.text())
123             self.fg.set_gain(gain)
124             self.gain = gain
125         except ValueError:
126             pass
127                 
128     def bandwidthEditText(self):
129         try:
130             bw = eng_notation.str_to_num(self.gui.bandwidthEdit.text().toAscii())
131             self.fg.set_bandwidth(bw)
132             self.bw = bw
133         except ValueError:
134             pass
135         
136     def amplifierEditText(self):
137         try:
138             amp = float(self.gui.amplifierEdit.text())
139             self.fg.set_amplifier_gain(amp)
140             self.amp = amp
141         except ValueError:
142             pass
143
144     def saveData(self):
145         fileName = QtGui.QFileDialog.getSaveFileName(self, "Save data to file", ".");
146         if(len(fileName)):
147             self.fg.save_to_file(str(fileName))
148
149         
150 def pick_subdevice(u):
151     """
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.
155     Otherwise, select A.
156     """
157     if u.db(0, 0).dbid() >= 0:       # dbid is < 0 if there's no d'board or a problem
158         return (0, 0)
159     if u.db(0, 0).dbid() >= 0:
160         return (1, 0)
161     return (0, 0)
162
163 class my_top_block(gr.top_block):
164     def __init__(self):
165         gr.top_block.__init__(self)
166
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",
170                           metavar="NUM")
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]");
193
194         (options, args) = parser.parse_args()
195         if len(args) != 0:
196             parser.print_help()
197             sys.exit(1)
198         self.options = options
199         self.show_debug_info = True
200
201         # Call this before creating the Qt sink
202         self.qapp = QtGui.QApplication(sys.argv)
203
204         self._fftsize = options.fft_size
205
206         self.u = usrp.source_c(which=options.which)
207         self._adc_rate = self.u.converter_rate()
208         self.set_bandwidth(options.bw)
209
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)
215
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
219             g = self._gain_range
220             options.gain = float(g[0]+g[1])/2
221         self.set_gain(options.gain)
222
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)
228
229         self.snk = qtgui.sink_c(self._fftsize, gr.firdes.WIN_BLACKMAN_hARRIS,
230                                 self._freq, self._bandwidth,
231                                 "USRP Display",
232                                 True, True, False, True, False)
233
234         # Set up internal amplifier
235         self.amp = gr.multiply_const_cc(0.0)
236         self.set_amplifier_gain(0.001)
237
238         # Connect the flow graph
239         self.connect(self.u, self.amp, self.snk)
240
241
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)
246
247         self.main_win = main_window(self.pysink, self)
248
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)
253
254         self.main_win.show()
255
256     def save_to_file(self, name):
257         # Pause the flow graph
258         self.stop()
259         self.wait()
260
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)
264
265         # Restart flow graph
266         self.start()
267
268     def set_gain(self, gain):
269         self._gain = gain
270         self.subdev.set_gain(self._gain)
271
272     def set_frequency(self, freq):
273         self._freq = freq
274         self.u.tune(0, self.subdev, self._freq)
275
276         try:
277             self.snk.set_frequency_range(self._freq, self._bandwidth)
278         except:
279             pass
280
281     def set_bandwidth(self, bw):
282         self._bandwidth = bw
283         self._decim = int(self._adc_rate / self._bandwidth)
284         self.u.set_decim_rate(self._decim)
285
286         try:
287             self.snk.set_frequency_range(self._freq, self._bandwidth)
288         except:
289             pass
290
291     def set_amplifier_gain(self, amp):
292             self._amp_value = amp
293             self.amp.set_k(self._amp_value)
294
295        
296 if __name__ == "__main__":
297     tb = my_top_block();
298     tb.start()
299     tb.qapp.exec_()