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.
200-Series USRP Radio (B2xx or N2xx) and Communications Toolbox Support Package for USRP Radio. For information on how to map an NI™ USRP device to an Ettus Research 200-series USRP device, see Supported Hardware and Required Software.
300-Series USRP Radio (X3xx) and Wireless Testbench Support Package for NI USRP Radios. For information on how to map an NI USRP device to an Ettus Research 300-series USRP device, see Supported Radio Devices (Wireless Testbench).
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. Thecomm.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. Thecomm.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 thecomm.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. Thecomm.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. TheFrameSynchronizer
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.