diff options
Diffstat (limited to 'gnuradio-examples/python/usrp2/usrp2_wfm_qt.py')
-rwxr-xr-x | gnuradio-examples/python/usrp2/usrp2_wfm_qt.py | 352 |
1 files changed, 352 insertions, 0 deletions
diff --git a/gnuradio-examples/python/usrp2/usrp2_wfm_qt.py b/gnuradio-examples/python/usrp2/usrp2_wfm_qt.py new file mode 100755 index 0000000000..0be21ceb98 --- /dev/null +++ b/gnuradio-examples/python/usrp2/usrp2_wfm_qt.py @@ -0,0 +1,352 @@ +#!/usr/bin/env python +# +# Copyright 2005,2006,2007,2008,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, eng_notation, optfir +from gnuradio import audio +from gnuradio import usrp2 +from gnuradio import blks2 +from gnuradio.eng_option import eng_option +from optparse import OptionParser +import sys +import math + + +try: + from gnuradio.qtgui import qtgui + from PyQt4 import QtGui, QtCore + import sip +except ImportError: + print "Please install gr-qtgui." + sys.exit(1) + +try: + from qt_wfm_interface import Ui_InterfaceWindow +except ImportError: + print "Error: could not find qt_wfm_interface.py:" + print "\tPlease run: \"pyuic4 qt_wfm_interface.ui -o qt_wfm_interface.py\"" + sys.exit(1) + +print "This program is not in a proper working state. Comment this out if you want to play." +sys.exit(1) + + +# //////////////////////////////////////////////////////////////////// +# Define the QT Interface and Control Dialog +# //////////////////////////////////////////////////////////////////// + + +class dialog_box(QtGui.QMainWindow): + def __init__(self, snk_usrp, snk_vol, fg, parent=None): + + QtGui.QWidget.__init__(self, parent) + self.gui = Ui_InterfaceWindow() + self.gui.setupUi(self) + + self.fg = fg + + # Set USRP parameters + self.set_bw(self.fg.usrp_bw()) + self.set_freq(self.fg.freq()) + self.set_gain(self.fg.gain()) + self.set_volume(self.fg.volume()) + + # Add the qtsnk widgets to the hlayout box + self.gui.sinkLayout.addWidget(snk_usrp) + self.gui.sinkLayout.addWidget(snk_vol) + + + # Connect up some signals + self.connect(self.gui.pauseButton, QtCore.SIGNAL("clicked()"), + self.pauseFg) + + self.connect(self.gui.bandwidthEdit, QtCore.SIGNAL("editingFinished()"), + self.bwEditText) + self.connect(self.gui.freqEdit, QtCore.SIGNAL("editingFinished()"), + self.freqEditText) + self.connect(self.gui.gainEdit, QtCore.SIGNAL("editingFinished()"), + self.gainEditText) + + self.connect(self.gui.volumeEdit, QtCore.SIGNAL("editingFinished()"), + self.volumeEditText) + + + def pauseFg(self): + if(self.gui.pauseButton.text() == "Pause"): + self.fg.stop() + self.fg.wait() + self.gui.pauseButton.setText("Unpause") + else: + self.fg.start() + self.gui.pauseButton.setText("Pause") + + + # Accessor functions for Gui to manipulate USRP + def set_bw(self, bw): + self.gui.bandwidthEdit.setText(QtCore.QString("%1").arg(bw)) + + def set_freq(self, freq): + self.gui.freqEdit.setText(QtCore.QString("%1").arg(freq)) + + def set_gain(self, gain): + self.gui.gainEdit.setText(QtCore.QString("%1").arg(gain)) + + def set_volume(self, vol): + self.gui.volumeEdit.setText(QtCore.QString("%1").arg(vol)) + + def bwEditText(self): + try: + bw = self.gui.bandwidthEdit.text().toDouble()[0] + self.fg.set_usrp_bw(bw) + except RuntimeError: + pass + + def freqEditText(self): + try: + freq = self.gui.freqEdit.text().toDouble()[0] + self.fg.set_freq(freq) + except RuntimeError: + pass + + def gainEditText(self): + try: + gain = self.gui.gainEdit.text().toDouble()[0] + self.fg.set_gain(gain) + except RuntimeError: + pass + + def volumeEditText(self): + try: + vol = self.gui.volumeEdit.text().toDouble()[0] + self.fg.set_volume(vol) + except RuntimeError: + pass + + + + +# //////////////////////////////////////////////////////////////////// +# Define the GNU Radio Top Block +# //////////////////////////////////////////////////////////////////// + + +class wfm_rx_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("-A", "--antenna", default=None, + # help="select Rx Antenna (only on RFX-series boards)") + parser.add_option("-f", "--freq", type="eng_float", default=100.1, + 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("-V", "--volume", type="eng_float", default=None, + help="set volume (default is midpoint)") + parser.add_option("-O", "--audio-output", type="string", default="", + help="pcm device name. E.g., hw:0,0 or surround51 or /dev/dsp") + + (options, args) = parser.parse_args() + if len(args) != 0: + parser.print_help() + sys.exit(1) + + self._volume = options.volume + self._usrp_freq = options.freq + self._usrp_gain = options.gain + self._audio_rate = int(32e3) + + # build graph + + self.u = usrp2.source_32fc(options.interface, options.mac_addr) + + # calculate decimation values to get USRP BW at 320 kHz + self.calculate_usrp_bw(320e3) + + self.set_decim(self._usrp_decim) + + #FIXME: need named constants and text descriptions available to (gr-)usrp2 even + #when usrp(1) module is not built. A usrp_common module, perhaps? + dbid = self.u.daughterboard_id() + print "Using RX d'board 0x%04X" % (dbid,) + #if not (dbid == 0x0001 or #usrp_dbid.BASIC_RX + # dbid == 0x0003 or #usrp_dbid.TV_RX + # dbid == 0x000c or #usrp_dbid.TV_RX_REV_2 + # dbid == 0x0040): #usrp_dbid.TV_RX_REV_3 + # print "This daughterboard does not cover the required frequency range" + # print "for this application. Please use a BasicRX or TVRX daughterboard." + # raw_input("Press ENTER to continue anyway, or Ctrl-C to exit.") + + chan_filt_coeffs = optfir.low_pass (1, # gain + self._usrp_rate, # sampling rate + 80e3, # passband cutoff + 115e3, # stopband cutoff + 0.1, # passband ripple + 60) # stopband attenuation + #print len(chan_filt_coeffs) + chan_filt = gr.fir_filter_ccf (self._chanfilt_decim, chan_filt_coeffs) + + self.guts = blks2.wfm_rcv (self._demod_rate, self._audio_decim) + + self.volume_control = gr.multiply_const_ff(1) + + # sound card as final sink + #audio_sink = audio.sink (int (audio_rate), + # options.audio_output, + # False) # ok_to_block + audio_sink = audio.sink (self._audio_rate, + options.audio_output) + + + if self._usrp_gain is None: + # if no gain was specified, use the mid-point in dB + g = self.u.gain_range() + print "Gain range: ", g + self._usrp_gain = float(g[0]+g[1])/2 + + if self._volume is None: + g = self.volume_range() + self._volume = float(g[0]+g[1])/2 + + if abs(self._usrp_freq) < 1e6: + self._usrp_freq *= 1e6 + + # set initial values + self.set_gain(self._usrp_gain) + self.set_volume(self._volume) + if not(self.set_freq(self._usrp_freq)): + print ("Failed to set initial frequency") + + + # Define a GUI sink to display the received signal + self.qapp = QtGui.QApplication(sys.argv) + fftsize = 2048 + + self.usrp_rx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, + -self._usrp_rate/2.0, self._usrp_rate/2.0, + "Received Signal", True, True, False, True, False, + use_openGL=False) + self.usrp_rx2 = qtgui.sink_f(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, + -self._usrp_rate/2.0, self._usrp_rate/2.0, + "Received Signal", True, True, False, True, False) + + # now wire it all together + self.connect (self.u, chan_filt, self.guts, self.volume_control, audio_sink) + self.connect (self.u, self.usrp_rx) + self.connect (self.volume_control, self.usrp_rx2) + + usrp_rx_widget = sip.wrapinstance(self.usrp_rx.pyqwidget(), QtGui.QWidget) + usrp_rx2_widget = sip.wrapinstance(self.usrp_rx2.pyqwidget(), QtGui.QWidget) + + self.main_box = dialog_box(usrp_rx_widget, usrp_rx2_widget, self) + self.main_box.show() + + + def calculate_usrp_bw(self, bw): + """ + Calculate the different decimation rates that make the USRP BW equal to the + input bandwidth parameter 'bw' and the audio bandwidth equal to the system- + wide bandwidth 'self._audio_rate' + """ + + adc_rate = self.u.adc_rate() + d_usrp = int(adc_rate/bw) + bw_real = adc_rate / float(d_usrp) + + d_chan = 1 + demod_rate = bw_real / d_chan + + d_audio = int(bw_real / self._audio_rate) + audio_rate = demod_rate / d_audio + + self._usrp_decim = d_usrp + self._chanfilt_decim = d_chan + self._audio_decim = d_audio + self._demod_rate = demod_rate + self._usrp_rate = bw_real + + print "USRP Decimation: ", self._usrp_decim + print "USRP Bandwidth: ", bw_real + print "Audio Decimation: ", self._audio_decim + print "Audio Bandwidth: ", audio_rate + + def set_volume (self, vol): + g = self.volume_range() + self._volume = max(g[0], min(g[1], vol)) + self.volume_control.set_k(10**(self._volume/10)) + + def set_freq(self, target_freq): + """ + Set the center frequency we're interested in. + + @param target_freq: frequency in Hz + @rypte: bool + + Tuning is a two step process. First we ask the front-end to + tune as close to the desired frequency as it can. Then we use + the result of that operation and our target_frequency to + determine the value for the digital down converter. + """ + r = self.u.set_center_freq(target_freq) + if r: + self._usrp_freq = target_freq + return True + return False + + def set_usrp_bw(self, bw): + self.calculate_usrp_bw(bw) + + def set_gain(self, gain): + self._usrp_gain = gain + self.u.set_gain(gain) + + def set_decim(self, decim): + self._usrp_decim = int(decim) + self.u.set_decim(self._usrp_decim) + + def volume(self): + return self._volume + + def freq(self): + return self._usrp_freq + + def usrp_bw(self): + return self._usrp_rate + + def gain(self): + return self._usrp_gain + + def decim(self): + return self._usrp_decim + + def volume_range(self): + return (-20.0, 0.0, 0.5) + + +if __name__ == '__main__': + tb = wfm_rx_block() + tb.start() + tb.qapp.exec_() + |