Main Content

FRS/GMRS Walkie-Talkie Receiver with USRP® Hardware

This example shows how to use the Universal Software Radio Peripheral® (USRP®) device with MATLAB® to implement a walkie-talkie receiver. The specific radio standard that this example follows is FRS/GMRS (Family Radio Service / General Mobile Radio Service) with CTCSS (Continuous Tone-Coded Squelch System). You can transmit a signal to the implemented receiver using a commercial walkie-talkie device.

In order to run this example, you need a USRP® board with an appropriate receiver daughterboard that supports the UHF 462-467 MHz band (for example, WBX). Please refer to the Setup and Configuration section of Documentation for USRP® Radio for details on configuring your host computer to work with the SDRu Receiver System object™.

This example is designed to work with USA standards for FRS/GMRS operation. The technical specifications for these standards can be found at [ 1 ] and [ 2 ]. Operation in other countries may or may not work.


Please refer to the FRS/GMRS Walkie-Talkie Transmitter with USRP® Hardware example for general information and overview details. Note that all the information in that section applies to this example, except that this example is designed to receive signals instead of transmit them.

Also, please refer to the Simulink® model in the FRS/GMRS Walkie-Talkie Receiver with USRP® Hardware example for a block diagram view of the system.

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;
  radioFound = false;
  address = '';
  platform = 'N200/N210/USRP2';
Checking radio connections...


The getParamsSdruFRSGMRSRxDemo.m function initializes some simulation parameters and generates a structure, frsRx. The fields of this structure are the parameters of the FRS/GMRS receiver system at hand.

% Configure the example to receive on channel 12 with the CTCSS code 5 with
% a detection threshold of 0.1.
channel = 12;
CTCSSCode = 5;
detectionThreshold = 0.1;

