NOTE: This post was imported from my previous blog – v3l0c1r4pt0r.tk. It was originally published on 1st November 2013.
This post is the second part of the Instructable mentioned on the previous post. That’s tutorial on how to make simple FM radio using GRC. That task is in my opinion the simplest project that can be made using GRC so it’s in fact beginners guide to GNU Radio which is really capable software. I hope that it is only the first my project using that software.
It isn’t hard to find GRC projects that implements FM radio functionality, that’s a fact. But when it comes to reproduce them so they are working just like SDR# you’d realize it’s a bit harder task. At least I did. I found about a three such projects but there was never any included project file and the only materials was video or pictures. I admit the video has pretty good explanation but it still wasn’t enough. The rest was even worse. They were only blog posts with few screen shots and short description. So finally to reproduce functionality of SDR#’s FM radio I had to think on my own. And after few hours I did what I tried to do.
A bit of theory
But let’s start at the beginning. The first thing that you need to do to start creating your own FM receiver using GRC is to find FM station that can be received without disruptions so you can check if your program works as well as i.e. SDR#. It can be done with help of SDR# and when you found one you are ready to learn some theory about FM signal processing. In fact it could be omitted, but in my opinion it is better to know a bit. I personally am not any specialist in radio theory so it will be really simple and I might be wrong somewhere so if you find any mistake in that what I will write here just let me know in comments.
The simplest FM radio consists of few elements:
- signal source – in our case it would be RTL-SDR dongle
- low pass filter
- WBFM demodulator
- audio output – your PC’s sound card
There can be few other elements depending on input and output sample rate, if it will be possible to match them using only above elements there won’t be any other. So our task will be getting signal using RTL-SDR, passing it through low pass filter and FM demodulator and outputting on PC’s sound card. Meanwhile we will also need to match the sample rate of the input to the one of the output (2 MHz in to 48 KHz out). All elements of this circuit can be found by writing part of its name while list on the right is selected. Element’s names are the ones used as section header below.
Our signal input. We need to set its sample rate to 2M. It can be done by editing samp_rate variable and setting its value to 2e6. We need also to set the frequency of the station we want to receive. It is good practice to add every value that might be changed in the future as standalone variable. This can be done by adding Variable block from Variables category or, if you want to have possibility to edit it during the runtime block named WX GUI Slider or WX GUI Text Box and then just writing variable name as value in block’s properties.
Now we need to convert sample rate from 2M (samp_rate) to 500K which I realized is the best value for low pass filter’s input rate. To do that we need to add another variable, named i.e. quadrature, set its value to 500e3 (means: 500K). With that we need to add rational resampler’s block and set its decimation value to int(samp_rate/quadrature). Of course its input on the schematic should be connected to output of RTL-SDR Source (can be achieved by clicking on blue out on one block and then blue in on another).
Low Pass Filter
The next step is to filter out frequencies other than the one we centered in th previous step. In that task we will use a low pass filter block. We here set cutoff frequency to 100e3. This is because that’s standard band’s width. I don’t know what correct value for transition width should be, but trying to change that I found that the higher value the better so it’s finally set to 1M. Obviously it should be connected to resampler’s output.
Now we could do the nearly final and the most important step: placing the FM demodulator. In my case its quadrature rate equals 500k (that’s the same value as before so I set this to the value of quadrature variable). I don’t know if it could be changed to something else so if you are not sure just leave it as is. In that setting it should work.
Next Rational Resampler and Multiply Const
These elements’ job is to match the signal’s rate to the one supported by sound card and provide volume regulation. At first we need to convert rate from 500k to 48k so we need to decimate by 500 and then multiply by 48. In the second block we set const to volume. Now we can create variable or place WX GUI Slider with variable name set to volume. As you can see here color of WBFM demodulator is different than rational resampler’s and multiplier’s in and out. To change that you need to select them and use up and down arrows on your keyboard.
That one’s function is to output signal on our sound card. Now its only required to edit its rate and choose 48k from a drop down list and that’s it! If you don’t have that option just choose the biggest value and edit value in rational resampler and it should work. Now you should be able to execute your program and test if it works. To hear anything it will probably be required to increase volume to about 50.
Finally: some links
If you don’t know how some part has been done or what value should have a particular variable below you can download projects that I’ve made first learning to use GRC myself and then preparing this tutorial. There is one project presented here and one made earlier.
Congratulations for this very complete tutorial. I have been trough a lot of searching for fm radio receiver using an RTL device on GRC for the last month (october 2013) and you are the first that provides great sound quality, and precise explanations. For people like me who dream of using linux to listen/record commercial FM broadcast, the natural following of this project would be 1-stereo, 2-hints to improve antenna reception, 3-RDS data. Keep going like that!!!
It’s really good to hear that my work helped someone. To be honest I wasn’t thinking about expanding that project but reading RDS sounds really interesting and it’s binary transmission that is the thing that I planned to do as my next SDR project, of course when I will have some free time. Nevertheless implementations of RDS decoders can be easily found on the Net so I need to consider if there is sense to repeat other people’s work.
This is a great demo – complete enough to be useful, but simple enough to show someone else in a few mins. Had been looking for something like this to demo GNURadio+RTLUSB. Thanks for your hard work! You should be sure it’s referenced from http://sdr.osmocom.org/trac/wiki/rtl-sdr too.
Hi Great turtorial I have been playing with GNU Radio companion for a few weeks now but have a lot to learn …..
In this example are you using version 3.7.x.x. ? I have 3.6.x.x running on one laptop but when I run your script it comes up with errors like cant find rational_sampler …. I am also running Ubuntu with 3.7.x.x but I cannnot find the Source module in this version so cannot use RTL-SDR Source … Is this version of GNU radio only for people using USR modules ??? Thanks for any help
@Graham, I can’t tell for sure if this example was made with 3.6.x.x but now I have 3.7 and there is no problem with rational resampler or rtl-sdr source. However rtl-sdr is provided as additional package so you probably didn’t installed it. I explained any prerequisites in my other tutorial here.
Excelente tutorial. Estoy manejando y experimentando con un dongle RTL2832-820T que cayó en mis manos. Realicé todos los pasos, pero me da 2 errores que son 4. El primer error es que la variable freq esta repetida. (2 errores, pues donde se repite es otro error). El segundo error dice que la variable volume esta repetida. (2 errores, pues donde se repite es otro error). Te agradecería si me dieras una mano para corregirlos. Mis felicitaciones por tan buen desempeño con el tutorial. Gracias.
I’m trying to duplicate this and I can’t get it to allow me to compile/run the project.
I’m completely new to GRC. I notice that in my app some of the outputs are orange color, and some are blue. Is there a mismatch?
As far as I know, colors means type of input/output, so yes, it is a mismatch. To connect two blocks, they must be same color. You can change type with up/down arrows.
Please,who can help me with the codes in Phython of each block of the receiver: RTL-SDR Source; FM deemphasis; frequency xlating FIR Filter; WBFM Receive; Low Pass filter; multiply const; audio sink; wx gui waterfall sink; wx gui fft sink.
Thanks for posting this! It’s really great to find a simple example to verify that my setup is working.
For my RTL-SDR v3 on Windows, I added the device arguments “rtl=0” to the RTL-SDR Source block.
“Next Rational Resampler and Multiply Const
…At first we need to convert rate from 500k to 48k so we need to decimate by 500 and then multiply by 48.”
Decimation 500 and interpolation 48. But why is in the FINISHED FM SCHEMATIC, the decimation factor is 50 instead of 500? I tried this setup and it works better when my dec. factor is 50 instead of 500. Can someone clarify please? Thanks
Oh, I missed something from the preceding block, WBFM Receive. It already decimated the 500 kHz by 10 so the new sample rate is 50 kHz which is also the incoming sample rate to the second rational resampler block. It now makes sense, thanks nonetheless! 😀
I am a newbie to both GnuRadio and RTL SDR. Pardon me if I ask stupid questions. I tried to replicate the GnuRadio Flow Graph given in this excellent blog. I don’t get the compile button due to the error situations listed below.
1. Variable ID:freq being identical to WX GUI Text Box ID:freq. Due to which, the titles of these two boxes stay red (indicating error situation)[These are above and below RTL-SDR Source block]
2. Variable ID:volume being identical to WX GUI Slider ID:volume. Due to which, the titles of these two boxes stay red (indicating error situation)[These are above Multiply Const block]
I am using Ubuntu 18.04.
I figured out how to disable those two blocks and get rid of the problem. I am trying to receive 100.1 MHz FM channel in my laptop. I run the program but I seem to receive some junk.