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

Reply via email to