Hello! I'm doing a project where i need to tune a signal around 10.7Mhz, and then start making a capture to a file. So I need to the a tuner which searches for the correct center frequency, so that I can narrow the sampling band as much as possible. The idea I'm trying to implement is a two step search. On the first I use a 250khz band using only USRP decimation, and a 4096 points fft. This way the center frequency has an accuracy of about 120hz. On the second step I narrow the band to 25kHz, decimating 10 times the signal from the usrp using software decimation. It's implemented using gr.keep_one_in_n(type,10). Keeping the same FFT size there should be an error of about 12hz. Now the problem is this: the estimation from the first step is closer to the real value, read on a spectrum analyzer, than the one in the second. Since I have the same number of points for the FFT, shouldn't the resolution per bin be 10 times better because the bandwidth is 10 times narrower? Do I need to change the way I'm decimating the signal? (Not using keep_one_in_n ...) Why am I getting poorer results? This is the 2-step tuner I have for now: #////////////////////////////////////////////////////////// # Set initial values so start signal search with the tunner #////////////////////////////////////////////////////////// cf = 10.701200e6 # center frequency fs = 250.0e3 # sampling frequency fsize = 4096 # number of point on the FFT print print "Initilizing Tunner.." tb = tunner(cf, fs, fsize) print "1st Search.." tb.start() # Waiting period, to avoid initial flunctuations time.sleep(5) # Get 500 samples to make the first estimation while(len(tb.v_sink.out_freq()) < 30): pass tb.stop() tb.wait() print "Search done!" # Make evaluation # @ get magnitude vector # @ get frequency vector print "Evaluating.." mg = scipy.array(tb.v_sink2.out_mag()) fq = scipy.array(tb.v_sink.out_freq()) print "MAG:", mg print "FREQ:", fq if mg.mean() > -10: cf = fq.mean() print "Center Frequency = ", cf print elif mg.mean() <= -10: print "Not enough power!!" print #////////////////////////////////////////////////////// # Set values to fine tunne the frequency before capture #////////////////////////////////////////////////////// tb = None cf = 10.701200e6 fs = 25.0e3 fsize = 4096 print print "Initilizing Tunner.." tb = tunner(cf, fs, fsize) print "2nd Search.." tb.start() # Waiting period, to avoid initial flunctuations time.sleep(5) # Get 30 samples to make the first estimation while(len(tb.v_sink.out_freq()) < 30): pass tb.stop() tb.wait() print "Search done!" # Make evaluation # @ get magnitude vector # @ get frequency vector print "Evaluating.." mg = scipy.array(tb.v_sink2.out_mag()) fq = scipy.array(tb.v_sink.out_freq()) print "MAG:", mg print "FREQ:", fq if mg.mean() > -10: cf = fq.mean() print "Center Frequency = ", cf print elif mg.mean() <= -10: print "Not enough power!!" And this is the part of the __init__ that concerns the decimation: (buffer_sink is a block made by me that implement a circular buffer to store values) class tunner(gr.top_block): def __init__(self, center_frequency, sampling_frequency, fft_size): gr.top_block.__init__(self) (....) full_decim = int(64e6/sampling_frequency) print "FULL DECIM = ", full_decim if full_decim > 256: decim = 256 sw_decim = gr.keep_one_in_n(gr.sizeof_gr_complex, int(250e3/sampling_frequency)) print "SW = ", int(250e3/sampling_frequency) elif full_decim <= 256: decim = full_decim sw_decim = gr.keep_one_in_n(gr.sizeof_gr_complex, 1) print "SW = 0" (....) self.connect(self.u, sw_decim, ss2v, fft, c2m, (imax,0), s2f1, self.buffer_sink) self.connect((imax,1), s2f2, p1) -- View this message in context: http://www.nabble.com/Software-Decimation---proble... Sent from the GnuRadio mailing list archive at Nabble.com.

on 2009-03-31 18:55

on 2009-04-01 00:42

I don't actually know but I would assume keep_one_in_n is not actually doing any Anti Aliasing for you, that may explain why you are getting a worse result. I recently implemented a system for doing what you are describing and it may be easier for you to just increase the size of your FFT. My system uses a 12800 bin FFT at 1.28M Complex S/s (giving 100Hz bins) and only uses ~20% CPU on an old P4 machine. Kieran

on 2009-04-01 01:49

Hello again! Thanks for the advice. But the problem is that during the file capture I was asked to have a resolution of about 1hz or 2hz on a bandwidth of about 200hz. I would like to have at that point enough decimation to sample at about 500hz. So I think I'll need the decimation working correctly in the final program. Won't this effect I'm seeing apear too? Right now I can have an accurate estimation until the hundreds. I was hoping to get the tens and units correct as well or with an error of 1hz or 2hz. It's very important to have this resolution given the fact that the power is mostly in a 100hz width. With decimation I have an error of about 60hz and it was supposed to be around 6hz to 12hz. Sorry if I'm repeating my self over and over. But it's very important to solve this problem to advance in my thesis project. Thanks in advance. Emanuel Ornelas E. Ornelas wrote: > points fft. This way the center frequency has an accuracy of about 120hz. > narrower? > cf = 10.701200e6 # center frequency > time.sleep(5) > # @ get frequency vector > print "Center Frequency = ", cf > > # Waiting period, to avoid initial flunctuations > # @ get magnitude vector > cf = fq.mean() > class tunner(gr.top_block): > decim = 256 > self.connect(self.u, sw_decim, ss2v, fft, c2m, (imax,0), > s2f1, self.buffer_sink) > self.connect((imax,1), s2f2, p1) > -- View this message in context: http://www.nabble.com/Software-Decimation---proble... Sent from the GnuRadio mailing list archive at Nabble.com.

on 2009-04-01 03:46

My advice would be to go read up on downsampling (especially anti-aliasing filters). :) The short answer is you need to low pass filter the incoming signal so when you perform the down sampling you do not get aliasing of the signal. Kieran

on 2009-04-01 07:37

On Wed, Apr 01, 2009 at 12:45:45PM +1300, Kieran B. wrote: > My advice would be to go read up on downsampling (especially anti-aliasing > filters). :) > > The short answer is you need to low pass filter the incoming signal so when > you perform the down sampling you do not get aliasing of the signal. Yes. Consider using gr.fir_filter_ccf(decim, taps) to decimate. The low pass filter taps can be generated using gr.firdes.low_pass. Eric