Frequency shift in the received and generated signals of the USRP

Hey all,

I am using USRP with two XCVR2450 Trancievers(working at 2.4-2.5GHz and
4.9-5.0GHz).
I generated a carrier at 2.45GHz from the USRP using :
$ python usrp_siggen.py -TA -f2.45e9
But when i see the generated signal in a spectrum analyzer, i see that
it
is shifted by 12.5KHz
from the center frequency( i see the carrier at 2.45GHz minus 12.5KHz).
I
try for other carrier frequencies but the
shift remain almost the same.

Also, I generated a carrierl of 2.45GHz from a signal generator ,
received
it in the usrp and I observed the spectrum.
Again I see that the signal that is demodulated by the USRP and received
in
the computer through the USB is not a baseband signal as expected.
Rather it
is a carrier of about 12.5KHz.

This means their is a fequency shift of about 12.5KHz both in
transmission
and in reception.When I use a carrier of frequency 4.9-5.0GHz, the
frequency
shift almost doubles to 25KHz.
Does anyone experienced such a problem before?
So, What can i do to correct this frequency shift? -Thanks

Bruhtesfa

On Thu, Nov 20, 2008 at 5:31 AM, Bruhtesfa E. [email protected]
wrote:

shift remain almost the same.
Does anyone experienced such a problem before?
So, What can i do to correct this frequency shift? -Thanks

Unfortunately, the problem is inherent in all RF communications
systems due to the fact all radios have an independent time base.

Because each local oscillator is not exactly 64.000000000MHz, when
that signal is multiplied up by the PLL - so does the “offset”. You
can reduce this by synchronizing yourself to a very reliable timebase,
but you still get some residual shift.

The fortunate part for you is that it is very well documented and
written about extensively. Take a look in your favorite wireless
communications systems book and you will most likely see a good
discussion with regards to time synchronization.

Enjoy your reading, and good luck!

Brian

Thanks Brian!

Because each local oscillator is not exactly 64.000000000MHz, when
that signal is multiplied up by the PLL - so does the “offset”.

I see on “USRP under 1.5x magnifaying lens, by: Firras” that the
tranceiver osillators tune as close as possible to the desired receiving
frequency in steps of 4MHz,and the remaining frequency offset is
downconverted by the USRP DDC. So if I am tuning to 2.40GHz(multiple of
4MHz), why a frequency offset occurs? or could you discribe how the
desired RF signal at 2.40GHz ends up at around 12KHz for XCVR2450
tranceiver particularly?

The fortunate part for you is that it is very well documented and
written about extensively. Take a look in your favorite wireless
communications systems book and you will most likely see a good
discussion with regards to time synchronization.

Do you think this frequency offset remains exactly the same every time
for the same USRP at a constant target frequency(ex. 2.40GHz)? Or is it
time varing?

Also is there some way(GNU Radio code that uses PLL and the frequency
offset) to demodulate the signal at this offset frequency back to
baseband?

Bruhtesfa

On Thu, Nov 20, 2008 at 10:16 AM, Bruhtesfa E.
[email protected] wrote:

Thanks Brian!

You are quite welcome!

I see on “USRP under 1.5x magnifaying lens, by: Firras” that the
tranceiver osillators tune as close as possible to the desired receiving
frequency in steps of 4MHz,and the remaining frequency offset is
downconverted by the USRP DDC. So if I am tuning to 2.40GHz(multiple of
4MHz), why a frequency offset occurs? or could you discribe how the
desired RF signal at 2.40GHz ends up at around 12KHz for XCVR2450
tranceiver particularly?

Tuning is done to the best of the receiver’s (synthesizer/PLL)
ability. Please reference what a superheterodyne receiver is:

http://en.wikipedia.org/wiki/Superheterodyne

Now, knowing that there is a 64MHz local oscillator reference on the
board, that must somehow get “multiplied up” using a PLL to generate
your 2.4GHz signal. Some simple math follows:

Multiplier = 2.4e9 / 64e6
Multiplier = 37.5

So a 64MHz signal must be multiplied up by 37.5x to generate the
desired frequency. Now, lets imagine that our crystal oscillator is
off by 320Hz. I believe this is a crystal oscillator rating of 5ppm.
For more information on PPM, see:

http://en.wikipedia.org/wiki/Parts_per_million

Establishing we have an oscillator with a 5ppm offset, and a
multiplier of 37.5, we can then calculate what our frequency offset
will be:

Foffset = multiplier * LOoffset
Foffset = 37.5 * 320Hz
Foffset = 12kHz

By only being off by 5 cycles for every 64 million, we have created a
12kHz offset only at the transmitter. This may be added or subtracted
based on how the receiver is sampling as well.

At these frequencies, this amount of offset is not atypical.

Do you think this frequency offset remains exactly the same every time
for the same USRP at a constant target frequency(ex. 2.40GHz)? Or is it
time varing?

