01 - Pluto Introduction
Hardware Required: ADALM-PLUTO
DOWNLOAD: CODE
This is the first tutorial in a series of tutorials focused on showing how to interface with the Analog Devices' Pluto SDR using Matlab.
There are numerous online resources for using the Pluto SDR with various finished signal analysis tools as well as resources for learning the complex aspects of building a software defined receiver. However, there are not very many introductory resources for learning how to work with an SDR by interfacing with it directly to transmit, read and process IQ data for beginners. This series of tutorials aim to fill this gap.
This tutorial assumes the user has successfully installed and setup Matlab as well as the Communications Toolbox, DSP Toolbox, and the Pluto Support Package.
CONTENTS
- Getting Started
- Configure Pluto
- Record FM Broadcast to IQ File
- Demodulate Recording and Play Audio
- Sample Audio Recordings
- Additional Resources
1. Getting Started
In this introductory tutorial we'll look at receiving radio signals using the Pluto SDR. We will go over setting up the radio in Matlab as well as collecting, recording, receiving/demodulating, and audio playback of a radio station. Given the built in functions in Matlab this is a relatively trivial exercise for the user but what happens in the background is not. Over the course of several tutorials we will dig deeper into these aspects. For now, we just want to see a piratical application in action to get us going!
First we need to connect a suitable antenna to the Pluto SDR. The Pluto SDR has two SMA connectors, one for transmit and one for receive. These two channels are for the most part independent of each other. We are only using the receive port for this tutorial. The two antennas that come with the Pluto SDR are not designed to be used at FM radio frequencies down in the VHF range. You can still use them for reception at FM radio frequencies, but you should NOT try to transmit as almost all the energy will be reflected back into the radio and not transmitted over the air. The reception will not be great so if you have an FM antenna available, use that instead. The antenna should ideally have a 50 ohm connector.
Now we need to setup the Matlab environment and define basic radio parameters. This includes the radio station's center frequency, audio sample rate, filename for the baseband IQ data file, filename for the wave file we can play back later, and the length of the recording.
% Reset Environment
clear;
clc;
% ------------- USER INPUT -------------
FM_freq = 91.5e6; % Choose FM Station (Hz)
FM_sample_rate = 48e3; % Default Audio Sample Rate
iq_recording = 'new_recording.bb'; % File Name of IQ FM Recording
wav_export = 'new_audio.wav'; % WAV Output File Name
record_duration = 10; % Record duration (seconds)
% --------------------------------------
2. Configure Pluto
The Pluto SDR technically has a AD9363 RF transceiver chip in it which is restricted to 325 MHz to 3.8 GHz operation. However, Analog Devices also makes the AD9361 and AD9364 RF transceiver chips which are very similar, but with an expanded frequency range of 70 MHz to 6 GHz. It is possible to configure the Pluto radio to treat the RF transceiver chip inside it as if it is a AD9364 in order to operate the Pluto SDR over the entire expanded frequency range. Presumably Analog Devices did not design the AD9363 for the wider bandwidth and consequently did not qualify it or design it in such a way that it meets all their performance metrics beyond the 325 MHz to 3.8 GHz range. However, for hobbyist purposes, this does not appear to be an issue.
So, let's go ahead and configure the radio to operate over the expanded range since we need to be able to access the FM Radio frequency band which spans 88.0 MHz – 108.0 MHz in the US.
% Expand Pluto Frequency Range
configurePlutoRadio('AD9364');
3. Record FM Broadcast to IQ File
Now we finally come to the interesting part where we collect and playback audio from a live FM radio station. The first thing we need to do is collect a series of RF samples at a particular frequency and sample rate, analogous to how you would collect a series of analog samples using an analog to digital converter (ADC). In fact you can very much think of the Pluto SDR as an ADC and a digital to analog converter (DAC) in a single chip, but operating at very high sample rates, and surrounded by a plethora of additional functionality related to signal attenuation, signal amplification, frequency up-conversion, frequency down-conversion and filtering among many other things.
The Pluto SDR has a 32,768 sample receive buffer, where each sample consists of a 16 bit I and 16 bit Q pair for a total of 131,072 bytes. There is also a separate transmit buffer of equivalent size. This is where the interdependence between sample rate and the time it takes to fill a 'frame' of data come into play. A frame doesn't need to be the full size of the buffer (it can be smaller or larger), but if it is and you are sampling at 1 million samples per second, you will get a chunk of 32,768 samples every 32.768 millisecond. Likewise, if you sample at 100,000 samples per second, it will take 327.68 milliseconds to fill the entire buffer.
The Pluto SDR can be configure for a sample rate between 65,105 SPS to 20 MSPS, however if you sample above 1 MSPS you will soon run into the USB 2.0 protocol limit for transferring data between the Pluto and your computer.
So next we will do the following:
- Setup an SDR receiver object, 'rx', configured with the parameters we previously defined.
- Capture RF samples using the 'capture' function with our 'rx' object as a parameter of the function. This recording will be saved to a baseband ('.bb') file which we will open later on when demodulating and playing back the captured FM broadcast.
- Release the receive object. If we don't release the receive object we can't create a new receive object using the same radio receive channel.
% Create Pluto Receive Object - Connect to SDR
rx = sdrrx('Pluto','BasebandSampleRate',528e3, ...
'CenterFrequency',FM_freq,'OutputDataType','double');
% Capture FM Broadcast and save to IQ File
disp('Capturing');
capture(rx,record_duration,'Seconds','Filename',iq_recording, ...
'EnableOversizeCapture', 1);
disp('Done Capturing');
% Release Pluto Receive Object - Disconnect from SDR
release(rx);
4. Demodulate Recording and Play Audio
Although this example conflates a 'receiver' with a 'demodulator,' it is important to remember these are two very different operations.
A receive is responsible for, among other things, carrier recovery, receive filtering, timing recovery, equalization, demodulation, and decoding. Only once a receiver has achieved carrier lock and is spitting out valid symbols does a demodulator come into play. A demodulator is just one of many different components of a receiver. However, conveniently for us, Matlab's comm.FMBroadcastDemodulator object takes care of all this for us in this particular example.
So next we will do the following:
- Open the file where we saved our baseband recording in Step 3 using the comm.BasebandFileReader object.
- Create a WAV dsp.AudioFileWriter object that we will later use to generate an audio file.
- Create a demodulator object using comm.FMBroadcastDemodulator. Although it is called a demodulator, it is really a full 'FM Receiver' implementation.
- Step through the baseband data file until we reach end of file and play it back over the computer speaker as well as off the demodulated audio into an .wav audio file.
- Release the audio file writer and close the file so we can open the .wav audio file using another program.
% Open IQ recording and define how many samples to read at a time
bbr = comm.BasebandFileReader(iq_recording);
bbr.SamplesPerFrame = 4400;
% Open a WAV output file to store our recording to
afw = dsp.AudioFileWriter(wav_export,'SampleRate',FM_sample_rate);
% Create FM Receiver Object
fmbDemod = comm.FMBroadcastDemodulator('AudioSampleRate', ...
FM_sample_rate,'SampleRate', ...
bbr.Metadata.BasebandSampleRate,'PlaySound',true);
% Read IQ frame, demodulate, playback audio, and write to WAV file
disp('Demod & Playback');
while ~isDone(bbr)
audio = fmbDemod(bbr());
afw(audio);
end
% Cleanup
release(afw);
disp('Done');
5. Sample Audio Recordings
Speaking Example
Music Example