diff options
author | trondeau | 2009-04-15 03:49:04 +0000 |
---|---|---|
committer | trondeau | 2009-04-15 03:49:04 +0000 |
commit | 322e065b19c922e2a9cc1710876e32d100453181 (patch) | |
tree | acc0c5d9643fd647d128ca4215147eef79189af3 /gr-qtgui/src/python | |
parent | ae5fa9430882f5140a3c9a9b61e4a5f7c4ed9127 (diff) | |
download | gnuradio-322e065b19c922e2a9cc1710876e32d100453181.tar.gz gnuradio-322e065b19c922e2a9cc1710876e32d100453181.tar.bz2 gnuradio-322e065b19c922e2a9cc1710876e32d100453181.zip |
Merging qtdevel2 branch -r10565:10849. This adds a lot of fixes and capabilities to the qtgui package. Most importantly, it allows interaction between PyQt and the C++ Qt routines in the gnuradio library.
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@10850 221aa14e-8319-0410-a670-987f0aec2ac5
Diffstat (limited to 'gr-qtgui/src/python')
-rw-r--r-- | gr-qtgui/src/python/Makefile.am | 11 | ||||
-rwxr-xr-x | gr-qtgui/src/python/pyqt_example.py | 144 | ||||
-rwxr-xr-x | gr-qtgui/src/python/pyqt_example_f.py | 143 | ||||
-rwxr-xr-x | gr-qtgui/src/python/qt_digital.py | 134 | ||||
-rwxr-xr-x | gr-qtgui/src/python/qttest_c.py | 37 | ||||
-rwxr-xr-x | gr-qtgui/src/python/qttest_f.py | 29 | ||||
-rwxr-xr-x | gr-qtgui/src/python/usrp2_display.py | 231 | ||||
-rwxr-xr-x | gr-qtgui/src/python/usrp_display.py | 208 |
8 files changed, 856 insertions, 81 deletions
diff --git a/gr-qtgui/src/python/Makefile.am b/gr-qtgui/src/python/Makefile.am index ad5787344..163b84a96 100644 --- a/gr-qtgui/src/python/Makefile.am +++ b/gr-qtgui/src/python/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2004,2009 Free Software Foundation, Inc. +# Copyright 2008,2009 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -21,9 +21,12 @@ include $(top_srcdir)/Makefile.common -noinst_PYTHON = \ - qttest_f.py \ - qttest_c.py +noinst_PYTHON = \ + pyqt_example_f.py \ + pyqt_example.py \ + qt_digital.py \ + usrp2_display.py \ + usrp_display.py qtguipythondir = $(grpythondir)/qtgui diff --git a/gr-qtgui/src/python/pyqt_example.py b/gr-qtgui/src/python/pyqt_example.py new file mode 100755 index 000000000..27b949c81 --- /dev/null +++ b/gr-qtgui/src/python/pyqt_example.py @@ -0,0 +1,144 @@ +#!/usr/bin/env python + +from gnuradio import gr, blks2 +from gnuradio.qtgui import qtgui +from PyQt4 import QtGui, QtCore +import sys, sip + +class dialog_box(QtGui.QWidget): + def __init__(self, display, control): + QtGui.QWidget.__init__(self, None) + self.setWindowTitle('PyQt Test GUI') + + self.boxlayout = QtGui.QBoxLayout(QtGui.QBoxLayout.LeftToRight, self) + self.boxlayout.addWidget(display, 1) + self.boxlayout.addWidget(control) + + self.resize(800, 500) + +class control_box(QtGui.QWidget): + def __init__(self, parent=None): + QtGui.QWidget.__init__(self, parent) + self.setWindowTitle('Control Panel') + + self.setToolTip('Control the signals') + QtGui.QToolTip.setFont(QtGui.QFont('OldEnglish', 10)) + + self.layout = QtGui.QFormLayout(self) + + # Control the first signal + self.freq1Edit = QtGui.QLineEdit(self) + self.layout.addRow("Signal 1 Frequency:", self.freq1Edit) + self.connect(self.freq1Edit, QtCore.SIGNAL("editingFinished()"), + self.freq1EditText) + + self.amp1Edit = QtGui.QLineEdit(self) + self.layout.addRow("Signal 1 Amplitude:", self.amp1Edit) + self.connect(self.amp1Edit, QtCore.SIGNAL("editingFinished()"), + self.amp1EditText) + + + # Control the second signal + self.freq2Edit = QtGui.QLineEdit(self) + self.layout.addRow("Signal 2 Frequency:", self.freq2Edit) + self.connect(self.freq2Edit, QtCore.SIGNAL("editingFinished()"), + self.freq2EditText) + + + self.amp2Edit = QtGui.QLineEdit(self) + self.layout.addRow("Signal 2 Amplitude:", self.amp2Edit) + self.connect(self.amp2Edit, QtCore.SIGNAL("editingFinished()"), + self.amp2EditText) + + self.quit = QtGui.QPushButton('Close', self) + self.layout.addWidget(self.quit) + + self.connect(self.quit, QtCore.SIGNAL('clicked()'), + QtGui.qApp, QtCore.SLOT('quit()')) + + def attach_signal1(self, signal): + self.signal1 = signal + self.freq1Edit.setText(QtCore.QString("%1").arg(self.signal1.frequency())) + self.amp1Edit.setText(QtCore.QString("%1").arg(self.signal1.amplitude())) + + def attach_signal2(self, signal): + self.signal2 = signal + self.freq2Edit.setText(QtCore.QString("%1").arg(self.signal2.frequency())) + self.amp2Edit.setText(QtCore.QString("%1").arg(self.signal2.amplitude())) + + def freq1EditText(self): + try: + newfreq = float(self.freq1Edit.text()) + self.signal1.set_frequency(newfreq) + except ValueError: + print "Bad frequency value entered" + + def amp1EditText(self): + try: + newamp = float(self.amp1Edit.text()) + self.signal1.set_amplitude(newamp) + except ValueError: + print "Bad amplitude value entered" + + + def freq2EditText(self): + try: + newfreq = float(self.freq2Edit.text()) + self.signal2.set_frequency(newfreq) + except ValueError: + print "Bad frequency value entered" + + def amp2EditText(self): + try: + newamp = float(self.amp2Edit.text()) + self.signal2.set_amplitude(newamp) + except ValueError: + print "Bad amplitude value entered" + + +class my_top_block(gr.top_block): + def __init__(self): + gr.top_block.__init__(self) + + Rs = 8000 + f1 = 1000 + f2 = 2000 + + fftsize = 2048 + + self.qapp = QtGui.QApplication(sys.argv) + + src1 = gr.sig_source_c(Rs, gr.GR_SIN_WAVE, f1, 0.1, 0) + src2 = gr.sig_source_c(Rs, gr.GR_SIN_WAVE, f2, 0.1, 0) + src = gr.add_cc() + channel = blks2.channel_model(0.001) + thr = gr.throttle(gr.sizeof_gr_complex, 100*fftsize) + self.snk1 = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, + -Rs/2, Rs/2, + "Complex Signal Example", + True, True, False, True, False) + + self.connect(src1, (src,0)) + self.connect(src2, (src,1)) + self.connect(src, channel, thr, self.snk1) + + self.ctrl_win = control_box() + self.ctrl_win.attach_signal1(src1) + self.ctrl_win.attach_signal2(src2) + + # Get the reference pointer to the SpectrumDisplayForm QWidget + pyQt = self.snk1.pyqwidget() + + # Wrap the pointer as a PyQt SIP object + # This can now be manipulated as a PyQt4.QtGui.QWidget + pyWin = sip.wrapinstance(pyQt, QtGui.QWidget) + + self.main_box = dialog_box(pyWin, self.ctrl_win) + + self.main_box.show() + +if __name__ == "__main__": + tb = my_top_block(); + tb.start() + tb.qapp.exec_() + diff --git a/gr-qtgui/src/python/pyqt_example_f.py b/gr-qtgui/src/python/pyqt_example_f.py new file mode 100755 index 000000000..bf10c5c0e --- /dev/null +++ b/gr-qtgui/src/python/pyqt_example_f.py @@ -0,0 +1,143 @@ +#!/usr/bin/env python + +from gnuradio import gr, blks2 +from gnuradio.qtgui import qtgui +from PyQt4 import QtGui, QtCore +import sys, sip + +class dialog_box(QtGui.QWidget): + def __init__(self, display, control): + QtGui.QWidget.__init__(self, None) + self.setWindowTitle('PyQt Test GUI') + + self.boxlayout = QtGui.QBoxLayout(QtGui.QBoxLayout.LeftToRight, self) + self.boxlayout.addWidget(display, 1) + self.boxlayout.addWidget(control) + + self.resize(800, 500) + +class control_box(QtGui.QWidget): + def __init__(self, parent=None): + QtGui.QWidget.__init__(self, parent) + self.setWindowTitle('Control Panel') + + self.setToolTip('Control the signals') + QtGui.QToolTip.setFont(QtGui.QFont('OldEnglish', 10)) + + self.layout = QtGui.QFormLayout(self) + + # Control the first signal + self.freq1Edit = QtGui.QLineEdit(self) + self.layout.addRow("Signal 1 Frequency:", self.freq1Edit) + self.connect(self.freq1Edit, QtCore.SIGNAL("editingFinished()"), + self.freq1EditText) + + self.amp1Edit = QtGui.QLineEdit(self) + self.layout.addRow("Signal 1 Amplitude:", self.amp1Edit) + self.connect(self.amp1Edit, QtCore.SIGNAL("editingFinished()"), + self.amp1EditText) + + + # Control the second signal + self.freq2Edit = QtGui.QLineEdit(self) + self.layout.addRow("Signal 2 Frequency:", self.freq2Edit) + self.connect(self.freq2Edit, QtCore.SIGNAL("editingFinished()"), + self.freq2EditText) + + + self.amp2Edit = QtGui.QLineEdit(self) + self.layout.addRow("Signal 2 Amplitude:", self.amp2Edit) + self.connect(self.amp2Edit, QtCore.SIGNAL("editingFinished()"), + self.amp2EditText) + + self.quit = QtGui.QPushButton('Close', self) + self.layout.addWidget(self.quit) + + self.connect(self.quit, QtCore.SIGNAL('clicked()'), + QtGui.qApp, QtCore.SLOT('quit()')) + + def attach_signal1(self, signal): + self.signal1 = signal + self.freq1Edit.setText(QtCore.QString("%1").arg(self.signal1.frequency())) + self.amp1Edit.setText(QtCore.QString("%1").arg(self.signal1.amplitude())) + + def attach_signal2(self, signal): + self.signal2 = signal + self.freq2Edit.setText(QtCore.QString("%1").arg(self.signal2.frequency())) + self.amp2Edit.setText(QtCore.QString("%1").arg(self.signal2.amplitude())) + + def freq1EditText(self): + try: + newfreq = float(self.freq1Edit.text()) + self.signal1.set_frequency(newfreq) + except ValueError: + print "Bad frequency value entered" + + def amp1EditText(self): + try: + newamp = float(self.amp1Edit.text()) + self.signal1.set_amplitude(newamp) + except ValueError: + print "Bad amplitude value entered" + + + def freq2EditText(self): + try: + newfreq = float(self.freq2Edit.text()) + self.signal2.set_frequency(newfreq) + except ValueError: + print "Bad frequency value entered" + + def amp2EditText(self): + try: + newamp = float(self.amp2Edit.text()) + self.signal2.set_amplitude(newamp) + except ValueError: + print "Bad amplitude value entered" + + +class my_top_block(gr.top_block): + def __init__(self): + gr.top_block.__init__(self) + + Rs = 8000 + f1 = 1000 + f2 = 2000 + + fftsize = 2048 + + self.qapp = QtGui.QApplication(sys.argv) + + src1 = gr.sig_source_f(Rs, gr.GR_SIN_WAVE, f1, 0.1, 0) + src2 = gr.sig_source_f(Rs, gr.GR_SIN_WAVE, f2, 0.1, 0) + src = gr.add_ff() + thr = gr.throttle(gr.sizeof_float, 100*fftsize) + self.snk1 = qtgui.sink_f(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, + -Rs/2, Rs/2, + "Float Signal Example", + True, True, False, True, False) + + self.connect(src1, (src,0)) + self.connect(src2, (src,1)) + self.connect(src, thr, self.snk1) + + self.ctrl_win = control_box() + self.ctrl_win.attach_signal1(src1) + self.ctrl_win.attach_signal2(src2) + + # Get the reference pointer to the SpectrumDisplayForm QWidget + pyQt = self.snk1.pyqwidget() + + # Wrap the pointer as a PyQt SIP object + # This can now be manipulated as a PyQt4.QtGui.QWidget + pyWin = sip.wrapinstance(pyQt, QtGui.QWidget) + + self.main_box = dialog_box(pyWin, self.ctrl_win) + + self.main_box.show() + +if __name__ == "__main__": + tb = my_top_block(); + tb.start() + tb.qapp.exec_() + diff --git a/gr-qtgui/src/python/qt_digital.py b/gr-qtgui/src/python/qt_digital.py index f7635b4a5..55be56b17 100755 --- a/gr-qtgui/src/python/qt_digital.py +++ b/gr-qtgui/src/python/qt_digital.py @@ -2,12 +2,109 @@ from gnuradio import gr, blks2 from gnuradio.qtgui import qtgui +from PyQt4 import QtGui, QtCore +import sys, sip import scipy +class dialog_box(QtGui.QWidget): + def __init__(self, display_tx, display_rx, channel): + QtGui.QWidget.__init__(self, None) + self.setWindowTitle('Digital Signal Examples') + + self.control = control_panel(channel, self) + + hlayout = QtGui.QHBoxLayout() + hlayout.addWidget(display_tx) + hlayout.addWidget(display_rx) + hlayout.setGeometry(QtCore.QRect(0,0,100,100)) + + vlayout = QtGui.QVBoxLayout() + vlayout.addLayout(hlayout) + vlayout.addLayout(self.control.layout, -1) + #vlayout.addStretch(-1) + + self.setLayout(vlayout) + self.resize(1000, 1000) + +class control_panel(QtGui.QWidget): + def __init__(self, channel, parent=None): + QtGui.QWidget.__init__(self, parent) + self.setWindowTitle('Control Panel') + + self.channel = channel + + self.layout = QtGui.QFormLayout() + + # Set channel noise + self.noiseEdit = QtGui.QLineEdit(self) + self.layout.addRow("Noise Amplitude:", self.noiseEdit) + self.connect(self.noiseEdit, QtCore.SIGNAL("editingFinished()"), + self.noiseEditText) + + # Set channel frequency offset + self.freqEdit = QtGui.QLineEdit(self) + self.layout.addRow("Frequency Offset:", self.freqEdit) + self.connect(self.freqEdit, QtCore.SIGNAL("editingFinished()"), + self.freqEditText) + + # Set channel timing offset + self.timeEdit = QtGui.QLineEdit(self) + self.layout.addRow("Timing Offset:", self.timeEdit) + self.connect(self.timeEdit, QtCore.SIGNAL("editingFinished()"), + self.timeEditText) + + self.quit = QtGui.QPushButton('Close', self) + self.layout.addRow(self.quit) + + self.connect(self.quit, QtCore.SIGNAL('clicked()'), + QtGui.qApp, QtCore.SLOT('quit()')) + + def set_noise(self, noise): + self.noise = noise + self.noiseEdit.setText(QtCore.QString("%1").arg(self.noise)) + + def set_frequency(self, freq): + self.freq = freq + self.freqEdit.setText(QtCore.QString("%1").arg(self.freq)) + + def set_time_offset(self, to): + self.timing_offset = to + self.timeEdit.setText(QtCore.QString("%1").arg(self.timing_offset)) + + def noiseEditText(self): + try: + noise = self.noiseEdit.text().toDouble()[0] + self.channel.noise.set_amplitude(noise) + + self.noise = noise + except RuntimeError: + pass + + def freqEditText(self): + try: + freq = self.freqEdit.text().toDouble()[0] + self.channel.freq_offset.set_frequency(freq) + + self.freq = freq + except RuntimeError: + pass + + def timeEditText(self): + try: + to = self.timeEdit.text().toDouble()[0] + self.channel.timing_offset.set_interp_ratio(to) + + self.timing_offset = to + except RuntimeError: + pass + + class my_top_block(gr.top_block): def __init__(self): gr.top_block.__init__(self) + self.qapp = QtGui.QApplication(sys.argv) + sps = 2 excess_bw = 0.35 gray_code = True @@ -20,21 +117,36 @@ class my_top_block(gr.top_block): rrctaps = gr.firdes.root_raised_cosine(1, sps, 1, excess_bw, 21) rx_rrc = gr.fir_filter_ccf(sps, rrctaps) - + + noise = 1e-7 + fo = 1e-6 + to = 1.0 + channel = blks2.channel_model(noise, fo, to) + thr = gr.throttle(gr.sizeof_gr_complex, 10*fftsize) - self.snk_tx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, -1/2, 1/2) - self.snk_rx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, -1/2, 1/2) + self.snk_tx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, -1/2, 1/2, + "Tx", True, True, False, True, True) + + self.snk_rx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, -1/2, 1/2, + "Rx", True, True, False, True, True) - self.connect(src, mod, self.snk_tx) - self.connect(mod, rx_rrc, thr, self.snk_rx) + self.connect(src, mod, channel, self.snk_tx) + self.connect(channel, rx_rrc, thr, self.snk_rx) - self.snk_tx.initialize() - qapp = self.snk_tx.get_qapplication() - self.snk_rx.initialize(qapp) + pyTxQt = self.snk_tx.pyqwidget() + pyTx = sip.wrapinstance(pyTxQt, QtGui.QWidget) + pyRxQt = self.snk_rx.pyqwidget() + pyRx = sip.wrapinstance(pyRxQt, QtGui.QWidget) + + self.main_box = dialog_box(pyTx, pyRx, channel) + self.main_box.control.set_noise(noise) + self.main_box.control.set_frequency(fo) + self.main_box.control.set_time_offset(to) + + self.main_box.show() + if __name__ == "__main__": tb = my_top_block(); tb.start() - tb.snk_tx.start_app(); - #tb.wait(); - + tb.qapp.exec_() diff --git a/gr-qtgui/src/python/qttest_c.py b/gr-qtgui/src/python/qttest_c.py deleted file mode 100755 index c681c84a3..000000000 --- a/gr-qtgui/src/python/qttest_c.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env python - -from gnuradio import gr -from gnuradio.qtgui import qtgui - -class my_top_block(gr.top_block): - def __init__(self): - gr.top_block.__init__(self) - - Rs = 8000 - f1 = 1000 - f2 = 2000 - - fftsize = 2048 - - src1 = gr.sig_source_c(Rs, gr.GR_SIN_WAVE, f1, 0.1, 0) - src2 = gr.sig_source_c(Rs, gr.GR_SIN_WAVE, f2, 0.1, 0) - src = gr.add_cc() - thr = gr.throttle(gr.sizeof_gr_complex, 20*fftsize) - self.snk1 = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, -Rs/2, Rs/2) - self.snk2 = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, -Rs/2, Rs/2) - - self.connect(src1, (src,0)) - self.connect(src2, (src,1)) - self.connect(src, thr, self.snk1) - self.connect(src1, self.snk2) - - self.snk1.initialize() - qapp = self.snk1.get_qapplication() - self.snk2.initialize(qapp) - -if __name__ == "__main__": - tb = my_top_block(); - tb.start() - tb.snk1.start_app(); - #tb.wait(); - diff --git a/gr-qtgui/src/python/qttest_f.py b/gr-qtgui/src/python/qttest_f.py deleted file mode 100755 index a950b35b1..000000000 --- a/gr-qtgui/src/python/qttest_f.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env python - -from gnuradio import gr -from gnuradio.qtgui import qtgui - -class my_top_block(gr.top_block): - def __init__(self): - gr.top_block.__init__(self) - - fftsize = 8192 - - win = gr.firdes.window(gr.firdes.WIN_HANN, fftsize, 0) - - src1 = gr.sig_source_f(1, gr.GR_SIN_WAVE, 0.1, 0.1, 0) - src2 = gr.sig_source_f(1, gr.GR_SIN_WAVE, 0.015, 0.1, 0) - src = gr.add_ff() - thr = gr.throttle(gr.sizeof_float, 20*fftsize) - self.snk = qtgui.sink_f(fftsize, win, -0.5, 0.5) - - self.connect(src1, (src,0)) - self.connect(src2, (src,1)) - self.connect(src, thr, self.snk) - -if __name__ == "__main__": - tb = my_top_block(); - tb.start() - tb.snk.start_app(); - #tb.wait(); - diff --git a/gr-qtgui/src/python/usrp2_display.py b/gr-qtgui/src/python/usrp2_display.py new file mode 100755 index 000000000..e5f01ef0e --- /dev/null +++ b/gr-qtgui/src/python/usrp2_display.py @@ -0,0 +1,231 @@ +#!/usr/bin/env python +# +# Copyright 2009 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gru +from gnuradio import usrp2 +from gnuradio import eng_notation +from gnuradio.eng_option import eng_option +from gnuradio.qtgui import qtgui +from optparse import OptionParser +from PyQt4 import QtGui, QtCore +import sys, sip + +class dialog_box(QtGui.QWidget): + def __init__(self, display, control): + QtGui.QWidget.__init__(self, None) + self.setWindowTitle('USRP2 Display') + + self.boxlayout = QtGui.QBoxLayout(QtGui.QBoxLayout.LeftToRight, self) + self.boxlayout.addWidget(display, 1) + self.boxlayout.addWidget(control) + + self.resize(800, 500) + +class control_panel(QtGui.QWidget): + def __init__(self, usrp, qtsink, parent=None): + QtGui.QWidget.__init__(self, parent) + self.setWindowTitle('USRP2 Control Panel') + + self.usrp = usrp + self.qtsink = qtsink + self.adc_rate = self.usrp.adc_rate() + + self.freq = 0 + self.decim = 0 + self.bw = 0 + self.gain = 0 + + self.setToolTip('Set the values of the USRP2') + QtGui.QToolTip.setFont(QtGui.QFont('OldEnglish', 10)) + + self.layout = QtGui.QFormLayout(self) + + # Received frequency + self.freqEdit = QtGui.QLineEdit(self) + self.layout.addRow("Frequency:", self.freqEdit) + self.connect(self.freqEdit, QtCore.SIGNAL("editingFinished()"), + self.freqEditText) + + # Receiver gain + self.gainEdit = QtGui.QLineEdit(self) + self.layout.addRow("Gain:", self.gainEdit) + self.connect(self.gainEdit, QtCore.SIGNAL("editingFinished()"), + self.gainEditText) + + + # Decim / Bandwidth + self.decimEdit = QtGui.QLineEdit(self) + self.layout.addRow("Decim Rate:", self.decimEdit) + self.connect(self.decimEdit, QtCore.SIGNAL("editingFinished()"), + self.decimEditText) + + self.quit = QtGui.QPushButton('Close', self) + self.layout.addRow(self.quit) + + self.connect(self.quit, QtCore.SIGNAL('clicked()'), + QtGui.qApp, QtCore.SLOT('quit()')) + + def set_frequency(self, freq): + self.freq = freq + sfreq = eng_notation.num_to_str(self.freq) + self.freqEdit.setText(QtCore.QString("%1").arg(sfreq)) + + def set_gain(self, gain): + self.gain = gain + self.gainEdit.setText(QtCore.QString("%1").arg(self.gain)) + + def set_decim(self, decim): + self.decim = decim + self.bw = self.adc_rate / float(self.decim) / 1000.0 + self.decimEdit.setText(QtCore.QString("%1").arg(self.decim)) + + def freqEditText(self): + try: + freq = eng_notation.str_to_num(self.freqEdit.text().toAscii()) + r = self.usrp.set_center_freq(freq) + self.freq = freq + self.qtsink.set_frequency_range(self.freq, self.freq-self.bw/2.0, self.freq+self.bw/2.0) + except RuntimeError: + pass + + #self.set_frequency(self.freq) + + def gainEditText(self): + try: + gain = float(self.gainEdit.text()) + self.usrp.set_gain(gain) + self.gain = gain + except ValueError: + pass + + #self.set_gain(gain) + + def decimEditText(self): + try: + decim = int(self.decimEdit.text()) + self.usrp.set_decim(decim) + + self.decim = decim + self.bw = self.adc_rate / self.decim + self.qtsink.set_frequency_range(-self.bw/2.0, self.bw/2.0, self.freq) + + except ValueError: + pass + + #self.set_decim(decim) + +class app_top_block(gr.top_block): + def __init__(self): + gr.top_block.__init__(self) + + parser = OptionParser(option_class=eng_option) + parser.add_option("-e", "--interface", type="string", default="eth0", + help="select Ethernet interface, default is eth0") + parser.add_option("-m", "--mac-addr", type="string", default="", + help="select USRP by MAC address, default is auto-select") + parser.add_option("-d", "--decim", type="int", default=16, + help="set fgpa decimation rate to DECIM [default=%default]") + parser.add_option("-f", "--freq", type="eng_float", default=None, + help="set frequency to FREQ", metavar="FREQ") + parser.add_option("-g", "--gain", type="eng_float", default=None, + help="set gain in dB (default is midpoint)") + parser.add_option("--fft-size", type="int", default=1024, + help="Set number of FFT bins [default=%default]") + (options, args) = parser.parse_args() + + if len(args) != 0: + parser.print_help() + sys.exit(1) + self.options = options + self.show_debug_info = True + + self.qapp = QtGui.QApplication(sys.argv) + + self.u = usrp2.source_32fc(options.interface, options.mac_addr) + self.u.set_decim(options.decim) + + input_rate = self.u.adc_rate() / self.u.decim() + + self.snk = qtgui.sink_c(options.fft_size, gr.firdes.WIN_BLACKMAN_hARRIS, + -input_rate/2, input_rate/2, + "USRP2 Display", + True, True, False, True, False) + + self.connect(self.u, self.snk) + + if options.gain is None: + # if no gain was specified, use the mid-point in dB + g = self.u.gain_range() + options.gain = float(g[0]+g[1])/2 + + if options.freq is None: + # if no freq was specified, use the mid-point + r = self.u.freq_range() + options.freq = float(r[0]+r[1])/2 + + self.set_gain(options.gain) + r = self.u.set_center_freq(options.freq) + + if self.show_debug_info: + print "Decimation rate: ", self.u.decim() + print "Bandwidth: ", input_rate + print "D'board: ", self.u.daughterboard_id() + + + self.ctrl_win = control_panel(self.u, self.snk) + + self.ctrl_win.set_frequency(options.freq) + self.ctrl_win.set_gain(options.gain) + self.ctrl_win.set_decim(options.decim) + + # Get the reference pointer to the SpectrumDisplayForm QWidget + pyQt = self.snk.pyqwidget() + + # Wrap the pointer as a PyQt SIP object + # This can now be manipulated as a PyQt4.QtGui.QWidget + pyWin = sip.wrapinstance(pyQt, QtGui.QWidget) + + self.main_box = dialog_box(pyWin, self.ctrl_win) + + self.main_box.show() + + def set_gain(self, gain): + self.u.set_gain(gain) + + def set_decim(self, decim): + ok = self.u.set_decim(decim) + if not ok: + print "set_decim failed" + input_rate = self.u.adc_rate() / self.u.decim() + return ok + +def main (): + tb = app_top_block() + tb.start() + tb.snk.exec_(); + +if __name__ == '__main__': + try: + main () + except KeyboardInterrupt: + pass + diff --git a/gr-qtgui/src/python/usrp_display.py b/gr-qtgui/src/python/usrp_display.py new file mode 100755 index 000000000..d5d2bc67d --- /dev/null +++ b/gr-qtgui/src/python/usrp_display.py @@ -0,0 +1,208 @@ +#!/usr/bin/env python + +from gnuradio import gr +from gnuradio import usrp +from gnuradio import eng_notation +from gnuradio.eng_option import eng_option +from gnuradio.qtgui import qtgui +from optparse import OptionParser +from PyQt4 import QtGui, QtCore +import sys, sip + +class dialog_box(QtGui.QWidget): + def __init__(self, display, control): + QtGui.QWidget.__init__(self, None) + self.setWindowTitle('USRP FFT') + + self.boxlayout = QtGui.QBoxLayout(QtGui.QBoxLayout.LeftToRight, self) + self.boxlayout.addWidget(display, 1) + self.boxlayout.addWidget(control) + + self.resize(800, 500) + +class control_panel(QtGui.QWidget): + def __init__(self, usrp, subdev, qtsink, parent=None): + QtGui.QWidget.__init__(self, parent) + self.setWindowTitle('USRP Control Panel') + + self.usrp = usrp + self.subdev = subdev + self.qtsink = qtsink + self.adc_rate = self.usrp.converter_rate() + + self.freq = 0 + self.decim = 0 + self.bw = 0 + self.gain = 0 + + self.setToolTip('Set the values of the USRP') + QtGui.QToolTip.setFont(QtGui.QFont('OldEnglish', 10)) + + self.layout = QtGui.QFormLayout(self) + + # Received frequency + self.freqEdit = QtGui.QLineEdit(self) + self.layout.addRow("Frequency:", self.freqEdit) + self.connect(self.freqEdit, QtCore.SIGNAL("editingFinished()"), + self.freqEditText) + + # Receiver gain + self.gainEdit = QtGui.QLineEdit(self) + self.layout.addRow("Gain:", self.gainEdit) + self.connect(self.gainEdit, QtCore.SIGNAL("editingFinished()"), + self.gainEditText) + + + # Decim / Bandwidth + self.decimEdit = QtGui.QLineEdit(self) + self.layout.addRow("Decim Rate:", self.decimEdit) + self.connect(self.decimEdit, QtCore.SIGNAL("editingFinished()"), + self.decimEditText) + + self.quit = QtGui.QPushButton('Close', self) + self.layout.addRow(self.quit) + + self.connect(self.quit, QtCore.SIGNAL('clicked()'), + QtGui.qApp, QtCore.SLOT('quit()')) + + def set_frequency(self, freq): + self.freq = freq + sfreq = eng_notation.num_to_str(self.freq) + self.freqEdit.setText(QtCore.QString("%1").arg(sfreq)) + + def set_gain(self, gain): + self.gain = gain + self.gainEdit.setText(QtCore.QString("%1").arg(self.gain)) + + def set_decim(self, decim): + self.decim = decim + self.bw = self.adc_rate / float(self.decim) / 1000.0 + self.decimEdit.setText(QtCore.QString("%1").arg(self.decim)) + + def freqEditText(self): + try: + freq = eng_notation.str_to_num(self.freqEdit.text().toAscii()) + self.usrp.tune(0, self.subdev, freq) + self.freq = freq + self.qtsink.set_frequency_range(self.freq, self.freq-self.bw/2.0, self.freq+self.bw/2.0) + except RuntimeError: + pass + + #self.set_frequency(self.freq) + + def gainEditText(self): + try: + gain = float(self.gainEdit.text()) + self.subdev.set_gain(gain) + self.gain = gain + except ValueError: + pass + + #self.set_gain(gain) + + def decimEditText(self): + try: + decim = int(self.decimEdit.text()) + self.usrp.set_decim_rate(decim) + + self.decim = decim + self.bw = self.adc_rate / self.decim + self.qtsink.set_frequency_range(-self.bw/2.0, self.bw/2.0, self.freq) + + except ValueError: + pass + + #self.set_decim(decim) + + +class my_top_block(gr.top_block): + def __init__(self): + gr.top_block.__init__(self) + + parser = OptionParser(option_class=eng_option) + parser.add_option("-w", "--which", type="int", default=0, + help="select which USRP (0, 1, ...) default is %default", + metavar="NUM") + parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, + help="select USRP Rx side A or B (default=first one with a daughterboard)") + parser.add_option("-A", "--antenna", default=None, + help="select Rx Antenna (only on RFX-series boards)") + parser.add_option("-d", "--decim", type="int", default=16, + help="set fgpa decimation rate to DECIM [default=%default]") + parser.add_option("-f", "--freq", type="eng_float", default=None, + help="set frequency to FREQ", metavar="FREQ") + parser.add_option("-g", "--gain", type="eng_float", default=None, + help="set gain in dB [default is midpoint]") + parser.add_option("-W", "--waterfall", action="store_true", default=False, + help="Enable waterfall display") + parser.add_option("-8", "--width-8", action="store_true", default=False, + help="Enable 8-bit samples across USB") + parser.add_option( "--no-hb", action="store_true", default=False, + help="don't use halfband filter in usrp") + parser.add_option("-S", "--oscilloscope", action="store_true", default=False, + help="Enable oscilloscope display") + parser.add_option("", "--avg-alpha", type="eng_float", default=1e-1, + help="Set fftsink averaging factor, [default=%default]") + parser.add_option("", "--ref-scale", type="eng_float", default=13490.0, + help="Set dBFS=0dB input value, [default=%default]") + parser.add_option("", "--fft-size", type="int", default=1024, + help="Set FFT frame size, [default=%default]"); + + (options, args) = parser.parse_args() + if len(args) != 0: + parser.print_help() + sys.exit(1) + self.options = options + self.show_debug_info = True + + # Call this before creating the Qt sink + self.qapp = QtGui.QApplication(sys.argv) + + self.u = usrp.source_c(which=options.which, decim_rate=options.decim) + rx_subdev_spec = (0,0) + self.u.set_mux(usrp.determine_rx_mux_value(self.u, rx_subdev_spec)) + self.subdev = usrp.selected_subdev(self.u, rx_subdev_spec) + + if options.gain is None: + # if no gain was specified, use the mid-point in dB + g = self.subdev.gain_range() + options.gain = float(g[0]+g[1])/2 + self.subdev.set_gain(options.gain) + + if options.freq is None: + # if no frequency was specified, use the mid-point of the subdev + f = self.subdev.freq_range() + options.freq = float(f[0]+f[1])/2 + self.u.tune(0, self.subdev, options.freq) + + fftsize = 2048 + input_rate = self.u.converter_rate() / self.u.decim_rate() + self.snk = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, + -input_rate/2, input_rate/2, + "USRP Display", + True, True, False, True, False) + + amp = gr.multiply_const_cc(0.001) + self.connect(self.u, amp, self.snk) + + self.ctrl_win = control_panel(self.u, self.subdev, self.snk) + + self.ctrl_win.set_frequency(options.freq) + self.ctrl_win.set_gain(options.gain) + self.ctrl_win.set_decim(options.decim) + + # Get the reference pointer to the SpectrumDisplayForm QWidget + pyQt = self.snk.pyqwidget() + + # Wrap the pointer as a PyQt SIP object + # This can now be manipulated as a PyQt4.QtGui.QWidget + pyWin = sip.wrapinstance(pyQt, QtGui.QWidget) + + self.main_box = dialog_box(pyWin, self.ctrl_win) + + self.main_box.show() + +if __name__ == "__main__": + tb = my_top_block(); + tb.start() + tb.qapp.exec_() |