The frequency offset changes over time and temperature. It is a fact
of life. Practical radio communications systems always have to
compensate for frequency offset, drift and the like.

Also is there some way(GNU Radio code that uses PLL and the frequency
offset) to demodulate the signal at this offset frequency back to
baseband?

Use the source. I don’t know if there is a block already written that
will do what you want to do - but the fact that you have insight into
all the blocks and the ability to write your own algorithms empowers
you to make GNU Radio do whatever you want it to do.

Good luck!

Brian

Tuning is done to the best of the receiver’s (synthesizer/PLL)
ability. Please reference what a superheterodyne receiver is:

http://en.wikipedia.org/wiki/Superheterodyne

Now, knowing that there is a 64MHz local oscillator reference on the
board, that must somehow get “multiplied up” using a PLL to generate
your 2.4GHz signal. Some simple math follows:

Multiplier = 2.4e9 / 64e6
Multiplier = 37.5

So a 64MHz signal must be multiplied up by 37.5x to generate the
desired frequency. Now, lets imagine that our crystal oscillator is
off by 320Hz. I believe this is a crystal oscillator rating of 5ppm.
For more information on PPM, see:

http://en.wikipedia.org/wiki/Parts_per_million

Establishing we have an oscillator with a 5ppm offset, and a
multiplier of 37.5, we can then calculate what our frequency offset
will be:

Foffset = multiplier * LOoffset
Foffset = 37.5 * 320Hz
Foffset = 12kHz

By only being off by 5 cycles for every 64 million, we have created a
12kHz offset only at the transmitter. This may be added or subtracted
based on how the receiver is sampling as well.

Thanks again!

Actually, the major problem for me was there is no data sheet/manual
about the XCVR2450 tranceiver. The only information on the manufacturer
website, www.ettus.com , is the operating frequency range and the
maximum transmit power. So, i didn’t know to what IF frequency the
tranceiver downconverts the RF signal;how much gain it provides and to
what extent the oscillator of the XCVR2450 is accurate.

So Dear : Matt E.,

Do you have any data sheet, description or manual for this tranceiver ?
If yes, where can i get it? If no, I think it is really important to
prepare a data sheet and a manual for each USRP Daughterboards;
otherwise, users of your daughterboards will face the same problem in
the future.

Bruhtesfa

On Nov 20, 2008, at 11:18 AM, Brian P. wrote:

Also is there some way(GNU Radio code that uses PLL and the frequency
offset) to demodulate the signal at this offset frequency back to
baseband?

Use the source. I don’t know if there is a block already written that
will do what you want to do - but the fact that you have insight into
all the blocks and the ability to write your own algorithms empowers
you to make GNU Radio do whatever you want it to do.

I’ve used “gr.freq_xlating_fir_filter_XXX” with success for this
purpose … admittedly all by hand. AFAIK, there is no automated way
to do it, though IIRC some folks have proposed working on such
algorithms in the past (search the listserv archives). For more
info, look at the source code in gnuradio-core/src/lib/filter . - MLD

Hi again Kaleem - I apologize for never getting anything out to the
list. I’ve been swamped with work & life. Here is the gist of how to
do a static freq_xlating_fir_filter – probably imperfect since this
is from memory:

Instead of: USRP.source() -> WHATEVER

You do : USRP.source() -> gr.freq_xlating_fir_filter_XXX() -> WHATEVER

The trick here is to get the bandwidth [BW] correct once samples reach
WHATEVER. In the former, you set the decimation rate in the
USRP.source(). In the latter, you have to set the decimation in the
XLATING filter, and then reverse compute a USRP decimation rate that
allows enough BW for the FIR filter part of the XLATING block.

For the USRP, the ADC is running at 64 MS/s, with decimation in
4:2:256 IIRC, allowing for BWs of 16 MS/s down to 250 kS/s.

Suppose you want 250 kS/s at WHATEVER. Then you want more than 250 kS/
s BW before the XLATING filtering in order to do the filtering …
maybe 500 kS/s would suffice … really depends on how precise
filtering you want to do. Anyway, you set the XLATING frequency shift
to the negative of what you’ve seen via comparison of a spectrum
analyzer and the transmitted signal. And you set the decimation of
the filter to 2 (in this case) to get the BW correct at WHATEVER (in
this case: and set the USRP’s decimation to 128 to get the sample rate
of 500 kS/s as the output of USRP.source()). Of course, you’ll need
to create the low-pass filter coefficients first, to pass those in to
the XLATING block on instantiation.

Try this out & play with the parameter to figure out what works for
your particular HW setup … in my testing, each USRP required a
different frequency shift; some were “small” while others were
“large”. But as long as you keep track of which USRP requires which
offset, they are pretty much static & can be used time and again with
reasonable precision.

Hope this makes sense, and is reasonably correct. - MLD