RTLSDR Scanner

Screenshot 1

Last year while developing Linux drivers for digital TV, Antti Palosaar noticed a hidden debug mode, which allowed you to sample relatively large chunks of radio spectrum.  Thanks to this the RTL-SDR library was born and Software Defined Radio was available on the cheap, after all these dongles tend to cost less than £20.

A little while ago I uploaded my contribution to this, a GUI called RTLSDR Scanner, to GitHub.

The software scans a range of frequencies and plots the result, allowing you to find signals to investigate.  The RTL dongle has a maximum bandwith of about 2.8MHz but with this you can scan the full range of the dongle, allowing you to see signals with ease.  For example the screen capture shows my local FM radio stations.

Once you've installed the RTL-SDR library the dependencies are a little more involved.  On Ubuntu 12 installing them is straight forward using the Software Centre, Windows is trickier and although I've had reports of it working on OSX I haven't had the chance to try it.

Each of these dongles is based around the  RTL-SDR library chipset which interfaces the computer via USB to a tuner chip.  Several tuners are available, I've tried a FC0012 and E4000, the latter was recommened but is now hard to find so the Rafael Micro R820T is the one to look for.  Details of compatible dongles are listed on this page.

Comments

Hi, rtlsdr-scanner looks like great software and I've been following your progress for a while. Unfortunately, most likely due to ignorance on my end, I can't get it to run. Does the error message shown in http://pastebin.com/GH9sEpN7 suggests any fixable problem to you? The software GUI pops up fine. But as soon as I start the scan that error appears and the GUI stops accepting input. This is on Ubuntu 10.04.

Al's picture

Hi, from the error it looks like it can't find your dongle. From a terminal prompt try running:
$~ rtl_test
With my E4000 device I get:

Found 1 device(s):
0: ezcap USB 2.0 DVB-T/DAB/FM dongle

Using device 0: ezcap USB 2.0 DVB-T/DAB/FM dongle
Found Elonics E4000 tuner
Supported gain values (14): -1.0 1.5 4.0 6.5 9.0 11.5 14.0 16.5 19.0 21.5 24.0 29.0 34.0 42.0
Reading samples in async mode...

If you get a 'No supported devices found' this page is a good start for installing the library (look under 'Building the software')

Hopefully the next commit will have better error checking.

Al

In between attempts to get RTLSDR Scanner working I was able to use other rtlsdr programs, including a couple that also use the pyrtlsdr wrapper. I'll keep messing around with the latest from git (I see you added the error handling for no dongle) to see if I can narrow it down.

Al's picture

Any chance you could run this Python script and post the results?

import rtlsdr

count = rtlsdr.librtlsdr.rtlsdr_get_device_count();
print count

for dev in range(0, count):
print dev, ": ", rtlsdr.librtlsdr.rtlsdr_get_device_name(dev)

Thanks, in the meantime I'll keep hunting.

1
0 : ezcap USB 2.0 DVB-T/DAB/FM dongle

Thanks. A pull of the latest revision, with the env stuff, works in the sense of the dongle being initialized and samples read and that's good enough to begin playing with. The plot isn't actually plotted visually; something related to the formating of the x,y pairs for matplotlib. I suspect is due to Ubuntu 10.04 having old python and packages. http://pastebin.com/MBb1NB1L .

It's a python 2.6 thing. I fixed it by setting the format stuff explicitly like in line 1016,

axes.set_title("Frequency Scan\n{0} - {1} MHz".format(self.settings.start,
# axes.set_title("Frequency Scan\n{} - {} MHz".format(self.settings.start,
self.settings.stop))

and line 550,

text = "f = {0:.3f}MHz, p = {1:.2f}dB".format(xpos, ypos)
# text = "f = {:.3f}MHz, p = {:.2f}dB".format(xpos, ypos)

I don't understand how I'd do this via github so, "diff -u rtlsdr_scan_old.py rtlsdr_scan.py > python26.patch", http://pastebin.com/rC2YN2n5 .

Al's picture

Don't worry it's not spam, its very useful.
Thanks for the patch, I've just committed it.

Al

I'm completely ignorant of Python, but I downloaded the dependencies and installed them after installing Python 2.7 (for wxPython) and 3.3 (for all the others). If I run your script, a command Window opens and closes fast, but seems to be complaining about modules. I am using Win7 x64, and have one of the Newsky DVB dongles which works well with SDR# for example.

Al's picture

I recommend you try running it in a command window (Start->Programs->Accessories->Command Prompt), you'll be able to see the errors then. I'm a bit concerned that you're using two different Python versions, I'd stick with just 2.7, having 2 versions could cause all sorts or problems.

