RTLSDR Scanner



Manual (EN) (FR)

Frequently Asked Questions

Screenshot 1

Screenshot 2

Screenshot 3

Screenshot 4

Screenshot 5

Screenshot 6

A cross platform Python frequency scanning GUI for USB TV dongles, using the OsmoSDR rtl-sdr library.

In other words a cheap, simple Spectrum Analyser.

The scanner attempts to overcome the tuner's frequency response by averaging scans from both the positive and negative frequency offsets of the baseband data.

Tested on:

  • Windows 7 (x86 and x64)
  • Ubuntu 12.04 (x86), 12.10 (x64), 13.04 (x64) and 14.04 (x64)
  • OS X Snow Leopard (10.6) and Mountain Lion (10.8)


Download the installer or stand-alone Windows executables from GitHub.

Download the latest source from GitHub.


Installation instructions are here.

The following dependencies are needed:

Linux and Mac users will need to manually install these,  Windows users can use the installer.


A basic manual is available in Portable Document Format.

Quick start

Run 'python -m rtlsdr_scanner'.

To start a scan simple enter the range at the bottom of the window and click 'Start', after a while a plot of signal strengths should be displayed.

'Dwell' controls how long each step is sampled for, longer times will result in more averaging of the signal.

'Continuous update' updates the display on each step. Caution only use this with small scans and low dwell times, otherwise it will become unresponsive.

'Grid' displays a grid on the scan plot.

Auto Calibration

Scans around the frequency specified for the strongest signal and then calculates the error correction of the dongle.

To get the best out of it you really need a continuous signal peak that stands out from the background noise.  If you live near an airport RADAR signals are great for this. Mobile phone signals also work well but you need to know the channel frequencies, making it tricky.  I have had some luck with commercial FM radio but you'll have to set the dwell time to the highest setting to get a usable offset.

Main Window

  • Start - Scan start frequency
  • Stop - Scan stop frequency
  • Mode - Sing or continuous scanning
  • Dwell - Sampling time spent on each step
  • FFT Size - FFT size, greater values result in higher analysis precision (with higher sizes dwell should be increased)
  • Live update - Update the display on each step (caution this can be slow and unpredictable)
  • Grid - Show a grid on the scan
  • Display - Change the plot type

File Menu

  • Open... - Open a saved scan
  • Save As... - Save a scan
  • Export... - Export a scan to a CSV file
  • Properties ... - Scan information

Edit Menu

  • Preferences - Set dongle gain, calibration, Local Oscillator (positive offset for upconverters) and sample bands (see below)

Scan Menu

  • Start - Start a scan
  • Stop - Stop the scan
  • Stop at end - Stop the scan when the current sweep is finished (only in continuous mode)

Tools Menu

  • Compare - Compare two previously saved scans
  • Auto Calibration - Perform a crude calibration of the dongle to a known signal (this should be a continuous, unwavering signal)


Dongles will differ depending on the tuner and circuit that's used, the software allows you to pick the best range that is sampled to give improved results.

Click on View -> Preferences and select the 'Band Offset' for you tuner, next detach the aerial or even better terminate it with a 50 ohm load.  Now click refresh to show the noise floor of the tuner, adjust the offset so the marked bands overlay the flattest areas of the plot and click OK.

I find the following offsets work well (click the offsets for images):

Tuner Offset (kHz)
Elonics E4000 250
Fitipower FC0012 140
Rafael Micro R820T 100

Note the large peak in the middle, this is at 0Hz (i.e. its the DC offset).  On the R820T it is much narrower, this is because it uses an intermediate frequency away from the low frequencies.  In this case the resulting spike is due to the sample length not being infinitely long (imagine taking a complete cycle of a sine wave then chopping the end off, this leaves it unbalanced and its average value is no longer 0, in other words it looks like it has a DC offset), the sample is windowed to reduce this but it's a trade-off between accuracy and frequency response.


Run 'rtlsdr_scan_diag.py', this tests if the correct modules are installed.




Click to view comments

Hi, I've had big success with your software. Bought a gps and it works perfectly!
I haven't found anyone else that has posted a picture with a working heat map, feel free to use it if you are unable to make one yourself. Thank you for spending the time developing this awesome free software. I've sent a small donation your way

