Dear all, I guess I should have spent more time experimenting and studying the examples before asking these questions. In any case, I have resolved both issues:
As it turns out the ADC's (I guess due to some hardware mismathces etc) may add a DC term at the output. This offset can be eliminated easily by adding some more code in the python script. The example "tweak_adc_offset.py" can help with this: so what I did is I left the RX-A and RX-B open and run tweak_adc_offset.py The oscope showed the DC values for channels A and B which have to be compensated. In my case was 322 and 180 for channels A and B, respectively. Then I run tweak_adc_offset.py -0 322 -1 180 and the oscope verified an almost 0 offset for both of the channels. I added the piece of code in both usrp_fft.py and usrp_oscope.py to be able to compensate for this offset in all these programs: parser.add_option ("-0", "--adc-offset-0", type="int", default=0, help="set adc offset to OFFSET", metavar="OFFSET") parser.add_option ("-1", "--adc-offset-1", type="int", default=0, help="set adc offset to OFFSET", metavar="OFFSET") parser.add_option ("-2", "--adc-offset-2", type="int", default=0, help="set adc offset to OFFSET", metavar="OFFSET") parser.add_option ("-3", "--adc-offset-3", type="int", default=0, help="set adc offset to OFFSET", metavar="OFFSET") where the parsing of arguments is taking place and the following piece of code # I added this to correct for the DC offset # Experiments: it seems that 322 and 180 works for my USRP FR_ADC_OFFSET_3_2 = 2 # hi 16: ADC3, lo 16: ADC2 FR_ADC_OFFSET_1_0 = 3 self.u._write_fpga_reg (FR_ADC_OFFSET_1_0, ((options.adc_offset_1 & 0xffff) << 16) | (options.adc_offset_0 & 0xffff)) self.u._write_fpga_reg (FR_ADC_OFFSET_3_2, ((options.adc_offset_3 & 0xffff) << 16) | (options.adc_offset_2 & 0xffff)) right after the definition of the usrp source. I attach the corrected script usrp_fft.py and usrp_oscope.py It wouldn't be hard to add a piece of code in all usrp-related scripts that compensates for the DC offset automatically at the beginning of the program. All is needed is to measure the average DC term and use some sort of AGC (I think it is already implemented in gnuradio) to drive the DC offset close to 0. I might take a crack at it later, but now I am satisfied with the manual way of compensation. Best Achilleas
#!/usr/bin/env python # # Copyright 2004 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 2, 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., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # from gnuradio import gr from gnuradio import usrp from gnuradio import eng_notation from gnuradio.eng_option import eng_option from gnuradio.wxgui import stdgui, fftsink from optparse import OptionParser import wx class app_flow_graph (stdgui.gui_flow_graph): def __init__(self, frame, panel, vbox, argv): stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv) self.frame = frame self.panel = panel parser = OptionParser (option_class=eng_option) parser.add_option ("-d", "--decim", type="int", default=16, help="set fgpa decimation rate to DECIM") parser.add_option ("-c", "--ddc-freq", type="eng_float", default=0, help="set Rx DDC frequency to FREQ", metavar="FREQ") parser.add_option ("-m", "--mux", type="intx", default=0x32103210, help="set fpga FR_RX_MUX register to MUX") parser.add_option ("-g", "--gain", type="eng_float", default=0, help="set Rx PGA gain in dB (default 0 dB)") parser.add_option ("-0", "--adc-offset-0", type="int", default=0, help="set adc offset to OFFSET", metavar="OFFSET") parser.add_option ("-1", "--adc-offset-1", type="int", default=0, help="set adc offset to OFFSET", metavar="OFFSET") parser.add_option ("-2", "--adc-offset-2", type="int", default=0, help="set adc offset to OFFSET", metavar="OFFSET") parser.add_option ("-3", "--adc-offset-3", type="int", default=0, help="set adc offset to OFFSET", metavar="OFFSET") (options, args) = parser.parse_args () self.u = usrp.source_c (0, options.decim, 1, options.mux, 0) self.u.set_rx_freq (0, options.ddc_freq) # I added this to correct for the DC offset # Experiments: it seems that 322 and 180 works for my USRP FR_ADC_OFFSET_3_2 = 2 # hi 16: ADC3, lo 16: ADC2 FR_ADC_OFFSET_1_0 = 3 self.u._write_fpga_reg (FR_ADC_OFFSET_1_0, ((options.adc_offset_1 & 0xffff) << 16) | (options.adc_offset_0 & 0xffff)) self.u._write_fpga_reg (FR_ADC_OFFSET_3_2, ((options.adc_offset_3 & 0xffff) << 16) | (options.adc_offset_2 & 0xffff)) self.u.set_pga (0, options.gain) self.u.set_pga (1, options.gain) self.u.set_verbose (0) input_rate = self.u.adc_freq () / self.u.decim_rate () fft = fftsink.fft_sink_c (self, panel, fft_size=512, sample_rate=input_rate) self.connect (self.u, fft) vbox.Add (fft.win, 1, wx.EXPAND) # build small control area at bottom hbox = wx.BoxSizer (wx.HORIZONTAL) hbox.Add ((1, 1), 1, wx.EXPAND) hbox.Add (wx.StaticText (panel, -1, "Set ddc freq: "), 0, wx.ALIGN_CENTER) self.tc_freq = wx.TextCtrl (panel, -1, "", style=wx.TE_PROCESS_ENTER) hbox.Add (self.tc_freq, 0, wx.ALIGN_CENTER) wx.EVT_TEXT_ENTER (self.tc_freq, self.tc_freq.GetId(), self.handle_text_enter) hbox.Add ((1, 1), 1, wx.EXPAND) # add it to the main vbox vbox.Add (hbox, 0, wx.EXPAND) self.update_status_bar () def handle_text_enter (self, event): str = event.GetString () self.tc_freq.Clear () self.u.set_rx_freq (0, eng_notation.str_to_num (str)) self.update_status_bar () def update_status_bar (self): ddc_freq = self.u.rx_freq (0) decim_rate = self.u.decim_rate () sample_rate = self.u.adc_freq () / decim_rate msg = "decim: %d %sS/s DDC: %s" % ( decim_rate, eng_notation.num_to_str (sample_rate), eng_notation.num_to_str (ddc_freq)) self.frame.GetStatusBar().SetStatusText (msg, 1) def main (): app = stdgui.stdapp (app_flow_graph, "USRP FFT") app.MainLoop () if __name__ == '__main__': main ()
#!/usr/bin/env python # # Copyright 2004 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 2, 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., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # from gnuradio import gr from gnuradio import usrp from gnuradio.eng_option import eng_option from gnuradio.wxgui import stdgui, fftsink, scopesink from optparse import OptionParser import wx class app_flow_graph (stdgui.gui_flow_graph): def __init__(self, frame, panel, vbox, argv): stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv) parser = OptionParser (option_class=eng_option) parser.add_option ("-d", "--decim", type="int", default=16, help="set fgpa decimation rate to DECIM") parser.add_option ("-c", "--cordic-freq", type="eng_float", default=0, help="set Rx cordic frequency to FREQ", metavar="FREQ") parser.add_option ("-m", "--mux", type="intx", default=0x32103210, help="set fpga FR_RX_MUX register to MUX") parser.add_option ("-n", "--nchan", type="intx", default=1, help="set nchannels to NCHAN") parser.add_option ("-g", "--gain", type="eng_float", default=0, help="set Rx PGA gain in dB (default 0 dB)") parser.add_option ("-0", "--adc-offset-0", type="int", default=0, help="set adc offset to OFFSET", metavar="OFFSET") parser.add_option ("-1", "--adc-offset-1", type="int", default=0, help="set adc offset to OFFSET", metavar="OFFSET") parser.add_option ("-2", "--adc-offset-2", type="int", default=0, help="set adc offset to OFFSET", metavar="OFFSET") parser.add_option ("-3", "--adc-offset-3", type="int", default=0, help="set adc offset to OFFSET", metavar="OFFSET") (options, args) = parser.parse_args () u = usrp.source_c (0, options.decim, options.nchan, options.mux, 0) u.set_rx_freq (0, options.cordic_freq) u.set_pga (0, options.gain) u.set_pga (1, options.gain) # I added this to correct for the DC offset # Experiments: it seems that 322 and 180 works for my USRP FR_ADC_OFFSET_3_2 = 2 # hi 16: ADC3, lo 16: ADC2 FR_ADC_OFFSET_1_0 = 3 u._write_fpga_reg (FR_ADC_OFFSET_1_0, ((options.adc_offset_1 & 0xffff) << 16) | (options.adc_offset_0 & 0xffff)) u._write_fpga_reg (FR_ADC_OFFSET_3_2, ((options.adc_offset_3 & 0xffff) << 16) | (options.adc_offset_2 & 0xffff)) input_rate = u.adc_freq () / u.decim_rate () c2f_1 = gr.complex_to_float () sink, win = scopesink.make_scope_sink_f (self, panel, "Rx Data", input_rate) vbox.Add (win, 1, wx.EXPAND) if(options.nchan == 2): u.set_rx_freq (1, options.cordic_freq) deint = gr.deinterleave (gr.sizeof_gr_complex) c2f_2 = gr.complex_to_float () self.connect (u, deint) self.connect ((deint,0),c2f_1) self.connect ((deint,1),c2f_2) self.connect ((c2f_2, 0), (sink, 2)) self.connect ((c2f_2, 1), (sink, 3)) else: self.connect (u,c2f_1) self.connect ((c2f_1, 0), (sink, 0)) self.connect ((c2f_1, 1), (sink, 1)) def main (): app = stdgui.stdapp (app_flow_graph, "USRP O'scope") app.MainLoop () if __name__ == '__main__': main ()
_______________________________________________ Discuss-gnuradio mailing list Discuss-gnuradio@gnu.org http://lists.gnu.org/mailman/listinfo/discuss-gnuradio