OK, thanks, I re-did everything I could find in 2.7. After adding Python27 to the PATH env var, I was also able to run the rtlsdr_scan.py script in a command window. Found a few missing dependencies, but then ran into this:

File "C:\RTLSDR-Scanner-master\src\rtlsdr_scan.py", line 39, in
import rtlsdr
ImportError: No module named rtlsdr

I had already downloaded the pre-built libraries for Windows, but this error message seems to indicate that I should have installed a Python module as I did with numpy or matplotlib, but I don't know Python like I know C, C++ and C#. Am I missing something or is this more of a configuration error?

Russ

Al's picture

Hi Russ,
Did you download and install pyrtlsdr? After downloading you'll need to run python setup.py install from what I remember.

I'll post a tutorial soon(ish) as installation is a bit tricky for Windows users.

Al

I made some more progress. Attempting to run setup.py, I discovered I needed setuptools and then distribute. Then I discovered I needed a PATH to C:\Python27\Lib\site-packages\rtlsdr-dev-py2.7.egg\rtlsdr\ so librtlsdr.py could be found. After this step, I still received this:

C:\RTLSDR-Scanner-master\src>python rtlsdr_scan.py
Traceback (most recent call last):
File "rtlsdr_scan.py", line 39, in
import rtlsdr
File "c:\Python27\lib\site-packages\rtlsdr-dev-py2.7.egg\rtlsdr\__init__.py",
line 18, in
from librtlsdr import librtlsdr
File "c:\Python27\lib\site-packages\rtlsdr-dev-py2.7.egg\rtlsdr\librtlsdr.py",
line 41, in
librtlsdr = load_librtlsdr()
File "c:\Python27\lib\site-packages\rtlsdr-dev-py2.7.egg\rtlsdr\librtlsdr.py",
line 36, in load_librtlsdr
raise ImportError('Error loading librtlsdr. Make sure librtlsdr '\
ImportError: Error loading librtlsdr. Make sure librtlsdr (and all of its depend
encies) are in your path

Al's picture

Is the RTLSDR library in your path (it should point to the location of rtlsdr.dll)?

Man, that rocks!

Obviously your last point worked. Thanks and nice work.

Al's picture

Glad to hear that matey, enjoy!

Super software, congratulation!It works perfectly!
One question: I want to compare two graphs (for example, to verify ratio front-rear antenna) and It would be more comfortable with fixed y-axis values...How can it do this?

Al's picture

Hello, glad you like the software, currently you can't set the scale but I'll look into adding this feature.

Al's picture

I've updated the code at GitHub which allows you to set the Y limits. There is a new button on the toolbar for this.

it's fantastic! many thanks!

Hi, first let me thank you for this very nice piece of software.
I'd like to ask two question regarding ThreadProcess run part, specifically the following code (lines 278-282):

for pwr, freq in itertools.izip(freqs, powers):
xr = pwr + (self.freq / 1e6)
xr = xr + (xr * self.cal / 1e6)
xr = int((xr * 5e4) + 0.5) / 5e4
scan[xr] = freq

1) Maybe I'am missing something, but it seems to me that in this part of code meaning of pwr and freq is swapped. If so, wouldn't it be more clean to have it named the following way?

for freq, pwr in itertools.izip(freqs, powers):
xr = freq + (self.freq / 1e6)
xr = xr + (xr * self.cal / 1e6)
xr = int((xr * 5e4) + 0.5) / 5e4
scan[xr] = pwr

2) I interpret line "xr = int((xr * 5e4) + 0.5) / 5e4" in such way, that it rounds frequency to nearest multiple of 20 Hz. Is there any reason behind this particular value (i.e. 20Hz)?

Thank you. Brux

Al's picture

Hi Brux,
1) This was a mistake I forgot to correct, I've sorted it out and committed it - Thanks for the reminder!

2) A Spectral Density function does not return frequencies in defined 'bins' as an Fast Fourier Transform would, this line simply aligns the frequency into steps before they are averaged (lines 1233-1242). I chose 20Hz as it seemed a good trade-off between accuracy and the amount of 'hits' the averaging function would get (line 1240).

Hope that's helpful,
Al

Many thanks for the software, superb visualisation of spectrum using inexpensive hardware.

My radio use is virtually zero due to local noise sources, I'd love to be able to use something like this to take timed scans, save them and later produce a baseline comparative noise plot for identifying times of peak interference and extent.
I see what I think is the same source extending across a wide swath if I could identify it coming on and going off it would be easier to know if I'm dealing with one or more devices with a similar signature (PLT). This is not a request just a "wouldn't it be great if"
Timed plots
Saved to website
Running plot with baseline comparison or "compared to" - some time scale
Could also be used to watch the affects of solar flares or greyline propagation.