Al's picture

Hi Tobby,

Thanks for posting this, it's interesting to see how this works in the field as I a unable to test it myself.

From your test and others that I've been sent it seems to do the job. I've added some features recently which should make scanning easier; the 'Start' and 'Stop buttons can now be changed to 'Continue' and 'Stop at end' which means you can move to a location make a few sweeps at that point then continue the scan at another location. The more locations you survey will increase the accuracy.

The mapping can't distinguish 'real' signals from reflected paths so I would expect you'd get better results in less built up areas and with higher frequencies where line of sight propagation is dominant. A few users have mapped mobile phone transmitters in their area and it does seem they get better results with the 4G 1.7 - 2.1GHz bands than the GSM bands on 800MHz or thereabouts.

Finally thank you for the donation, they all add up and allow me to spend time on FOSS projects which I really enjoy.


Thanks for this cool tool.
I seem to have a problem, when I run "python rtlsdr_scan" I get an error I cannot solve.

ImportError: No module named tools.list_ports

Can you shed some light on this problem?
I ran "python rtlsdr_scan_diag.py" and it says:
"No problems found"


Typos problems:
"ImportError: No module named tool.list_ports" should be "ImportError: No module named serial.tools.list_ports"


Al's picture

Hi Freddie,

Can you go to 'Help->System Information' and post the output? Usually this error is due to an out dated version of pySerial.


I'm afraid I don't understand this statement:
"go to 'Help->System Information'
This Does not exist on the system I'm working on.
This system is a CubieTruck ARMHFV7i running Ubuntu 12.04 LTS. The window manager is LXDE.
Python version is 2.7.3
I did a locate pySerial and it comes up with nothing.
Have I do something wrong? Do I need to install something else?

Al's picture


The 'System Information' item is available in the scanners 'Help' menu.

It's possible that PySerial is not installed or an older version, in which case run the following in a terminal:
sudo apt-get install python-serial

Hope that helps.

I found the problem.
It appears that pip installed to /usr/local/lib/python2.7/site-packages, however the PYTHONPATH was pointing to /usr/lib/python2.7/site-packages. The /usr/lib/python2.7/site-packages version of serial doesn't have the all the pieces of pySerial so I got this error.
I fixed it by removing the PYTHONPATH from my .bashrc file and it works just like it should.
Kinda weird huh?

Al's picture

Strange, my guess is that somewhere an installation has added that. Full points for finding it!

Is there a way to show multiple peaks. When I scan a range it only shows the highest one. Would be awesome if you could set a threshold in dB and show X's with the specific frequency on anything above that level.

Please let me know if I am missing something. I have to mouseover on all but highest to see what freq. And that isn't very accurate as the default mouse pointer is a fat finger :)


Al's picture

Hi Larry,

I'm looking into a way to mark multiple peaks, I'm currently experimenting with a few methods of achieving this and will hopefully have a solution soon.

As for the fat finger, the scanner starts up in mouse panning mode, if you click the 'Pan' button (the 4 joined arrows on the toolbar) it will revert to a pointer.

i keep getting

(python:9007): GLib-CRITICAL **: g_hash_table_insert_internal: assertion 'hash_table != NULL' failed
Traceback (most recent call last):
File "./rtlsdr_scan.py", line 119, in
frame = FrameMain(APP_NAME, pool)
File "/home/gareth/src/RTLSDR-Scanner/src/main_window.py", line 169, in __init__
File "/home/gareth/src/RTLSDR-Scanner/src/main_window.py", line 195, in __create_widgets
self.graph = PanelGraph(self, self, self.settings, self.status, self.remoteControl)
File "/home/gareth/src/RTLSDR-Scanner/src/panels.py", line 110, in __init__
File "/home/gareth/src/RTLSDR-Scanner/src/panels.py", line 263, in create_plot
File "/home/gareth/src/RTLSDR-Scanner/src/toolbars.py", line 502, in set_type
File "/home/gareth/src/RTLSDR-Scanner/src/toolbars.py", line 402, in __set_func
self.ToggleTool(buttons[self.settings.plotFunc - 1], True)
File "/usr/lib/python2.7/dist-packages/wx-2.8-gtk2-unicode/wx/_controls.py", line 3875, in ToggleTool
return _controls_.ToolBarBase_ToggleTool(*args, **kwargs)
TypeError: in method 'ToolBarBase_ToggleTool', expected argument 2 of type 'int'

