Family Radio Service (FRS) Full-Duplex Transceiver with USRP™ Hardware
This example shows how to use two Universal Software Radio Peripheral devices exploiting SDRu (Software Defined Radio USRP System objects to perform full duplex communication by transmitting/receiving recorded audio simultaneously using MATLAB® and the FRS protocol.
Please refer to the Setup and Configuration section ofGuided USRP Radio Support Package Hardware Setup for details on configuring your host computer to work with the SDRu Transmitter and SDRu Receiver System objects™.
In order to run this example, you need two host computers connected to two USRP radios with daughterboards (e.g. SBX or WBX) that support full-duplex operation and the FRS band. Using this script, FRSFullDuplexTransceiverWithUSRPHardwareExample, the first USRP radio sends one audio signal at 467.6125 MHz, and simultaneously receives another audio signal at 467.6625 MHz. The second USRP radio sends at 467.6625 MHz and receives at 467.6125 MHz using the MATLAB script FRSFullDuplexTransceiverWithUSRPHardwareExample_2. Each host computer plays the received audio signal on its audio device.
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;
Checking radio connections...
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
Initialization
The configureFDTx and configureFDRx MATLAB functions initialize simulation parameters and generate parameter structures for the FRS transmitter and receiver systems.
The frequency calibration compensation value, rfRxFreqCorrection, can be determined for your USRP environment by running the MATLAB script FrequencyOffsetCalibrationReceiverUSRPHardwareExample while sending a sine wave at the RF receiver center frequency, rfRxFreq, with MATLAB script FrequencyOffsetCalibrationTransmitterUSRPHardwareExample.
% Transmitter Initialization rfTxFreq = 467.6125e6; % RF Transmitter Center Frequency (Hz) frsFDTxParams = configureFDTx(platform, rfTxFreq); % Receiver Initialization rfRxFreq = 467.6625e6; % RF Receiver Center Frequency (Hz) rfRxFreqCorrection = -4e3; % Frequency calibration compensation value (Hz) rfRxFreqActual = rfRxFreq + rfRxFreqCorrection; frsFDRxParams = configureFDRx(platform, rfRxFreqActual);
Transmit One Audio File Using FRS Waveform
This example uses a source object to generate data signals for the transmitter. The source signal is a multimedia audio file. When using a multimedia file, the sampling rate needs to be converted to 8 kHz; therefore, the FRSGMRSDemoAudioSource object employs a rate conversion filter to convert the 22.5 kHz signal to an 8 kHz signal.
% Create a data source to transmit the contents of a sound file at a % sampling frequency of 8 kHz. source = FRSGMRSDemoSource('Sound file', frsFDTxParams.SourceSampleRate); source.AudioFileName = 'speech_dft.avi'; % The Continuous Tone-Coded Squelch System (CTCSS) filters out % undesired communication or interference from these other users by % generating a tone between 67 Hz and 250 Hz and transmitting it along with % the source signal. ctcss = dsp.SineWave(frsFDTxParams.CTCSSAmplitude, ... frsFDTxParams.CTCSSToneFrequencies(frsFDTxParams.CTCSSCode), ... 'SampleRate', frsFDTxParams.SourceSampleRate, ... 'SamplesPerFrame', frsFDTxParams.SourceFrameLength, ... 'OutputDataType', 'single'); % The interpolator and FM modulator convert the sampling rate of the sum of % the modulating signal and the CTCSS tone to match the USRP hardware % sampling rate of 200 kHz. interpolator = dsp.FIRInterpolator(frsFDTxParams.InterpolationFactor, ... frsFDTxParams.InterpolationNumerator); fmMod = comm.FMModulator('SampleRate', frsFDTxParams.RadioSampleRate, ... 'FrequencyDeviation', frsFDTxParams.FrequencyDeviation); % The SDRu transmitter sets the interpolation factor and master clock rate % so that the example uses round numbers to convert the sampling rate from % 8 kHz to 200 kHz. 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. % Set up transmitter radio object to use the found radio switch platform case {'B200','B210'} radioTx = comm.SDRuTransmitter('Platform', platform, ... 'SerialNum', address, ... 'MasterClockRate', frsFDTxParams.RadioMasterClockRate, ... 'CenterFrequency', frsFDTxParams.CenterFrequency,... 'Gain', frsFDTxParams.RadioGain, ... 'InterpolationFactor', frsFDTxParams.RadioInterpolationFactor) case {'X300','X310','N300','N310','N320/N321'} radioTx = comm.SDRuTransmitter('Platform', platform, ... 'IPAddress', address, ... 'MasterClockRate', frsFDTxParams.RadioMasterClockRate, ... 'CenterFrequency', frsFDTxParams.CenterFrequency,... 'Gain', frsFDTxParams.RadioGain, ... 'InterpolationFactor', frsFDTxParams.RadioInterpolationFactor) case {'N200/N210/USRP2'} radioTx = comm.SDRuTransmitter('Platform', platform, ... 'IPAddress', address, ... 'CenterFrequency', frsFDTxParams.CenterFrequency,... 'Gain', frsFDTxParams.RadioGain, ... 'InterpolationFactor', frsFDTxParams.RadioInterpolationFactor) end
radioTx = comm.SDRuTransmitter with properties: Platform: 'N200/N210/USRP2' IPAddress: '192.168.10.2' ChannelMapping: 1 CenterFrequency: 467612500 LocalOscillatorOffset: 0 Gain: 15 PPSSource: 'Internal' ClockSource: 'Internal' MasterClockRate: 100000000 InterpolationFactor: 500 TransportDataType: 'int16' EnableBurstMode: false
Receive Another Audio File Using FRS Demodulation
Create objects to resample the input to 200 kHz, perform automatic gain control, perform channel selectivity filtering, FM demodulate, resample to an 8 kHz audio output, perform CTCSS decoding, filter out the CTCSS tones, then send the signal to an audio output device.
% Set up transmitter radio object to use the found radio switch platform case {'B200','B210'} radioRx = comm.SDRuReceiver('Platform', platform, ... 'SerialNum', address, ... 'MasterClockRate', frsFDRxParams.RadioMasterClockRate, ... 'CenterFrequency', frsFDRxParams.CenterFrequency,... 'Gain', frsFDRxParams.RadioGain, ... 'DecimationFactor', frsFDRxParams.RadioDecimationFactor, ... 'SamplesPerFrame', frsFDRxParams.RadioFrameLength, ... 'OutputDataType', 'single') case {'X300','X310','N300','N310','N320/N321'} radioRx = comm.SDRuReceiver('Platform', platform, ... 'IPAddress', address, ... 'MasterClockRate', frsFDRxParams.RadioMasterClockRate, ... 'CenterFrequency', frsFDRxParams.CenterFrequency,... 'Gain', frsFDRxParams.RadioGain, ... 'DecimationFactor', frsFDRxParams.RadioDecimationFactor, ... 'SamplesPerFrame', frsFDRxParams.RadioFrameLength, ... 'OutputDataType', 'single') case {'N200/N210/USRP2'} radioRx = comm.SDRuReceiver('Platform', platform, ... 'IPAddress', address, ... 'CenterFrequency', frsFDRxParams.CenterFrequency,... 'Gain', frsFDRxParams.RadioGain, ... 'DecimationFactor', frsFDRxParams.RadioDecimationFactor, ... 'SamplesPerFrame', frsFDRxParams.RadioFrameLength, ... 'OutputDataType', 'single') end
radioRx = comm.SDRuReceiver with properties: Platform: 'N200/N210/USRP2' IPAddress: '192.168.10.2' ChannelMapping: 1 CenterFrequency: 467658500 LocalOscillatorOffset: 0 Gain: 5 PPSSource: 'Internal' ClockSource: 'Internal' MasterClockRate: 100000000 DecimationFactor: 500 TransportDataType: 'int16' OutputDataType: 'single' SamplesPerFrame: 4000 EnableBurstMode: false
% AGC agc = comm.AGC; % Low pass filter for channel separation channelFilter = frsFDRxParams.ChannelFilter; % FM demodulator fmDemod = comm.FMDemodulator('SampleRate', frsFDRxParams.RadioSampleRate, ... 'FrequencyDeviation', frsFDRxParams.FrequencyDeviation); % Decimation filter to resample to 8 kHz decimator = dsp.FIRDecimator(frsFDRxParams.DecimationFactor, ... frsFDRxParams.DecimationNumerator); % The CTCSS decoder compares the estimated received code with the % preselected code and then sends the signal to the audio device if the two % codes match. decoder = FRSGMRSDemoCTCSSDecoder(... 'MinimumBlockLength', frsFDRxParams.CTCSSDecodeBlockLength, ... 'SampleRate', frsFDRxParams.AudioSampleRate); % High pass filter to filter out CTCSS tones audioFilter = frsFDRxParams.AudioFilter; % Audio device writer audioPlayer = audioDeviceWriter(frsFDRxParams.AudioSampleRate);
Stream Processing Loop
% Perform stream processing if a radio is found. if radioFound % Loop until the example reaches the target stop time. timeCounter = 0; while timeCounter < frsFDTxParams.StopTime % Transmitter stream processing % ----------------------------------------------------------------- dataTx = step(source); % Generate audio waveform dataWTone = dataTx + step(ctcss); % Add CTCSS tones % Interpolation FM modulation outResamp = step(interpolator, dataWTone); % Resample to 200 kHz outMod = step(fmMod, outResamp); step(radioTx, outMod); % Transmit to USRP radio % Receiver stream processing % ----------------------------------------------------------------- dataRx = step(radioRx); outAGC = step(agc, dataRx); % AGC outChanFilt = step(channelFilter, outAGC); % Adjacent channel filtering rxAmp = mean(abs(outChanFilt)); if rxAmp > frsFDRxParams.DetectionThreshold outThreshold = outChanFilt; else outThreshold = complex(single(zeros(frsFDRxParams.RadioFrameLength, 1))); end % FM demodulation and decimation outFMDemod = step(fmDemod, outThreshold); % FM demodulate outDecim = step(decimator, outFMDemod); % Resample to 8 kHz % CTCSS decode and conditionally send to audio output rcvdCode = step(decoder, outDecim); if (rcvdCode == frsFDRxParams.CTCSSCode) || (frsFDRxParams.CTCSSCode == 0) rcvdSig = outDecim; else rcvdSig = single(zeros(frsFDRxParams.AudioFrameLength, 1)); end audioSig = step(audioFilter, rcvdSig); % Filter out CTCSS tones step(audioPlayer, audioSig); % Audio output timeCounter = timeCounter + frsFDRxParams.RadioFrameTime; end else warning(message('sdru:sysobjdemos:MainLoop')) end % Release all SDRu and audio resources , FM Modulator and Demodulator release(fmMod) release(radioTx) release(fmDemod) release(radioRx) release(audioPlayer)
Conclusion
In this example, you used Communications Toolbox™ System objects to perform full duplex transmission and reception using FRS waveforms and two USRP radios.
Appendix
The following functions are used in this example.