Main Content

Frequency Offset Calibration Receiver with USRP Hardware

This example shows how to use USRP™ System objects to measure and calibrate for transmitter/receiver frequency offset at the receiver.

The USRP transmitter sends a sine wave at 100Hz with the MATLAB script, FrequencyOffsetCalibrationTransmitterUSRPHardwareExample.m, to the USRP receiver. The USRP receiver monitors received signals, calculates the transmitter/receiver frequency offset and displays it in the MATLAB command window for calibration with the MATLAB script, FrequencyOffsetCalibrationReceiverUSRPHardwareExample.m

Required Hardware and Software

You need one of the following:

Introduction

The example provides the following information about the USRP transmitter/receiver link:

  • The quantitative value of the frequency offset

  • A graphical view of the spur-free dynamic range of the receiver

  • A graphical view of the qualitative SNR level of the received signal

To calibrate the frequency offset between two USRP devices, run FrequencyOffsetCalibrationTransmitterUSRPHardwareExample.m on one USRP radio, and while simultaneously running FrequencyOffsetCalibrationReceiverUSRPHardwareExample.m on another USRP radio. The CenterFrequency property of the SDRu transmitter and receiver System objects should have the same value.

To compensate for a transmitter/receiver frequency offset, add the displayed frequency offset to the Center Frequency of the SDRu Receiver System object. Be sure to use the sign of the offset in your addition. Once you've done that, the spectrum displayed by the receiver's spectrum analyzer System object should have its maximum amplitude at roughly 0 Hz.

Please refer to the Simulink® model Frequency Offset Calibration with USRP Hardware in Simulink for a block diagram view of the system.

Hardware Requirements

To run this example, ensure that the center frequency of the SDRu Transmitter and Receiver System objects is within the acceptable range of your USRP daughter board and the antennas you are using.

Code Architecture

The Frequency Offset Calibration Receiver example uses three System objects: comm.SDRuReceiver, a coarse frequency offset object, and a spectrum analyzer to show the power spectral density of the received signal.

Discover Radio

Discover radio(s) connected to your computer. This example uses the first USRP radio found using the findsdru function. Check if the radio is available and record the radio type. If no available radios are found, the example uses a default configuration for the system but does not run the main loop.

connectedRadios = findsdru;
if strncmp(connectedRadios(1).Status, 'Success', 7)
  radioFound = true;
  platform = connectedRadios(1).Platform;
  switch connectedRadios(1).Platform
    case {'B200','B210'}
      address = connectedRadios(1).SerialNum;
    case {'N200/N210/USRP2','X300','X310','N300','N310','N320/N321'}
      address = connectedRadios(1).IPAddress;
  end
else
  radioFound = false;
  address = '192.168.10.2';
  platform = 'N200/N210/USRP2';
end
Checking radio connections...

Initialization

Baseband and RF configuration

rfRxFreq           = 1.85e9;  % Nominal RF receive center frequency
bbRxFreq           = 100;     % Received baseband sine wave frequency

prmFreqCalibRx = configureFreqCalibRx(platform, rfRxFreq, bbRxFreq);

% This example communicates with the USRP board using the SDRu receiver
% System object. B200 and B210 series USRP radios are addressed using a
% serial number while USRP2, N200, N210, X300 and X310 radios are addressed
% using an IP address. The parameter structure, prmFreqCalibRx, sets the
% CenterFrequency, Gain, InterpolationFactor, and SamplesPerFrame
% arguments.
switch platform
  case {'B200','B210'}
    radio = comm.SDRuReceiver(...
        'Platform',         platform, ...
        'SerialNum',        address, ...
        'MasterClockRate',  prmFreqCalibRx.MasterClockRate, ...
        'CenterFrequency',  prmFreqCalibRx.RxCenterFrequency,...
        'Gain',             prmFreqCalibRx.Gain, ...
        'DecimationFactor', prmFreqCalibRx.DecimationFactor,...
        'SamplesPerFrame',  prmFreqCalibRx.FrameLength,...
        'OutputDataType',   prmFreqCalibRx.OutputDataType)
  case {'X300','X310','N300','N310','N320/N321'}
    radio = comm.SDRuReceiver(...
        'Platform',         platform, ...
        'IPAddress',        address, ...
        'MasterClockRate',  prmFreqCalibRx.MasterClockRate, ...
        'CenterFrequency',  prmFreqCalibRx.RxCenterFrequency,...
        'Gain',             prmFreqCalibRx.Gain, ...
        'DecimationFactor', prmFreqCalibRx.DecimationFactor,...
        'SamplesPerFrame',  prmFreqCalibRx.FrameLength,...
        'OutputDataType',   prmFreqCalibRx.OutputDataType)
  case {'N200/N210/USRP2'}
    radio = comm.SDRuReceiver(...
        'Platform',         platform, ...
        'IPAddress',        address, ...
        'CenterFrequency',  prmFreqCalibRx.RxCenterFrequency,...
        'Gain',             prmFreqCalibRx.Gain, ...
        'DecimationFactor', prmFreqCalibRx.DecimationFactor,...
        'SamplesPerFrame',  prmFreqCalibRx.FrameLength,...
        'OutputDataType',   prmFreqCalibRx.OutputDataType)
end

% Create a coarse frequency offset compensation System object to calculate
% the offset. The System object performs an FFT on its input signal and
% finds the frequency of maximum power. This quantity is the frequency
% offset.
CFO = comm.CoarseFrequencyCompensator(...
    'FrequencyResolution',      25, ...
    'SampleRate',               prmFreqCalibRx.Fs);

specAnalyzer = spectrumAnalyzer(...
    'Name',                          'Actual Frequency Offset',...
    'Title',                         'Actual Frequency Offset', ...
    'SpectrumType',                  'Power density',...
    'FrequencySpan',                 'Full', ...
    'SampleRate',                     prmFreqCalibRx.Fs, ...
    'YLimits',                        [-120,-60],...
    'SpectralAverages',               50, ...
    'FrequencySpan',                  'Start and stop frequencies', ...
    'StartFrequency',                 -100e3, ...
    'StopFrequency',                  100e3,...
    'Position',                       figposition([50 30 30 40]));
radio = 

  comm.SDRuReceiver with properties:

                 Platform: 'N200/N210/USRP2'
                IPAddress: '192.168.10.2'
           ChannelMapping: 1
          CenterFrequency: 1.8500e+09
    LocalOscillatorOffset: 0
                     Gain: 38
                PPSSource: 'Internal'
        EnableTimeTrigger: false
              ClockSource: 'Internal'
          MasterClockRate: 100000000
         DecimationFactor: 500
        TransportDataType: 'int16'
           OutputDataType: 'double'
          SamplesPerFrame: 4096
          EnableBurstMode: false

Stream Processing

Loop until the example reaches the target number of frames.
% Check for the status of the USRP radio
if radioFound
    for iFrame = 1 : prmFreqCalibRx.TotalFrames
        [rxSig, len ] = radio();
        if len > 0
         % Display received frequency spectrum.
         specAnalyzer(rxSig);
         % Compute the frequency offset.
         [~, offset] = CFO(rxSig);
         % Print the frequency offset compensation value in MATLAB command
         % window.
         offsetCompensationValue = -offset;
        end
    end
else
    warning(message('sdru:sysobjdemos:MainLoop'))
end

% Release all System objects
release(radio);
clear radio
release(CFO);

Conclusion

In this example, you used System objects to build a receiver that calculates the relative frequency offset between a USRP transmitter and a USRP receiver.

Appendix

The following scripts are used in this example.