frsRxParams = getParamsSdruFRSGMRSRxDemo(platform, channel, CTCSSCode, ...
frsRxParams = 

  struct with fields:

      RadioMasterClockRate: 20000000
           RadioSampleRate: 200000
                 RadioGain: 5
     RadioDecimationFactor: 100
          RadioFrameLength: 4000
             ChannelFilter: [1×1 dsp.FIRFilter]
    ChannelFilterNumerator: [1×33 double]
        FrequencyDeviation: 2500
          DecimationFactor: 25
       DecimationNumerator: [1×600 double]
           AudioSampleRate: 8000
          AudioFrameLength: 160
                   Channel: 12
                 CTCSSCode: 5
        DetectionThreshold: 0.1000
    CTCSSDecodeBlockLength: 4000
      CTCSSToneFrequencies: [38×1 double]
      GoertzelCoefficients: [38×1 double]
               AudioFilter: [1×1 dsp.FIRFilter]
                  StopTime: 10
            RadioFrameTime: 0.0200

FRS/GMRS Receiver

The FRS/GMRS receiver example tunes the USRP® board to receive at the center frequency specified by the channel selection. The script applies automatic gain control (AGC) and FM demodulates the received signal. A CTCSS tone decoder passes the demodulated signal to an audio device if the received code matches the selected code.

AGC and Channel Selectivity Filter

Automatic gain controller applies a variable gain to the received signal to assure that the received signal amplitude is at a known level. In this example, the walkie-talkie transmitter is likely nearby the USRP® board, which implies that the received signal should not suffer from fading, and the received signal-to-noise ratio (SNR) should be high. In practice, the received signals will likely suffer from fading and low SNR.

agc = comm.AGC;

This script uses a low pass channel separation filter to reduce the signals from an adjacent channel. The gap between adjacent channels is 25 kHz, which means the baseband bandwidth is at most 12.5 kHz. Thus, we choose the cutoff frequency to be 10 kHz. Create a digital filter System object that implements an FIR transfer function and set the Numerator property to the value specified in the frsRx structure.

channelFilter = frsRxParams.ChannelFilter;

Next, a channel selector computes the average power of the filtered signal. If it is greater than a threshold (set to a default of 10%), the channel selector determines that the received signal is from the correct channel and it allows the signal to pass through. In the case of an out-of-band signal, although the channel separation filter reduces its magnitude, it is still FM modulated and the modulating signal will be present after FM demodulation. To reject such a signal completely, the channel selector outputs zero.

FM Demodulation and Decimation

This example uses the FM Demodulator Baseband System object whose sample rate and maximum frequency deviation are set to 200 kHz and 2.5 kHz, respectively.

fmDemod = comm.FMDemodulator('SampleRate', frsRxParams.RadioSampleRate, ...
    'FrequencyDeviation', frsRxParams.FrequencyDeviation);

A decimation filter converts the sampling rate to 8 kHz. This rate is one of the native sampling rates of your host computer's output audio device. Use an FIR decimator System object to convert the 200 kHz signal to an 8 kHz signal. Set the decimation factor to 25, and the numerator to the value specified in the frsRx structure.

decimator = dsp.FIRDecimator(frsRxParams.DecimationFactor, ...

Continuous Tone-Coded Squelch System (CTCSS)

The CTCSS [ 3 ] decoder computes the power at each CTCSS tone frequency using the Goertzel algorithm [ 4 ] and outputs the code with the largest power. The Goertzel algorithm provides an efficient method to compute the frequency components at predetermined frequencies, i.e., the tone code frequencies used by FRS/GMRS.

The script compares the estimated received code with the preselected code and then sends the signal to the audio device if the two codes match. When the preselected code is zero, it indicates no squelch system is used and the decision block passes the signal at the channel to the audio device no matter which code is used.

decoder = FRSGMRSDemoCTCSSDecoder(...
  'MinimumBlockLength', frsRxParams.CTCSSDecodeBlockLength, ...
  'SampleRate', frsRxParams.AudioSampleRate);

Audio Output

A high pass filter with a cutoff frequency of 260 Hz filters out the CTCSS tones, which have a maximum frequency of 250 Hz. Use an audio device writer System object to play the received signals through your computer's speakers. If you do not hear any sound, please select another device using the Device property of the audio device writer object, audioPlayer.

audioFilter = frsRxParams.AudioFilter;

audioPlayer = audioDeviceWriter(frsRxParams.AudioSampleRate);

Configuration of Receiver Object

The script 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.

% Setup radio object to use the found radio
switch platform
  case {'B200','B210'}
    radio = comm.SDRuReceiver('Platform', platform, ...
      'SerialNum', address, ...
      'MasterClockRate', frsRxParams.RadioMasterClockRate);
  case {'X300','X310'}
    radio = comm.SDRuReceiver('Platform', platform, ...
      'IPAddress', address, ...
      'MasterClockRate', frsRxParams.RadioMasterClockRate);
  case {'N200/N210/USRP2'}
    radio = comm.SDRuReceiver('Platform', platform, ...
        'IPAddress', address);
  case {'N300','N310'}
    radio = comm.SDRuReceiver('Platform', platform, ...
      'IPAddress', address, ...
      'MasterClockRate', frsRxParams.RadioMasterClockRate);
  case {'N320/N321'}
    radio = comm.SDRuReceiver('Platform', platform, ...
      'IPAddress', address, ...
      'MasterClockRate', frsRxParams.RadioMasterClockRate);

Set the master clock rate and decimation factor to obtain a sample rate of 200 kHz at the output of the SDRu receiver object. For example, for a B210 radio, set MasterClockRate to 20 MHz and DecimationRate to 100. For N200, N210, and USRP2 radios master clock rate is fixed at 100 MHz. The 200 kHz sample rate enables us to use a simple decimation filter to convert the sampling rate from 200 kHz to 8 kHz. Frame length controls the number of samples at the output of the SDRu receiver, which is the input to the AGC. The frame length must be an integer multiple of the decimation factor, which is 25. Set the frame length to 4000 samples. Select the output data type as single to reduce the required memory and speed up execution.Set the center frequency source to input port and the gain to 5 dB. Note that, for X3xx series radios, these numbers may vary to match the valid radio hardware values.

radio.CenterFrequencySource = 'Input port';
radio.Gain = frsRxParams.RadioGain;
radio.DecimationFactor = frsRxParams.RadioDecimationFactor;
radio.SamplesPerFrame = frsRxParams.RadioFrameLength;
radio.OutputDataType = 'single';

% Display SDRu receiver object
radio = 

  comm.SDRuReceiver with properties:

                 Platform: 'B210'
                SerialNum: '30F59A1'
           ChannelMapping: 1
    LocalOscillatorOffset: 0
                     Gain: 5
                PPSSource: 'Internal'
              ClockSource: 'Internal'
          MasterClockRate: 20000000
         DecimationFactor: 100
        TransportDataType: 'int16'
           OutputDataType: 'single'
          SamplesPerFrame: 4000
          EnableBurstMode: false

Running the Example

Turn on your walkie-talkie, set the channel to 12 and the private code to 5. The center frequency is a function of the selected channel number.

% Get the carrier frequency for the selected channel
fc = convertChan2FreqFRSGMRSDemo(frsRxParams.Channel);

Stream Processing Loop

Capture FRS/GMRS signals and demodulate for 10 seconds, which is specified by frsRx.StopTime. The SDRu object returns a column vector, x. Because the MATLAB script may run faster than the hardware, the object also returns the actual size of the valid data in x using the second output argument, len. If len is zero, then there is no new data for the demodulator code to process.

Check for the status of the USRP® radio

if radioFound
  % Loop until the example reaches the target stop time.
  timeCounter = 0;
  while timeCounter < frsRxParams.StopTime

    [data, len] = step(radio, fc);
    if len > 0

      % AGC and channel selectivity
      outAGC = step(agc, data);

      outChanFilt = step(channelFilter, outAGC);
      rxAmp = mean(abs(outChanFilt));
      if rxAmp > frsRxParams.DetectionThreshold
        x = outChanFilt;
        x = complex(single(zeros(frsRxParams.RadioFrameLength, 1)));

      % FM demodulator and decimation
      y = step(fmDemod, x);
      outRC = step(decimator, y);

      % CTCSS decoder
      rcvdCode = step(decoder, outRC);
      if (rcvdCode == frsRxParams.CTCSSCode) || (frsRxParams.CTCSSCode == 0)
        rcvdSig = outRC;
        rcvdSig = single(zeros(frsRxParams.AudioFrameLength, 1));

      % Output to audio device
      audioSig = step(audioFilter, rcvdSig);
      step(audioPlayer, audioSig);

      timeCounter = timeCounter + frsRxParams.RadioFrameTime;

Release the audio , FM Demodulator Baseband and USRP® resources.



In this example, you used Communications Toolbox™ System objects to build an FRS/GMRS receiver utilizing the USRP® device. The example showed that the MATLAB script can process signals captured by the USRP® device in real time.

Further Exploration

The CTCSS decoding computes the DFT (Discrete-Time Fourier Transform) of the incoming signal using the Goertzel algorithm and computes the power at the tone frequencies. Since the tone frequencies are very close to each other (only 3-4 Hz apart) the block length of the DFT should be large enough to provide enough resolution for the frequency analysis. However, long block lengths cause decoding delay. For example, a block length of 16000 will cause 2 seconds of delay because the CTCSS decoder operates at an 8 kHz sampling rate. This creates a trade-off between detection performance and processing latency. The optimal block length may depend on the quality of the transmitter and receiver, the distance between the transmitter and receiver, and other factors. You are encouraged to change the block length in the initialization function by navigating to the getParamsSdruFRSGMRSRxDemo function and changing the value of the CTCSSDecodeBlockLength field. This will enable you to observe the trade-off and find the optimal value for your transmitter/receiver pair.


The following function is used in this example.


Copyright Notice

Universal Software Radio Peripheral® and USRP® are trademarks of National Instruments Corp.