Al's picture

Hi, this should be fixed in the latest version.


Can you check if the remote option is working correctly? I run rtl_tcp on my Mac and run rtlsdr_scan.py with -r but i get a usb_claim_interface error -3.

Al's picture


Are you seeing the error from rtl_tcp or from the scanner?

I am unable to get rtlsdr_scan.py to run after install. This is a first time install There are no errors from rtlsdr_scan.py. The OS is Windows 7 Professional. The rtlsdr_scan.py command window shows something like the following. Suggestions?

Traceback (most recent call last):
File "C:\Program Files (x86)\RTLSDR Scanner\rtlsdr_scan.py", line 54, in
from cli import Cli
File "C:\Program Files (x86)\RTLSDR Scanner\cli.py", line 36, in
from file import save_plot, export_plot, ScanInfo, File
File "C:\Program Files (x86)\RTLSDR Scanner\file.py", line 37, in
from PIL, import Image
ImportError: No module named PIL

That should have said "...There are no errors from rtlsdr_scan_diag.py..." Sorry, brain got ahead of fingers.

Looks like the Windows installation for rtlsdr-scan failed to install PIL. I installed PIL manually and rtlsdr-scan.py starts up now. Perhaps a check for PIL needs to be added to rtlsdr_scan_diag.py?

I'm looking forward to learning more about your rtlsdr scanner package. Thank you for creating it.

Al's picture

Thanks, I've added check to rtlsdr_scan_diag.py but I'm still trying to work out why PIL wasn't installed in the first place.

There is a new RTLSDR.dll file that can allow an R820T USB tuner to go down as low as 4 or 5 MHz. Performance may not be as good as a real expensive wideband SDR that low, but it does receive lower frequencies. This works great in SDRSharp but if I put this DLL in the directory with this program, it does not enable low band scanning. I am trying to check the noise floor on CATV return path which is normally 5-42 MHz and without this modified open source DLL, I can only use this application to check 24 MHz and up.

Is there any way to build this application with support for the lower frequencies? Here is the original article I followed to get the new DLL that enables the direct sampling modes for pre 24 MHz tuning in this dongle: http://www.rtl-sdr.com/direct-sampling-mode-hardware-modifcations/

Thank you for your help!

Al's picture

Thanks for the info, I tried the new DLL with the stock antenna which was very good at picking up my PC but otherwise I didn't have any problems.
As for your problem I wonder if the pyrtlsdr library is looking at a different DLL, I've updated rtlsdr_scan_diag.py to show the location of the driver that's being loaded as it may not be the one in the installation directory.

Hi Al,

Firstly, huge thanks for writing an amazing program - much more intuitive and useful than SDR# as a wideband scanner. My question relates to the calculation of received power. I have been searching for a way to convert this figure to dBm so I can refer data collected in RTLSDR Scanner to another scanner that collects data in dBm. I guess I am showing my lack of technical understanding - but I have been searching for days on the internet and can't find any information - could you possibly point me in the right direction? Also wondering if you would consider re-writing some parts of the program for a commercial arrangement?

Al's picture

Thanks Fraser glad you find the software useful, in fact I'm surprised at how many people do!

The reason I use dB/√Hz is really to reinforce the fact that this software uses Power Spectral Density analysis to transform the received bandwidth from the time domain (i.e. amplitude vs. time) to the frequency domain (amplitude vs. frequency), as many programs use a standard FFT instead.  PSD has a few advantages especially when it comes to stitching frequency ranges together.

The square root can be ignored as the analysis is scaled to 1Hz, basically meaning that the value is the power of a particular frequency per unit frequency.

On top of this the dBm unit is the ratio of power referenced to 1mW (decibels are just a ratio, not a unit) and the gain of dongles is not created equal (even sometimes between identical dongles).
Because of this I decided to use ratios (the decibel) rather than an absolute unit (dBm) because of the variation in tuners.

