Building an SDR FM Radio Based on ADALM Pluto with GNU Radio

Building an SDR FM Radio Based on ADALM Pluto with GNU Radio

Today, I will share how a senior communications engineer, 【Urban Wood】, implemented an SDR FM player using the graphical programming tool GNU Radio on Windows, and added stereo modulation functionality.

Here we go, enjoy!

Funpack Activity Report – Issue 5

Part One: Completion Status of Activity Tasks

I chose the first topic, the FM player. On one hand, it was my first time using both the software and hardware, and this topic was relatively easier to implement; on the other hand, GNURadio is something that can be explored for a long time, and I wanted to study it seriously, so I started with this to secure a baseline and plan to expand my learning later when I have time.

First, following the official website and activity video prompts, I implemented the basic requirements of the topic, expanded the frequency band of ADALM-PLUTO, and modified the AD9363 to AD9361, allowing it to reach from 70MHz to 6GHz; at the same time, I replaced the ADALM-PLUTO antenna. I first found a pull rod antenna but discovered the interface was incompatible, then I found an unused network cable, pulled out a twisted pair wire, and without stripping the insulation (just exposing a bit of copper), it fit perfectly as an FM antenna. It worked excellently, just wrapped around the curtain pull cord, and I could adjust the height daily by raising and lowering the cord, achieving two purposes at once. When there is no ready-made antenna, this can be a temporary solution. Regarding the FM radio functionality, I mainly implemented it under Windows using GNURadio, achieving demodulation of FM broadcast from the frequency band of 87~108M, as well as an upper computer interface to realize the frequency modulation function.

At the same time, I also added stereo modulation functionality, achieving volume adjustment, fixed frequency selection, frequency waterfall chart in the frequency domain, and amplitude waveform chart in the time domain interface functionality expansion; I also attempted to install GNURadio on Linux, choosing the domestic deepin20 system. Although the application store has GNURadio built-in, I still completed the installation via command line by referring to the documentation on wiki.analog.com, as I hadn’t installed the PLUTO driver and related modules. For specific effects, please refer to the video I uploaded titled “Building an SDR FM Radio Based on ADALM Pluto with GNU Radio”; I also uploaded a video with the same name on Bilibili, my account is “都是_木头”.

Part Two: Key Code Snippets Corresponding to Each Function

Since GNU Radio can be implemented directly through graphical programming, I did not add my own code, so I will mainly provide a brief explanation of some key module parameter settings:

Step One: Achieving the Most Basic Functionality, which is to receive a station and produce sound.
The filename is ADALM PlutoSDR fm_demod_easy.grc

The data flow is as follows: PlutoSDR_Source->Rational Resampler->FM Demod (or WBFM Receiver)>Audio Sink. Connect these modules in this order and modify the corresponding parameters to resolve errors encountered during debugging. Let’s look at it in reverse order:

Audio Sink module is straightforward to use; it receives input signals and plays them through speakers. There is only one rate setting, the most common being 48kHz, which we will use.

Audio_sample_rate: 48kHz

FM Demod is the demodulation module; here we only need to set two parameters: the input rate and the decimation value, while the other parameters can remain at their defaults. The Channel Rate is the input rate, which is the output rate of Rational Resampler, decimated to Audio_sample_rate; the decimation rate can be set by ourselves, and we set it to 8, which will align with the insertion rate.

Channel Rate: Audio_sample_rate * Audio_Decimation = 48kHz * 8 = 384kHz
Audio Decimation: Audio_Decimation = 8

Rational Resampler is referred to as a rational resampling polyphase FIR filter. In simple terms, it changes the signal sampling rate through decimation and interpolation to adjust the data flow speed for easier backend processing. Here, because the incoming baseband signal is still outputting at the initial sampling rate of 2.8M, which is relatively high compared to audio signals below 20kHz, we perform downsampling on the sampled data to facilitate audio data processing. At the same time, when setting the decimation value, the sampling rate must be converted to an integer (the module automatically rounds), and to keep it simple, we will not perform interpolation, setting Interpolation to 1.

Interpolation: 1

Decimation: int(samp_rate / Channel Rate )= int(2.8M / 384kHz) = 7

The remaining parameters can remain at their defaults.

There are actually many options for this part; parameters can be adjusted based on needs, or other modules can be selected, as long as they have sampling adjustment functionality, low-pass filters can achieve the aforementioned functionality, with the only difference being parameter settings.