Another thing that I wondered about is more parameters saved in the output to show device, frequency ppm, gain, dwell, offset etc. This might allow others to recreate a similar plot in their location.

Thanks again.
Stu

Al's picture

Hi Stu, thanks for the thumbs up.

The program supports command line arguments so you could run it from a scheduler (in Windows use 'Task Scheduler' and in Linux use 'cron').

For example to scan from 100 to 102MHz to a file named 'test' run the command:

rtlsdr_scan.py --start 100 --end 102 test.rfs

For a full list of options run:

rtlsdr_scan.py -h

I've added your ideas to the list of (possible) upcoming features, although it's getting pretty big so don't hold your breath!

Many thanks for that sorry I should have though to try -h, was too distracted trying to identify a huge noise spike from my neighbour's house.
Compare plots put me on to that within minutes, never would have found that without trawling through chunks of what should be dead RF spectrum.

I will cron some jobs through the night, might even get back into radio if I can break down the local bad stuff.

I always feel a bit guilty making software comments as I know a few simple words could actually represent a number of long days work. It's useful right now so no complaints from me if requests don't justify the time involved.

Al's picture

When I get time I'll document the command line interface properly as it is a bit hidden.

Don't worry about making comments, it's good to get some feedback and ideas. More than a few features and bug fixes have made their way into to code this way.

Hello Al. Happy New Year!

I am using Linux Mint 15 (Olivia), an Ubuntu fork, with a Realtek RTL2832U-based dongle and when I try to run the scanner program by typing:
./rtlsdr_scan.py --start 100 --end 102 test.rfs (From your example above)
I first get a warning:
***************************************************************************************************
/usr/lib/pymodules/python2.7/matplotlib/__init__.py:1035: UserWarning: This call to matplotlib.use() has no effect
because the the backend has already been chosen;
matplotlib.use() must be called *before* pylab, matplotlib.pyplot,
or matplotlib.backends is imported for the first time.
***************************************************************************************************

And then this output:
***************************************************************************************************
warnings.warn(_use_error_msg)
RTLSDR Scanner

Detached kernel driver
Found Elonics E4000 tuner
Traceback (most recent call last):
File "./rtlsdr_scan.py", line 89, in <module>
frame = FrameMain("RTLSDR Scanner", pool)
File "/home/mike/RTLSDR-Scanner-master/src/main_window.py", line 135, in __init__
self.devices = get_devices(self.settings.devices)
File "/home/mike/RTLSDR-Scanner-master/src/devices.py", line 71, in get_devices
device.gains = sdr.valid_gains_db
AttributeError: 'RtlSdr' object has no attribute 'valid_gains_db'
Reattached kernel driver
***************************************************************************************************

Any idea what I am missing or doing wrong?

Any info is greatly appreciated!
Mike

Al's picture

Hi Mike, Happy New Year to you too!

Firstly don't worry about the warning, it won't cause any problems.  It's because Mint and Ubuntu use an outdated version of matplotlib.

The 'AttributeError' you are seeing is due the pyrtlsdr library being outdated.  If you still have the download directory from originally installing it you can open a terminal, change to the directory and run:

git pull
sudo setup.py install

Otherwise follow the instructions here.

 

First of all - thank you!
I was surprised how easy was installing it under Windows XP - great job, unexpected as well as precious contribution!

Thanks again.

73,
IZ5RNZ - Andrea

Al's picture

Hey great software by the way, on sourceforge in the category features it says "Graphical user and command line interfaces". I haven´t figured out how to use it in terminal... is that really possible?

It would make things much easier automating the monitoring of my telemetry transmitters.

thanks for any information.

Marcus

Al's picture

Hi Marcus,

When I get time I will add some better instructions to the software as a PDF.

In the meantime you can get basic command line help by running:

python rtlsdr_scan.py -h

You can omit the python if Python is in your path.

For example, a scan from 80 to 90MHz with a gain of 8.7 to the file 'scan.rfs', use the following:

rtlsdr_scan.py -s 80 -e 90 -g 8.7 scan.rfs

Thanks a lot! I'll try that that tonight.

If you encounter an error after install:

run: rtlsdr_scan_diag.py

if it says librtlsdr not found in path:
Copy rtlsdr.dll to c://pyhton2.7

If rtlsdr gives you a very short command window that closes and doesn't start, then probably module six isn't installed.
Download six-1.5.2.tar.gz from https://pypi.python.org/pypi/six
Unzip for example in the pythondirectory.
Open a command prompt
goto the directory where you extracted six.
run: python setup.py install
try running rtlsdr. If all went well it works.

Al's picture

Hello,

Thanks for the tip, looks like six is a dependency for newer versions.

Click to add a comment