To sum-up: treat dB/√Hz as just decibels (e.g. a signal which is 6dB lower than another is about half the power); don't worry about it as an absolute value.

Even it is very long to install and requires also to install PYTHON, this nice software is very useful and does a lot of functions that they are missing to SDR# :
- A large frequency spectrum is displayed
- The mean envelope curve of the spectrum is continuously updated

Like SDR# it is able to work with an upconverter displaying the true tested frequency.
For the hobbyist it opens the door of the frequency spectrum analysis.

Al's picture

Glad you like it and find it useful, my hope was that hobbyists (like myself) would benefit from a cheap spectrum analyser.

Python does has it's disadvantages and originally I was thinking about using C++ (for speed) but I chose it because:
- I wanted to learn Python
- I didn't envisage that it would be anything more than a simple script
- The matplotlib library greatly simplifies plotting, looks great but only supports Python
- It runs on multiple platforms

In retrospect not the best of reasons but porting it to another language would be a major undertaking.

I have built a little homebrew noise source to experiment some stuff with an USB dongle and a 125MHz upconverter and with RTL SDR Scanner :
- A video amp salvaged from the trash from 0 to 30MHz : strange no flat BW with several peaks
- An old MFJ all SW bands preamp antenna from 0 to 30MHz : the gain curve is clearly visible, but the frequency dial of the MFJ is not reliable
- The upconverter itself from 0 to 100Mhz : the BW is as expected from 0.5 to 65MHz
- An experimental pass-band filter 2X L=1uH C=270pF coupled with a 10pF : we can see the two peaks like camel bumps
- ...
It is tricky to tune it with the LC circuits, but you can do it with some patience, playing with the gain and attenuation, and having some care in order not to damp the LC circuit

I don't understand all the commands and what sometime it bugs, but I'm really impressed by the offered possibility of this program !

Al's picture

Thanks a lot! I'm glad you find it useful.

You're experiment sounds interesting, I really should build a wideband noise source and document some results with various filters and oscillators.

When you find bugs you can post a quick description of them in these comments and I'll try and fix them.

Hi Al,

Find here my modest and noisy experiments under the nick name ALZ, sorry it's in French :

Half of the parts come from recycle i.e. : transistors, shield, epoxy breadboard, battery connector ...
The first transistor in reverse biasing acts as a Zener diode, this is actually the noise source, you may try some NPN transistors to find a noisy one, better with an oscilloscope you can see the starting voltage of noise (Zener bend), the reverse voltage should be about 9V ...

The noise is detected from few KHz to 1GHz upper limit of my USB dongle, sure it's not very flat or calibrated like a professional one but it's not too bad for a one pound source.

I hope it can help someone.


Sorry I forgot about the bugs, I don't know, maybe is my Windows 7 PC :
- When you clear the screen you can restart the program but it display anything on the screen.
- Sometimes after several sweeps the program freezes.

I don't understand what OBW means and what it does when you click on it?

Al's picture

I'll look into both problems, I'm aware of the freezing issues but have had no luck so far with it.

OBW is an acronym for 'Occupied Bandwidth', it's a measure of the frequency range that contains 99% of the total power.
Select part of the spectrum by dragging the middle mouse button and tick OBW, you may have to alter the range to get a sensible result.

I like your approach to the noise source, especially the reverse biased base-emitter - my junk boxes are always my first port of call when building anything.

I now have a HackRF and I was wondering if the Scanner will work with HackRf? It is part of the osmocom library, but RTLSDR Scanner does not seem to find it.

Al's picture

I've had quite a few requests for the HackRF and AirSpy support but I simply can't afford to buy either of them, I have had some kind offers of loan devices but I'm not keen on adding support for a device that I won't always have access to.

My software uses the specific Osmocom RTLSDR driver (via the pyrtlsdr driver) which doesn't support the HackRF. I think the library you mention is gr-osomosdr which works with GNU Radio, I chose not to use this as it would make my project dependent on GNU Radio, which in turn can be difficult to set up.

