#!/usr/bin/env python #AM reciever from gnuradio import gr, eng_notation, blks2 from gnuradio import audio from gnuradio import usrp, optfir from gnuradio.eng_option import eng_option from optparse import OptionParser import sys import math from gnuradio.wxgui import stdgui2, fftsink2 import wx class am_rx_graph (stdgui2.std_top_block): def __init__(self,frame,panel,vbox,argv): stdgui2.std_top_block.__init__ (self,frame,panel,vbox,argv) # station is the frequency to be received station = parseargs(argv[1:]) adc_rate = 64e6 #output sample rate of the ADC, 64Ms/s usrp_decim = 250 usrp_rate = adc_rate /usrp_decim # output sample rate of the usrp, 256 ks/s lpf_decim = 4 lpf_rate = usrp_rate / lpf_decim # 64 kHz # usrp is data source # tells which usrp board is used and what the dec rate is #src = usrp.source_c (0, usrp_decim) #Tell USRP what daughter board to use and displays name #(1,0) means side B, 1st channel - picks daughterboard #rx_subdev_spec = (1,0) #src.set_mux(usrp.determine_rx_mux_value(src,rx_subdev_spec)) #subdev = usrp.selected_subdev(src,rx_subdev_spec) #print "Using daughterboard",subdev.name() #sets the shift frequency of the ddc (on FPGA) Note: must be minus or FFT display is reversed JF 08-08-08 #src.set_rx_freq (0, -station) #Turn up USRP gain to maximum #g = subdev.gain_range() #subdev.set_gain(float(g[1])) # checks the actual shift frequency #actual_shift_freq =src.rx_freq(0) #this line is to allow playback without usrp actual_shift_freq = -710000 #print "Actual DDC shift frequency", actual_shift_freq #print "USRP gain ", float(g[1]) # set gain on USRP #src.set_pga(0,20) #defines a file to collect usrp output #am_usrp_sink = gr.file_sink(gr.sizeof_gr_complex, "am_usrp710.dat") #self.connect(src, am_usrp_sink) #defines the file to playback the usrp data from am_usrp_source = gr.file_source(gr.sizeof_gr_complex, "am_usrp710.dat") # computes taps for LPF and creates channel filter with those taps channel_coeffs = optfir.low_pass ( 1.0, # gain usrp_rate, # sampling rate 4.5e3, # low pass cutoff freq 5e3, # width of trans. band 0.1, #passband ripple 60) #stopband attenuation #set frequency shift for picking up other signals offset = 0 chan_filter = gr.freq_xlating_fir_filter_ccf( lpf_decim,channel_coeffs, offset ,usrp_rate) # define a file to collect channel filter output and connect #chan_sink = gr.file_sink(gr.sizeof_gr_complex, "chan.dat") #self.connect(chan_filter, chan_sink) #create an automatic gain control (AGC) block with 1 second time constant decay .1 attack. my_agc = gr.agc2_cc(1.5e-4,1.5e-5,10,1,0.0) # create a block to take the magnitude (envelope) of the AM Signal magblock = gr.complex_to_mag() # define and connect a sink of collect the output of the magnitude block #mag_sink = gr.file_sink(gr.sizeof_float, "mag.dat") #self.connect(magblock, mag_sink) #create a volume control and collect data into a file volumecontrol = gr.multiply_const_ff(.04) #volcont_sink = gr.file_sink(gr.sizeof_float, "volcont.dat") #self.connect(volumecontrol, volcont_sink) # compute FIR filter taps for audio filter audio_coeffs = optfir.low_pass ( 1.0, # gain lpf_rate, # sampling rate 4.5e3, # edge of passband 5e3, # edge of stopband, 0.1, #passband ripple 60) # stopband ripple # create audio filter and a file for its output audio_filter = gr.fir_filter_fff ( 1, audio_coeffs) #audio_filt_sink = gr.file_sink(gr.sizeof_float, "audio_filt.dat") #self.connect(audio_filter, audio_filt_sink) # create a resampler to bring 64ks/s rate to 48ks/s for audio card and data file rsamp=blks2.rational_resampler_fff(3,4) #rsamp_sink = gr.file_sink(gr.sizeof_float, "rsamp.dat") #self.connect(rsamp, rsamp_sink) #create a sink representing the audio card audio_sink = audio.sink (int (48000)) # now wire it all together #use this line to receive from usrp #self.connect (src,chan_filter) #use this line to playback recorded data self.connect (am_usrp_source, chan_filter) self.connect (chan_filter, my_agc) self.connect (my_agc, magblock) self.connect (magblock, volumecontrol) self.connect (volumecontrol,audio_filter) self.connect (audio_filter, rsamp) self.connect (rsamp, (audio_sink, 0)) if 1: pre_demod = fftsink2.fft_sink_c (panel, title="USRP Output", ref_level=70, fft_size=512, sample_rate=usrp_rate) self.connect (am_usrp_source, pre_demod) vbox.Add (pre_demod.win, 1, wx.EXPAND) #Sets offset for floating pointer in FFT window pre_demod.win.set_baseband_freq(-actual_shift_freq) if False: post_demod = fftsink2.fft_sink_c (panel, title="Post Channel Filter", fft_size=256, sample_rate=lpf_rate) self.connect (chan_filter, post_demod) vbox.Add (post_demod.win, 1, wx.EXPAND) if False: post_filt = fftsink2.fft_sink_f (panel, title="Post Envelope Detector", fft_size=512, sample_rate=lpf_rate) self.connect (magblock,post_filt) vbox.Add (post_filt.win, 1, wx.EXPAND) def parseargs (args): nargs = len (args) # multiplies the input frequency by 1000 to put in Hz if nargs == 1: freq1 = float (args[0]) * 1e3 else: sys.stderr.write ('usage: am_rcv freq1\n') sys.exit (1) return freq1 if __name__ == '__main__': app = stdgui2.stdapp (am_rx_graph, "AM RX") app.MainLoop ()