How I implemented FM channel scanner on RTL's Software defined radio module

in python •  7 years ago 

This is a story from long time ago when I had to implement a FM channel scanner on RTL's USB module interfaced to a BeagleBone black.
The software defined module that I had was this:

image source: adafruit

The task at hand was to determine all the FM frequencies at which the local FM stations broadcasted their signal.

The rtl_fm program

First thing to do was to grab the source for driving the RTL SDR module and compile it. You can find instructions here to compile and install a suite of applications that allow you to control the rtl_sdr module. The program that I was interested in was 'rtl_fm'. The following command entered on command line (Bash on Linux and cmd on windows) would play radio station broadcasting at the frequency 91.1 MHz (assuming that you have already installed aplay on your system)

rtl_fm -f 91.1e6 -s 200000 -r 48000 – | aplay -r 48k -f S16_LE

Let's have a look at the options supplied to 'rtl_fm' and what the they represent.

  • -f This option tells the rtl_fm program to tune SDR to the frequency given next, in our case is is 91.1 Mega (10^6) Hz
  • -s The sampling frequency to be used to acquire the audio data
  • -r The output sampling rate

So what is sampling rate you ask? It is method by which the signals are input to a digital system. Sampling rate basically defines here how many samples of the audio signals are to be measured and recorded in a second.
The output of 'rtl_fm' is directed to 'aplay' using the pipe (|) operator.

rtl_fm outputs the audio data in 16-bit little Endian PCM format. This information is conveyed to 'aplay' with the option 'S16_LE' and using option '-r' causes 'aplay' to play the audio with sampling rate of 48KHz .

For the purpose of analysis, I saved the data output by 'rtl_fm' to a file using named pipe.

rtl_fm -f 91.1e6 -s 200000 -r 48000 > audio.raw

Now that I have raw audio data in the file “audio.raw” it is time to read the contents of this file and make sense out of it. This file is going to be a binary file and also from the option given to “aplay” (taken from the “rtl_fm” help page) in the command line, we can infer that the format used for the data in the audio output is signed 16 bit little endian (S16_LE). Following python code block would read 256 short ints (or signed 16 bit numbers) from the file.

i = 0
dataSet = []
while i != 256:
    dat = f.read(2)
    (temp, )= struct.unpack('h', dat)
    dataSet.append(temp)
i = i+1

Next, the audio signal has to be analyzed in frequency domain. This let's us know the key characteristics of any signal. This can be done by applying Fourier transform. Fourier transform breaks the signal into the frequency components that make up the signal. Using matplotlib and scipy python libraries I was able to plot the frequency spectrum of the signal:

What this basically tells us is that, at what frequencies the signal is strong and at what frequencies it is weak.
For comparison, now we will have a look at the audio data as output by rtl_fm for a channel that does not exist. If you listened to audio the only thing that you would hear is radio static noise.

As you can see, the spectrum is all over the place. This is because, noise being random, does not have frequency content belonging to one particular frequency group as opposed to a audio signal where the signal has to be in audible range.
This we are going to use to our advantage. First of, we need to filter all the low frequency component so that we do not let these components interfere with our further analysis. For this, we use well, a filter. We will be using Butterwort filter which is a type of IIR filter, meaning that this is a feedback based filter. You can use signal.butter() to design a butter worth filter from the scipy package. The output of this function will be a bunch of co-efficients that you can use in a difference function or can be passed to “signal.lfilter()” (linear filter) for filtering.

Spectrum of the filtered audio:

Spectrum of the filtered audio

Spectrum of the filtered noise:

Spectrum of the filtered noise

If you compare the spectrum of filtered audio and noise files, the noise file has more variance than the audio file spectrum. Now it is easy to see that by averaging out these values, we should be able to say noise from audio (well, most of the time :)).

If anybody is interested in the complete source for this program, please let me know in comments section.

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

Congratulations @navinb! You have completed some achievement on Steemit and have been rewarded with new badge(s) :

You published your First Post

Click on any badge to view your own Board of Honor on SteemitBoard.
For more information about SteemitBoard, click here

If you no longer want to receive notifications, reply to this comment with the word STOP

By upvoting this notification, you can help all Steemit users. Learn how here!

Congratulations @navinb! You have completed some achievement on Steemit and have been rewarded with new badge(s) :

You made your First Vote

Click on any badge to view your own Board of Honor on SteemitBoard.
For more information about SteemitBoard, click here

If you no longer want to receive notifications, reply to this comment with the word STOP

By upvoting this notification, you can help all Steemit users. Learn how here!