FRS/GMRS Walkie-Talkie Receiver with RTL-SDR Radio

This example shows how to use the RTL-SDR radio with MATLAB® and Simulink® 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.

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.

This example is implemented in two versions:

The following text describes the Simulink version, but both versions have the same functionality.


Walkie-talkies provide a subscription-free method of communicating over short distances. Although their popularity has been diminished by the rise of cell phones, they are still useful when lack of reception or high per-minute charges hinders the use of cell phones.

Modern walkie-talkies operate on the FRS/GMRS standards. Both standards use frequency modulation (FM) at 462 or 467 MHz, which is in the UHF (Ultra High Frequency) band. You will use a walkie-talkie as the transmitter for this example.

Structure of the Example

This is the top-level block diagram of the model:

Running the Example

Turn on your walkie-talkie, set the channel to be one of the 14 channels (numbered 1 to 14) and the private code to be either one of the 38 private codes (numbered 1 to 38) or 0, in which case no squelch system is used and all received messages are accepted. Note that the private codes above 38 are digital codes and are not implemented in this example.

Set the channel and private code in the Model Parameters GUI in the model so that they match the settings on the walkie-talkie. Run the model, speak into the walkie-talkie, and see if you can hear your voice come out of the computer speakers. If not, try adjusting the "Average signal threshold for squelch" parameter downward slightly. You can change the channel and private code without stopping and restarting the model.

If you hear some dropouts or delay in the sound, run the model in Accelerator mode. From the model menu, select Simulation->Accelerator, then click the run button. If you still experience dropouts or delay in Accelerator mode, try running the model in Rapid Accelerator mode.

FRS/GMRS Receiver Subsystem

The RTL-SDR Receiver block converts the RF waveform to complex baseband samples, which become the input to this subsystem.

Below is the block diagram of the FRS-GMRS Receiver subsystem:

Automatic Gain Control

The Automatic Gain Control block is the first block that processes the received signal. It processes the signal to ensure that the average magnitude of the samples is about 1. In this case, the walkie-talkie transmitter is likely nearby the RTL-SDR radio, which implies that the received signal should not suffer from fading, and the received noise should be low. In practice, the received signals will likely suffer from fading and low SNR.

Channel Selectivity and FM Demodulation

The channel selectivity filter is the next block. If the incoming signal is from an adjacent channel, a low pass channel separation filter will reduce its power significantly. 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.

Next, a channel selector computes the average power of the filtered signal, and 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.

The output goes into the FM Demodulator Baseband block the maximum frequency deviation of which is set to 2.5 kHz.

After FM demodulation, the FIR Decimation block converts the sampling rate to 240 kHz / 30 = 8 kHz. This is one of the native sample rates of the audio device on your host computer.

Continuous Tone-Coded Squelch System (CTCSS) and Decision Block

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 into the Decision block. The Goertzel algorithm is used because it provides an efficient method to compute the frequency components at predetermined frequencies (namely, the tone code frequencies used by FRS/GMRS).

The Decision block compares the decoded code with a preselected code and 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.

Audio Output

Before the audio device, a high pass filter with a cutoff frequency of 260 Hz is used to filter out the CTCSS tones (which have a maximum frequency of 250 Hz) so that they are not heard.

The Audio Device Writer block is set up by default to output to the current audio device in your system preferences.

Exploring the Example

The CTCSS decoding computes the DTFT (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 DTFT 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 16384 will cause 2 seconds of delay, since the CTCSS decoder operates at an 8 kHz sampling rate. This creates a tradeoff 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 getParamsSdrrFRSRx function and changing the value of the CTCSSDecodeBlockLength field. This will enable you to observe the tradeoff and find the optimal value for your transmitter/receiver pair.


The following script is used in this example:


Was this topic helpful?