Merging qtdevel2 branch -r10565:10849. This adds a lot of fixes and capabilities...
[debian/gnuradio] / gr-qtgui / src / python / usrp2_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, gru
24 from gnuradio import usrp2
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 from PyQt4 import QtGui, QtCore
30 import sys, sip
31
32 class dialog_box(QtGui.QWidget):
33     def __init__(self, display, control):
34         QtGui.QWidget.__init__(self, None)
35         self.setWindowTitle('USRP2 Display')
36
37         self.boxlayout = QtGui.QBoxLayout(QtGui.QBoxLayout.LeftToRight, self)
38         self.boxlayout.addWidget(display, 1)
39         self.boxlayout.addWidget(control)
40
41         self.resize(800, 500)
42
43 class control_panel(QtGui.QWidget):
44     def __init__(self, usrp, qtsink, parent=None):
45         QtGui.QWidget.__init__(self, parent)
46         self.setWindowTitle('USRP2 Control Panel')
47
48         self.usrp = usrp
49         self.qtsink = qtsink
50         self.adc_rate = self.usrp.adc_rate()
51
52         self.freq = 0
53         self.decim = 0
54         self.bw = 0
55         self.gain = 0
56          
57         self.setToolTip('Set the values of the USRP2')
58         QtGui.QToolTip.setFont(QtGui.QFont('OldEnglish', 10))
59
60         self.layout = QtGui.QFormLayout(self)
61
62         # Received frequency
63         self.freqEdit = QtGui.QLineEdit(self)
64         self.layout.addRow("Frequency:", self.freqEdit)
65         self.connect(self.freqEdit, QtCore.SIGNAL("editingFinished()"),
66                      self.freqEditText)
67
68         # Receiver gain
69         self.gainEdit = QtGui.QLineEdit(self)
70         self.layout.addRow("Gain:", self.gainEdit)
71         self.connect(self.gainEdit, QtCore.SIGNAL("editingFinished()"),
72                      self.gainEditText)
73
74
75         # Decim / Bandwidth
76         self.decimEdit = QtGui.QLineEdit(self)
77         self.layout.addRow("Decim Rate:", self.decimEdit)
78         self.connect(self.decimEdit, QtCore.SIGNAL("editingFinished()"),
79                      self.decimEditText)
80
81         self.quit = QtGui.QPushButton('Close', self)
82         self.layout.addRow(self.quit)
83
84         self.connect(self.quit, QtCore.SIGNAL('clicked()'),
85                      QtGui.qApp, QtCore.SLOT('quit()'))
86
87     def set_frequency(self, freq):
88         self.freq = freq
89         sfreq = eng_notation.num_to_str(self.freq)
90         self.freqEdit.setText(QtCore.QString("%1").arg(sfreq))
91         
92     def set_gain(self, gain):
93         self.gain = gain
94         self.gainEdit.setText(QtCore.QString("%1").arg(self.gain))
95
96     def set_decim(self, decim):
97         self.decim = decim
98         self.bw = self.adc_rate / float(self.decim) / 1000.0
99         self.decimEdit.setText(QtCore.QString("%1").arg(self.decim))
100
101     def freqEditText(self):
102         try:
103             freq = eng_notation.str_to_num(self.freqEdit.text().toAscii())
104             r = self.usrp.set_center_freq(freq)
105             self.freq = freq
106             self.qtsink.set_frequency_range(self.freq, self.freq-self.bw/2.0, self.freq+self.bw/2.0)
107         except RuntimeError:
108             pass
109
110         #self.set_frequency(self.freq)
111
112     def gainEditText(self):
113         try:
114             gain = float(self.gainEdit.text())
115             self.usrp.set_gain(gain)
116             self.gain = gain
117         except ValueError:
118             pass
119         
120         #self.set_gain(gain)
121         
122     def decimEditText(self):
123         try:
124             decim = int(self.decimEdit.text())
125             self.usrp.set_decim(decim)
126
127             self.decim = decim
128             self.bw = self.adc_rate / self.decim
129             self.qtsink.set_frequency_range(-self.bw/2.0, self.bw/2.0, self.freq)           
130             
131         except ValueError:
132             pass
133
134         #self.set_decim(decim)
135         
136 class app_top_block(gr.top_block):
137     def __init__(self):
138         gr.top_block.__init__(self)
139
140         parser = OptionParser(option_class=eng_option)
141         parser.add_option("-e", "--interface", type="string", default="eth0",
142                           help="select Ethernet interface, default is eth0")
143         parser.add_option("-m", "--mac-addr", type="string", default="",
144                           help="select USRP by MAC address, default is auto-select")
145         parser.add_option("-d", "--decim", type="int", default=16,
146                           help="set fgpa decimation rate to DECIM [default=%default]")
147         parser.add_option("-f", "--freq", type="eng_float", default=None,
148                           help="set frequency to FREQ", metavar="FREQ")
149         parser.add_option("-g", "--gain", type="eng_float", default=None,
150                           help="set gain in dB (default is midpoint)")
151         parser.add_option("--fft-size", type="int", default=1024,
152                           help="Set number of FFT bins [default=%default]")
153         (options, args) = parser.parse_args()
154
155         if len(args) != 0:
156             parser.print_help()
157             sys.exit(1)
158         self.options = options
159         self.show_debug_info = True
160         
161         self.qapp = QtGui.QApplication(sys.argv)
162
163         self.u = usrp2.source_32fc(options.interface, options.mac_addr)
164         self.u.set_decim(options.decim)
165         
166         input_rate = self.u.adc_rate() / self.u.decim()
167         
168         self.snk = qtgui.sink_c(options.fft_size, gr.firdes.WIN_BLACKMAN_hARRIS,
169                                 -input_rate/2, input_rate/2,
170                                 "USRP2 Display",
171                                 True, True, False, True, False)
172
173         self.connect(self.u, self.snk)
174
175         if options.gain is None:
176             # if no gain was specified, use the mid-point in dB
177             g = self.u.gain_range()
178             options.gain = float(g[0]+g[1])/2
179
180         if options.freq is None:
181             # if no freq was specified, use the mid-point
182             r = self.u.freq_range()
183             options.freq = float(r[0]+r[1])/2
184             
185         self.set_gain(options.gain)
186         r = self.u.set_center_freq(options.freq)
187
188         if self.show_debug_info:
189             print "Decimation rate: ", self.u.decim()
190             print "Bandwidth: ", input_rate
191             print "D'board: ", self.u.daughterboard_id()
192
193
194         self.ctrl_win = control_panel(self.u, self.snk)
195
196         self.ctrl_win.set_frequency(options.freq)
197         self.ctrl_win.set_gain(options.gain)
198         self.ctrl_win.set_decim(options.decim)
199
200         # Get the reference pointer to the SpectrumDisplayForm QWidget
201         pyQt  = self.snk.pyqwidget()
202
203         # Wrap the pointer as a PyQt SIP object
204         # This can now be manipulated as a PyQt4.QtGui.QWidget
205         pyWin = sip.wrapinstance(pyQt, QtGui.QWidget)
206
207         self.main_box = dialog_box(pyWin, self.ctrl_win)
208
209         self.main_box.show()
210
211     def set_gain(self, gain):
212         self.u.set_gain(gain)
213
214     def set_decim(self, decim):
215         ok = self.u.set_decim(decim)
216         if not ok:
217             print "set_decim failed"
218         input_rate = self.u.adc_rate() / self.u.decim()
219         return ok
220
221 def main ():
222     tb = app_top_block()
223     tb.start()
224     tb.snk.exec_();
225
226 if __name__ == '__main__':
227     try:
228         main ()
229     except KeyboardInterrupt:
230         pass
231