PlutoSDR Source, GNU Radio has two built-in Pluto modules, one source and one sink; PlutoSDR Source is the source, and the other is Pluto Sink. Here, we only used PlutoSDR Source as the receiver. The Device URI is set according to the Pluto’s IP address, meaning that the PC and Pluto communicate via network interface. The LO Frequency is set to the station frequency, and the sampling rate Sample Rate was mentioned to be 2.8M; the RF Bandwidth configures the RX analog filter bandwidth, which states it should be limited between 200kHz and 52M, which is likely related to Pluto’s hardware specifications. In practice, it seems to have no effect; it can still work below 200kHz, though I’m not sure if it defaults to 200kHz when below the lower limit.

The remaining parameters can remain at their defaults.

After executing this, you should be able to hear the broadcast.

Step Two: Add a graphical interface and enhance some adjustment functionalities.

The file is: ADALM PlutoSDR fm_demod_GUI.grc

Mainly added three display modules: Qt gui frequency sink, Qt gui waterfall sink, and Qt gui time sink; additionally, volume adjustment and channel tuning functionalities were added. The specific parameters can be viewed in the source file. One important point to note is that the data types must be unified; otherwise, some parameter settings will not be achievable.

Actually, WX modules can also be used, but they would need to be completely replaced, and some names and parameter settings differ slightly. The display is somewhat better with Qt, each has its advantages.

Step Three: Change the module to achieve stereo.

The file is: ADALM PlutoSDR WBFM_receive_PLL_Stereo.grc

The simplest way is to change the demodulation module to WBFM Receive PLL, which is also a filter. Of course, two output ports need to connect to respective multiply_const modules, similarly, the Qt gui time sink and audio_sink need to be changed to two receivers.

Part Three: Reflections on This Activity

In fact, this interface and functionality are still relatively basic. Software like SDRSharp has many more perfect and powerful software interfaces and functionalities. Although what I implemented is still quite rough, participating in this activity has indeed yielded a lot, at least the following:

Firstly, I achieved three firsts. The first time using the graphical programming tool GNU Radio, the first time recording a video with OBS Studio, and the first time (unwillingly) becoming a content creator. Especially since both of these software are open source and very powerful, it has increased my interest in open-source software, especially professional open-source tools. Without participating in this activity, I probably wouldn’t have had the opportunity.

Secondly, I revisited communication principles and digital signal processing knowledge. Although I have studied these specialized courses, I didn’t have such good software and hardware conditions during previous learning; it was purely theoretical learning, and I rarely touched it after completing the course. The functional modules in GNU Radio are a concrete representation of theoretical concepts, serving as an intuitive simulator; combined with Pluto, it has completed a real engineering implementation, significantly increasing playability. It is definitely an excellent learning tool for communication principles and digital signal processing courses. Those familiar yet unfamiliar terms have pulled me back into the classroom.

Thirdly, I discovered many resources. Whether on hardware forums, Bilibili, CSDN, Zhihu, etc., I found a lot of resources related to software-defined radio; the materials shared in the activity group and the questions discussed provided me with considerable reference and inspiration. In fact, many of the original links provided by GNU Radio and ADI’s official websites, and many examples are explained very thoroughly; I found the usage of many modules there, and studying their descriptions carefully is usually sufficient.

Fourthly, I met many experts. In the discussion group, Su teacher is well known, and there are enthusiastic contributors like Frank, Lucia, video sharers like Teray, experience sharers like Circle and Chris, etc. Although we have not met in person, they are all worthy of my learning and gratitude. I also noticed an interesting debate shared by the openWIFI author “Paper Plane” about Pluto on Zhihu, which is extremely exciting and highlights Pluto’s high cost-performance ratio even more.

There are many gains that cannot be listed one by one. In summary, it has sparked my interest in learning and exploring software-defined radio, and even aroused my interest in Matlab, Linux, Python, FPGA, etc. Just the other day, I saw on the GNU Radio official website that there is a conference event in September, and I am curious about what new things might emerge, so I will keep an eye on it.

As for suggestions, I feel that the price of the Pluto project is too high, which may deter many people. Although subsidies were added later, the number of participants is still quite limited, which is somewhat regrettable. Additionally, the hardware activities are excellent, but for some, they may not be difficult, but for beginners, the time is a bit tight, especially for Funpack, which has a short cycle. I suggest organizing a similar follow-up event to promote projects that receive good feedback.

Finally, I would like to thank all the teachers at Yinge for their hard work!

END

Yinge Academy

The Yinge team is dedicated to providing standardized core skill courses for electronic engineers and students in related fields, helping everyone effectively enhance their professional capabilities at various stages of learning and work.

Building an SDR FM Radio Based on ADALM Pluto with GNU Radio

Yinge Academy

Let’s explore and advance together in the field of electronics

Follow the Yinge service account for instant access to classes

Building an SDR FM Radio Based on ADALM Pluto with GNU Radio

Click to read the original text for the latest Funpack activity

Leave a Comment

Your email address will not be published. Required fields are marked *