Main Content

QPSK Receiver with USRP Hardware

This example shows how to design a QPSK reciever using a USRP™ radio and USRP System objects. The QPSK receiver receives and demodulates the signal sent by the QPSK Transmitter with USRP Hardware example at bit rate of up to 1 Mbps, and prints the demodulated signal in the MATLAB® command line. In particular, this example illustrates methods to address real-world wireless communications issues like carrier frequency and phase offset, timing recovery and frame synchronization.

For the Simulink® implementation of the same system, refer to the QPSK Receiver with USRP Hardware in Simulink in Simulink example.

Required Hardware and Software

To run this example, you need one of these USRP radios and the corresponding software support package.

The example requires two MATLAB sessions, one for the transmitter and one for the receiver. You run the QPSK Transmitter with USRP Hardware example in one MATLAB session to transmit the QPSK signal.

Select Radio

Select the required radio platform from the the drop down list.

platform = "B210";
address  = '3136D21';

Initialize Receiver Parameters

Set the sample rate, gain, and center frequency. Ensure that the specified center frequency of the receiver System object is within the acceptable range of the selected RF card.Specify the desired capture time in seconds. The sdruqpskreceiver_init.m script initializes the simulation parameters and generates the structure prmQPSKReceiver.

USRPGain            = 35; % Set radio gain
USRPCenterFrequency = 915000000; % Set radio center frequency
captureTime         = 10; % Set radio capture time
sampleRate          = 1000000; % Set input signal sample rate
isHDLCompatible     = false;  % disable to run 'FFT-Based' coarse frequency compensation instead of 'Correlation-Based' for improved performance in MATLAB version.
printReceivedData   = false;  % enable to print received data

% Receiver parameter structure
prmQPSKReceiver = sdruqpskreceiver_init(platform, address, sampleRate, USRPCenterFrequency, ...
    USRPGain, captureTime, isHDLCompatible);

Code Architecture

The function runSDRuQPSKReceiver implements the QPSK receiver using two System objects. It selects comm.SDRuReceiver System object for interfacing with the USRP radio and uses the QPSKReceiver System object for data decoding.

The host computer communicates with the USRP radio using comm.SDRuReceiver and with the ADALM-PLUTO radio using sdrrx System object. The prmQPSKReceiver parameter structure sets the center frequency, gain, and interpolation factor.

The QPSKReceiver demodulates and retrieves the original transmitted message. The QPSKReceiver has six subcomponents, modeled using System objects.

  • Automatic gain control: The automatic gain control (AGC) subcomponent sets the output power to a particular level to ensure that the equivalent gains of the phase and timing error detectors are constant over time. The automatic gain control (AGC) is placed before the raised cosine receive filter so that the signal amplitude can be measured with an oversampling factor of two. This process improves the accuracy of the estimate.

  • Coarse frequency compensation: The coarse frequency compensator subcomponent uses a correlation-based algorithm to roughly estimate the frequency offset and then compensate for it. The estimated coarse frequency offset is averaged so that fine frequency compensation is allowed to lock or converge. Hence, the coarse frequency offset is estimated using a comm.CoarseFrequencyCompensator System object and an averaging formula. The comm.PhaseFrequencyOffset performs the compensation.

  • Timing recovery: Performs timing recovery with closed-loop scalar processing to counteract the channel-induced delays, using a comm.SymbolSynchronizer System object. The comm.SymbolSynchronizer object implements a phase locked loop (PLL) to correct the symbol timing error in the received signal. For this example, you select the rotationally-invariant Gardner timing error detector, allowing timing recovery to take place before fine frequency compensation. The input to the comm.SymbolSynchronizer object is a fixed-length frame of samples and the output is a frame of symbols whose length can vary due to bit stuffing and stripping, depending on actual channel delays.

  • Fine frequency compensation: The fine frequency compensation subcomponent performs closed-loop scalar processing and compensates for the frequency offset accurately using a comm.CarrierSynchronizer System object. The comm.CarrierSynchronizer object implements a PLL to track the residual frequency offset and the phase offset in the input signal.

  • Frame synchronization: The frame synchronization sub component performs frame synchronization and converts the variable length symbol inputs into fixed-length outputs using a FrameSynchronizer System object. The FrameSynchronizer object has a secondary boolean scalar output that indicates the validity of the first frame output.

  • Data decoder: The data decoder subcomponent performs phase ambiguity resolution and demodulation. Also, the data decoder compares the regenerated message with the transmitted one and calculates the BER.

Receive QPSK Signal and Calculate BER

Run the example to start receiving the QPSK signal. The QPSK receiver demodulates and calculates the bit error rate (BER) of the received signal.

[BER, overflow] = runSDRuQPSKReceiver(prmQPSKReceiver, printReceivedData); 
fprintf('Error rate is = %f.\n',BER(1));
Error rate is = 0.000170.
fprintf('Number of detected errors = %d.\n',BER(2));
Number of detected errors = 1163.
fprintf('Total number of compared samples = %d.\n',BER(3));
Total number of compared samples = 6837600.
fprintf('Total number of overflows = %d.\n', overflow);
Total number of overflows = 1.

The QPSK receiver calculates the BER value only for the 'Hello world' message part when some of the adaptive components in the QPSK receiver are not converged. Initially, the BER value is high since some of the adaptive components in the QPSK receiver are still in transient state. Once the transient state passes, the BER value decreases. To achieve lower BER values, you can increase the simulation time by modifying the captureTime in the receiver initialization file.

Troubleshooting

Unable to decode received signal

Problem

  • The QPSK receiver fails to decode the received signal.

Possible causes

  • The gains set for the USRP transmitter and receiver System objects may not be optimal due to the varying gain levels across different USRP RF cards.

  • The preamble detector threshold is not correctly set, resulting in recurrent garbled messages or no output message.

  • A large relative frequency offset between the transmit and receive radios.

Possible solutions

  • Adjust the SDRGain in both the USRP transmitter and receiver System objects to match the specific gain requirements of your RF cards.

  • If messages are consistently garbled, increase the preamble detector's threshold in the receiver initialization file. Conversely, if there is no output message, decrease this threshold.

  • To correct for a large relative frequency offset, transmit a tone at a known frequency and measure the offset between the transmitted and received frequency. Then, apply this offset to the SDRCenterFrequency in the receiver System object. Additionally, increase the maximum frequency offset parameter in the receiver initialization file.

Supporting Functions

This example uses the following functions:

  • runSDRuQPSKReceiver.m

  • sdruqpskreceiver_init.m

  • QPSKReceiver.m

References

1. Rice, Michael. Digital Communications - A Discrete-Time Approach. 1st ed. New York, NY: Prentice Hall, 2008.