I am a college student that is trying to have a program to connect to a synthetic aperture radar system like the system done by MIT but slightly modified by using a dongle instead of recording a wave file. (see http://ocw.mit.edu/resources/res-ll-003-build-a-small-radar-system-capab... for details on the project) I have been combing through the code for weeks and I haven't been able to find a way to add something to your program.

Here's what I want to do: I just want to add an option to the display drop down menu that can calculate ranging and SAR that I will code. The scanner would also have to focus on audio frequencies because of the nature of the device.

If you could just give me some pointers on where I could begin that would be great! And just so you know this is only for educational purposes and will not be mass distributed or sold. Please let me know if you are interested in helping.

I'm also fairly new to programming and only know the basics of a few languages. I have resources for help, but because I am somewhat unfamiliar with python I have found this as a difficult challenge. Any tips are greatly appreciated!

Al's picture


Thanks for the interest, but I think modifying my software to do this will be an uphill struggle. The main reason is that my program is based around spectrum analysis of a radio frequency signal whereas the SAR approach is in the audio range. Furthermore to produce an image the software needs to know where the RADAR module is located to produce the output.

If you don't have access to MATLAB you maybe able to use GNU Octave. I used matplotlib in my software to perform calculations but mainly to produce the graphs and I would definitely recommend it, although you will need to get to grips with Python.

As for learning Python, Google is your best bet. For matplotlib there's a good beginners guide.

Very nice software. After numerous hoops to jump through, have the scanner working on a HP Elitebook 8440p laptop running Linux Mint.

Being a ham for 35 years+ I'm sure I'll find many uses for the R820 rtlsdr dongle and this great scaninf software. One needs to be very persistant when trying to get the rtlsdr dongle working with various software! However the payback is very good with a $15.00 dongle and the developers fine software out for them. Thanks for this great piece of software and I cant wate to get into the manual.

one good use I can think of already is checking for second harmonics of Amatuer equipment!

Beholding to developers like you
Robert D. Houlihan, N9DH

Al's picture

Hi, thanks very much but a be warned; the manual is very out of date, but I hope to get it up to speed soon. For the moment I recommend you just play around with it.
If you have any difficulties please post another comment and I'll get back to you.

Hello Al,

I have used RTL SDR SCANNER with an +125MHz upconverter, and I have tested it with two different sinus generators from 0 up to 30MHz, but on the spectrum results, there is always a stray line above each wanted signal lines at exactly +250kHz.

First I suspected my generators (but both with the same symptom doesn't look possible), then the up-converter to do these parasitic lines, but using only the USB dongle (since it starts from 24MHz), the stray lines are still there.

Do you know what could cause that?
Is it due to the program, the sound card or the USB dongle?

Al's picture

Hello Antoine,

The 250kHz lines could be something to do with the way the software attempts to flatten the frequency response. If you click on 'Edit -> Radio devices' the 'Band offset' defaults to 250kHz. You can click this number to change it which may help.

It also might be due to a high input signal overloading either the upconverter or the dongle, either way I'd be interested to hear back if you have any luck with it.

Actually, I wanted to attempt to calibrate the dB/Hz spectrum scale in dBm/Hz with a sine generator, measuring the Vpp output signal on a 50 Ohms resistor load and calculating the dBm power, I found that the spectrum scale is about dBm =dBscale -28dB (with 0dB of gain to have a reference).

Playing with the generator's attenuator (with two levels -16dBm -36dBm), shows that the relative dBLog10 scale works well.

Because I don't have a HF wattmeter to compare, this measurment is not very accurate, I don't know exactly where the 0dBm could be (I suppose it depends on the dongle and the upconverter gains).

I don't know whether -36dBm overload the USB tuner dongle, I haven't found any datas about it; since the upconverter has clipping input diodes I suppose that a 0.01Vpp should not overload it too much, if I'm not wrong it can accept +1dBm before distortion.

One thing is shure is that, except the harmonics, the generator has only one main sine signal, I tested it with my Sony ICFSW7600GR radio in SSB mode, which is selective and accurate enough to hear a parasitic signal.

Thanks for your advices, I will try to play with the "offset" next time, and I'll come back with the results.

Hello Al,

I'm not completely satisfied with my last experiments :
1- I've tested the USB dongle alone (without the upconverter) at the same levels as before, and the positive result is the stray lines doesn't come from the converter.
2- Reducing the generator level makes disappear these parasitics lines.
3- Turning the generator OFF, and closing the input antenna of the dongle with a 50 ohms plug, and 0dB gain, but with 0KHz offset makes reappear the stray lines with a higher level and regularly at each 250KHz !
4- Putting 1KHz to 200KHz for the offset solve the problem and suppress these lines ...

I have also tested the dongle with SDR# and with a high level signal there is also parasitic lines like AM side bands.

I think you are right, the problem should come from an overloading of the USB tuner.

Could you explain what the offset does?
Has it an effect to the tuner bandwith?
I have read the manual, and honestly I didn't understood very well this function.


Al's picture


From your experiments it does sound like there's an issue with interference, probably from the dongle or the USB bus, these dongles are prone to it. Some people have tried shielding them or adding USB filtering to lower the noise.

The software attempts to get a flat frequency response from the dongle by taking 2 regions from the captured spectrum and averaging them.
To set this, go back to the 'Scan Offset' window, disconnect the antenna and replace it with your 50ohm load. Then click refresh and adjust the offset so the green areas cover the flattest parts of the spectrum. Typically there will be a spike in the middle the the response will roll off at the edges, 250kHz was chosen as it seems to work well with most tuners.
My FC0012 has a few spikes in this range so I find a 360KHz offset is better.

Setting the offset has no effect on bandwidth as this stays constant, it only affects which part of the spectrum is used for generating the plot.

Hope that clears things up a bit.

Hello Al,

Thanks for your comments and clarifications, and spending time about it; today I have better results and perhaps what causes my problem :
Maybe overloading the USB stick (mine has a R820T) triggers the stray spikes but for me this is not the only cause, I've noticed that adjusting the offset to 0KHz causes lines each 250KHz on the whole swept band, and precisely snapped on the grid (125.000MHz, 125.250, 125.500, 125.750 etc...).

Adjusting the offset to about 200KHz, I've tested these following functions with good results, and reduced the spikes down up to the dongle's noise floor (-48dB) :
- Increasing the time Dwell >131ms
- Increasing the FFT >4000-8000
- Increasing the PSD Overlap (different to 0, about 33%)
- Changing the window function

That makes me think it could be a kind of resonance or oscillation, not electrical but "mathematical" like a repetition in a serie, but where, in the program, in one digital component? I can't explain that, I have not enough knowledge, but maybe a pinch of random or of negative feedback in the calculations could solve that.


Al's picture

Good to hear you're results, it's the first time someone has told me of their results, thank you.

I'm a bit wary of using absolute measurements as the gain does vary with the type of tuner in the dongle and it does appear that in some there is a certain amount of AGC even at 0dB gain.

I'm really not sure of input levels as the datasheets* are not available, I'm sure the signal will be clipped way before the input diodes start conducting.
With a suitable signal generator and oscilloscope you could probe the I and Q outputs of the tuner to see when clipping appears. Otherwise use something like SDR#, turning up the input signal and watch for odd harmonics of the input, to give you a rough idea of levels.

*The maximum input level of the E4000 tuner (now obsolete) is 10dBm, but this the maximum rating before destroying the LNA, not the dynamic range.

Hi Al,
I install your software on my PC with Linux OS.it was so good and i find it very useful.
how i can use this software with N210 instead of RTLSDR?

Al's picture

Hi Ehasn,

Unfortunately not. I'd like to get my hands on some of the Ettus kit but my pockets aren't deep enough for that, hence why I got into using cheap dongles.

Hi, tried to install using the windows RTLSDR installer but it fails to install "pillow".
Found the Pillow software but I cant find any instructions on how to install it manually into windows.

Any ideas would be appreciated.

Found a windows pillow installer and RTLSDR now runs but stops on a command screen with message
DLL load failed %1 is not a valid win32 application
Error importing libraries

Any ideas would be appreciated

Al's picture

Sounds like something is broken! It might be worth running the installer again using the 'Full installation' option. Otherwise try uninstalling Python and it's libraries and starting again. Unfortunately the error message doesn't give any clues about where the problem comes from.
Which version of Windows are you using?


Click to add a comment