Merging trondeau/qt branch r11231:11360. This merge improves the usability and exampl...
[debian/gnuradio] / gr-qtgui / src / python / usrp_display.py
1 #!/usr/bin/env python
2
3 from gnuradio import gr
4 from gnuradio import usrp
5 from gnuradio import eng_notation
6 from gnuradio.eng_option import eng_option
7 from gnuradio.qtgui import qtgui
8 from optparse import OptionParser
9 import sys
10
11 try:
12     from gnuradio.qtgui import qtgui
13     from PyQt4 import QtGui, QtCore
14     import sip
15 except ImportError:
16     print "Please install gr-qtgui."
17     sys.exit(1)
18
19 try:
20     from usrp_display_qtgui import Ui_MainWindow
21 except ImportError:
22     print "Error: could not find usrp_display_qtgui.py:"
23     print "\t\"pyuic4 usrp_display_qtgui.ui -o usrp_display_qtgui.py\""
24     sys.exit(1)
25
26
27
28 # ////////////////////////////////////////////////////////////////////
29 #        Define the QT Interface and Control Dialog
30 # ////////////////////////////////////////////////////////////////////
31
32
33 class main_window(QtGui.QMainWindow):
34     def __init__(self, snk, fg, parent=None):
35
36         QtGui.QWidget.__init__(self, parent)
37         self.gui = Ui_MainWindow()
38         self.gui.setupUi(self)
39
40         self.fg = fg
41
42         # Add the qtsnk widgets to the layout box
43         self.gui.sinkLayout.addWidget(snk)
44
45         # Connect up some signals
46         self.connect(self.gui.pauseButton, QtCore.SIGNAL("clicked()"),
47                      self.pauseFg)
48         self.connect(self.gui.frequencyEdit, QtCore.SIGNAL("editingFinished()"),
49                      self.frequencyEditText)
50         self.connect(self.gui.gainEdit, QtCore.SIGNAL("editingFinished()"),
51                      self.gainEditText)
52         self.connect(self.gui.bandwidthEdit, QtCore.SIGNAL("editingFinished()"),
53                      self.bandwidthEditText)
54         self.connect(self.gui.amplifierEdit, QtCore.SIGNAL("editingFinished()"),
55                      self.amplifierEditText)
56
57         self.connect(self.gui.actionSaveData, QtCore.SIGNAL("activated()"),
58                      self.saveData)
59         self.gui.actionSaveData.setShortcut(QtGui.QKeySequence.Save)
60
61     def pauseFg(self):
62         if(self.gui.pauseButton.text() == "Pause"):
63             self.fg.stop()
64             self.fg.wait()
65             self.gui.pauseButton.setText("Unpause")
66         else:
67             self.fg.start()
68             self.gui.pauseButton.setText("Pause")
69       
70
71     # Functions to set the values in the GUI
72     def set_frequency(self, freq):
73         self.freq = freq
74         sfreq = eng_notation.num_to_str(self.freq)
75         self.gui.frequencyEdit.setText(QtCore.QString("%1").arg(sfreq))
76         
77     def set_gain(self, gain):
78         self.gain = gain
79         self.gui.gainEdit.setText(QtCore.QString("%1").arg(self.gain))
80
81     def set_bandwidth(self, bw):
82         self.bw = bw
83         sbw = eng_notation.num_to_str(self.bw)
84         self.gui.bandwidthEdit.setText(QtCore.QString("%1").arg(sbw))
85
86     def set_amplifier(self, bw):
87         self.amp = amp
88         self.gui.amplifierEdit.setText(QtCore.QString("%1").arg(self.amp))
89
90
91     # Functions called when signals are triggered in the GUI
92     def frequencyEditText(self):
93         try:
94             freq = eng_notation.str_to_num(self.gui.frequencyEdit.text().toAscii()) 
95             self.fg.set_frequency(freq)
96             self.freq = freq
97         except RuntimeError:
98             pass
99
100     def gainEditText(self):
101         try:
102             gain = float(self.gui.gainEdit.text())
103             self.fg.set_gain(gain)
104             self.gain = gain
105         except ValueError:
106             pass
107                 
108     def bandwidthEditText(self):
109         try:
110             bw = eng_notation.str_to_num(self.gui.bandwidthEdit.text().toAscii())
111             self.fg.set_bandwidth(bw)
112             self.bw = bw
113         except ValueError:
114             pass
115         
116     def amplifierEditText(self):
117         try:
118             amp = float(self.gui.amplifierEdit.text())
119             self.fg.set_amplifier_gain(amp)
120             self.amp = amp
121         except ValueError:
122             pass
123
124     def saveData(self):
125         fileName = QtGui.QFileDialog.getSaveFileName(self, "Save data to file", ".");
126         if(len(fileName)):
127             self.fg.save_to_file(str(fileName))
128
129         
130 def pick_subdevice(u):
131     """
132     The user didn't specify a subdevice on the command line.
133     If there's a daughterboard on A, select A.
134     If there's a daughterboard on B, select B.
135     Otherwise, select A.
136     """
137     if u.db(0, 0).dbid() >= 0:       # dbid is < 0 if there's no d'board or a problem
138         return (0, 0)
139     if u.db(0, 0).dbid() >= 0:
140         return (1, 0)
141     return (0, 0)
142
143 class my_top_block(gr.top_block):
144     def __init__(self):
145         gr.top_block.__init__(self)
146
147         parser = OptionParser(option_class=eng_option)
148         parser.add_option("-w", "--which", type="int", default=0,
149                           help="select which USRP (0, 1, ...) default is %default",
150                           metavar="NUM")
151         parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
152                           help="select USRP Rx side A or B (default=first one with a daughterboard)")
153         parser.add_option("-A", "--antenna", default=None,
154                           help="select Rx Antenna (only on RFX-series boards)")
155         parser.add_option("-W", "--bw", type="float", default=1e6,
156                           help="set bandwidth of receiver [default=%default]")
157         parser.add_option("-f", "--freq", type="eng_float", default=None,
158                           help="set frequency to FREQ", metavar="FREQ")
159         parser.add_option("-g", "--gain", type="eng_float", default=None,
160                           help="set gain in dB [default is midpoint]")
161         parser.add_option("-8", "--width-8", action="store_true", default=False,
162                           help="Enable 8-bit samples across USB")
163         parser.add_option( "--no-hb", action="store_true", default=False,
164                           help="don't use halfband filter in usrp")
165         parser.add_option("-S", "--oscilloscope", action="store_true", default=False,
166                           help="Enable oscilloscope display")
167         parser.add_option("", "--avg-alpha", type="eng_float", default=1e-1,
168                           help="Set fftsink averaging factor, [default=%default]")
169         parser.add_option("", "--ref-scale", type="eng_float", default=13490.0,
170                           help="Set dBFS=0dB input value, [default=%default]")
171         parser.add_option("", "--fft-size", type="int", default=1024,
172                           help="Set FFT frame size, [default=%default]");
173
174         (options, args) = parser.parse_args()
175         if len(args) != 0:
176             parser.print_help()
177             sys.exit(1)
178         self.options = options
179         self.show_debug_info = True
180
181         # Call this before creating the Qt sink
182         self.qapp = QtGui.QApplication(sys.argv)
183
184         self._fftsize = 2048
185
186         self.u = usrp.source_c(which=options.which)
187         self._adc_rate = self.u.converter_rate()
188         self.set_bandwidth(options.bw)
189
190         if options.rx_subdev_spec is None:
191             options.rx_subdev_spec = pick_subdevice(self.u)
192         self._rx_subdev_spec = options.rx_subdev_spec
193         self.u.set_mux(usrp.determine_rx_mux_value(self.u, self._rx_subdev_spec))
194         self.subdev = usrp.selected_subdev(self.u, self._rx_subdev_spec)
195
196         self._gain_range = self.subdev.gain_range()
197         if options.gain is None:
198             # if no gain was specified, use the mid-point in dB
199             g = self._gain_range
200             options.gain = float(g[0]+g[1])/2
201         self.set_gain(options.gain)
202
203         if options.freq is None:
204             # if no frequency was specified, use the mid-point of the subdev
205             f = self.subdev.freq_range()
206             options.freq = float(f[0]+f[1])/2
207         self.set_frequency(options.freq)
208
209         self.snk = qtgui.sink_c(self._fftsize, gr.firdes.WIN_BLACKMAN_hARRIS,
210                                 self._freq, self._bandwidth,
211                                 "USRP Display",
212                                 True, True, False, True, False)
213
214         # Set up internal amplifier
215         self.amp = gr.multiply_const_cc(0.0)
216         self.set_amplifier_gain(0.001)
217
218         # Connect the flow graph
219         self.connect(self.u, self.amp, self.snk)
220
221
222         # Get the reference pointer to the SpectrumDisplayForm QWidget
223         # Wrap the pointer as a PyQt SIP object
224         #     This can now be manipulated as a PyQt4.QtGui.QWidget
225         self.pysink = sip.wrapinstance(self.snk.pyqwidget(), QtGui.QWidget)
226
227         self.main_win = main_window(self.pysink, self)
228
229         self.main_win.set_frequency(self._freq)
230         self.main_win.set_gain(self._gain)
231         self.main_win.set_bandwidth(self._bandwidth)
232
233         self.main_win.show()
234
235     def save_to_file(self, name):
236         # Pause the flow graph
237         self.stop()
238         self.wait()
239
240         # Add file sink to save data
241         self.file_sink = gr.file_sink(gr.sizeof_gr_complex, name)
242         self.connect(self.amp, self.file_sink)
243
244         # Restart flow graph
245         self.start()
246
247     def set_gain(self, gain):
248         self._gain = gain
249         self.subdev.set_gain(self._gain)
250
251     def set_frequency(self, freq):
252         self._freq = freq
253         self.u.tune(0, self.subdev, self._freq)
254
255         try:
256             self.snk.set_frequency_range(self._freq, self._bandwidth)
257         except:
258             pass
259
260     def set_bandwidth(self, bw):
261         self._bandwidth = bw
262         self._decim = int(self._adc_rate / self._bandwidth)
263         self.u.set_decim_rate(self._decim)
264
265         try:
266             self.snk.set_frequency_range(self._freq, self._bandwidth)
267         except:
268             pass
269
270     def set_amplifier_gain(self, amp):
271             self._amp_value = amp
272             self.amp.set_k(self._amp_value)
273
274        
275 if __name__ == "__main__":
276     tb = my_top_block();
277     tb.start()
278     tb.qapp.exec_()