# GNSS-SDR operation with a Realtek RTL2832U USB dongle DVB-T receiver

## Introduction

This article describes what is probably one of the cheapest ways for experimenting with real-life signals and GNSS-SDR. This is a product from a combined effort of many people, so let us only mention (to our knowledge) the very original source, the V4L/DVB kernel developer Antti Palosaari, who discovered an undocumented operation mode for some USB DVB-T dongles based on the Realtek RTL2832U chipset, enabling them to be used as a cheap Software Defined Radio (SDR) front-end. The key feature is that the chip allows transferring raw I/Q samples to the host, which in principle is responsible for DAB/DVB+/FM demodulation. This is great news for a GNSS software receiver since it covers the targeted frequency bands.

The RTL2832U outputs 8-bit I/Q-samples with a baseband sample rate up to 3.2 MSPS, according to the specifications. However, the highest sample rate that has been tested so far without losing samples is 2.8 MSPS. The frequency range is highly dependent on the used tuner. Dongles that use Elonics E4000 offer the widest possible range (64 - 1700 MHz with a gap from approx. 1100 - 1250 MHz). When used out-of-spec, a tuning range of approx. 50 MHz - 2.2 GHz is possible (with gap). More information about device compatibility is available at the Osmocom rtl-sdr Wiki.

The GNSS Galileo E1 and GPS L1 links are centered at 1575.42 MHz, and this band is covered by the E4000 tuner IC. The GNSS-SDR software receiver can be configured to use the RTL2832U as a real-time signal source, thus providing a low-cost option (about 20 € or \$25) to build a real-time software-defined GPS L1 receiver. This article introduces the operation details and some performance measurements regarding this GNSS-SDR feature.

## OsmoSDR driver support

The GNSS-SDR support for Realtek RTL2832U dongles makes use of the OsmoSDR GNU Radio source block and driver. We implemented a new GNSS-SDR Signal Source adapter that instantiates OsmoSDR’s gr_hier_block2, which associated GNSS-SDR Signal Source name is Osmosdr_Signal_Source. The adapter’s source code is located at:

It makes use of the gr-osmosdr library, including the following header:

#include <osmosdr/source.h>


Important: The compilation of the RTL2832U support in GNSS-SDR is optional and it requires the installation of the gr-osmoSDR library. See GNSS-SDR’s README.md file for step-by-step building instructions with the optional OsmoSDR driver.

## Configuring GNSS-SDR for GPS L1 real-time operation

In order to use a compatible USB DVB-T device, it is necessary to select the Osmosdr_Signal_Source implementation in the GNSS-SDR configuration file (gnss-sdr.conf) for the SignalSource block. In addition, the following parameters should be configured:

• the baseband sampling frequency,
• the RF center frequency,
• the RF gain, and
• the AGC operation.

Hereafter can be found a working configuration for the reception of a GPS L1 C/A signal:

[GNSS-SDR]
;######### GLOBAL OPTIONS ##################
GNSS-SDR.internal_fs_sps=2000000

;######### SIGNAL_SOURCE CONFIG ############
SignalSource.implementation=Osmosdr_Signal_Source
SignalSource.item_type=gr_complex
SignalSource.sampling_frequency=2000000
SignalSource.freq=1575420000
SignalSource.gain=50
SignalSource.rf_gain=40
SignalSource.if_gain=30
SignalSource.AGC_enabled=true
SignalSource.samples=0
SignalSource.repeat=false
SignalSource.dump=false
SignalSource.dump_filename=../data/signal_source.dat
SignalSource.enable_throttle_control=false


The recommended sampling frequency is 2 MSPS. This configuration enables the real-time receiver operation with 8 satellite channels in an Intel Core 2 quad Q9400 @ 2.66 GHz with 4 GB of RAM. In addition, we obtained the best results enabling the Automatic Gain Control (AGC) of the E4000 front-end.

## RTL2832U oscillator accuracy and stability issues

It is known, as reported in Michele Bavaro’s GNSS blog, that the crystal oscillator used by the RTL2832U dongles has very low accuracy. Our experiments with two different devices (EzCap 666 and Generic P160) confirm this issue. We used a high accuracy signal generator to generate an unmodulated carrier at the GPS L1 link and we measured the carrier frequency error in the captured signal. The resulting deviations were in the order of 80 kHz for the EzCap and 14.8 kHz for the P160.

The local oscillator frequency inaccuracies cause two different effects in the GNSS receiver:

1. The baseband signal is shifted to an Intermediate Frequency (IF), equal to the VCO deviation. It can be seen as an apparent Doppler shift. If the superposed Doppler shift (real signal Doppler + the parasitic IF) is beyond the acquisition Doppler search margins, the acquisition will fail.

2. A deviation in the sample clock since the local oscillator is used also for the Analog-to-Digital Converter (ADC) sample clock reference. This issue affects the tracking Delay Locked Loop (DLL) as there is a deviation in the theoretical sample clock frequency set in the receiver configuration file and the real sample frequency. If the deviation is high enough, the tracking DLL will lose the lock.

Thanks to the GNSS-SDR flexibility, the software receiver can be configured to overcome both effects. On the one hand, the parasitic IF frequency can be canceled using the Signal Conditioner block by enabling the frequency translating FIR filter as follows:

;######### SIGNAL_CONDITIONER CONFIG ############
SignalConditioner.implementation=Signal_Conditioner

;######### INPUT_FILTER CONFIG ############
InputFilter.implementation=Freq_Xlating_Fir_Filter
InputFilter.input_item_type=gr_complex
InputFilter.output_item_type=gr_complex
InputFilter.taps_item_type=float
InputFilter.number_of_taps=5
InputFilter.number_of_bands=2
InputFilter.band1_begin=0.0
InputFilter.band1_end=0.85
InputFilter.band2_begin=0.90
InputFilter.band2_end=1.0
InputFilter.ampl1_begin=1.0
InputFilter.ampl1_end=1.0
InputFilter.ampl2_begin=0.0
InputFilter.ampl2_end=0.0
InputFilter.band1_error=1.0
InputFilter.band2_error=1.0
InputFilter.filter_type=bandpass
InputFilter.grid_density=16
InputFilter.sampling_frequency=2000000
InputFilter.IF=14821

;######### RESAMPLER CONFIG ############
Resampler.implementation=Pass_Through
Resampler.dump=false
Resampler.item_type=gr_complex


On the other hand, the sample frequency error can be measured and taken into account by setting the estimated sample clock frequency value in the internal GNSS-SDR sampling frequency parameters as follows:

GNSS-SDR.internal_fs_sps=corrected_value
InputFilter.sampling_frequency=corrected_value


## GPS active antenna

We used a ceramic patch antenna equipped with an internal Low Noise Amplifier (LNA) to reduce the overall noise figure. The picture below shows a picture of such Garmin GA27C GPS antenna exposing the ceramic patch over the LNA PCB.

In order to connect the antenna to a DVB-T dongle it is necessary some hardware hacking:

1. Assuming that the GPS antenna is equipped with an SMA M connector, it is required to build an RF cable to convert the SMA M connector to the MCX M connector in order to plug the GPS antenna into the DVB-T dongle.

2. We must feed the LNA using a Bias-T network.

## Some performance measurements and conclusions

Two different setups were assessed to receive and process GPS signals in real-time:

• In the first one, we connected the DVB dongle to an active patch antenna using a custom 20 dB amplification and filtering circuit. The gain block provides also the +5 DC voltage required to power the active antenna internal LNA. More information on this circuit can be found at Arribas’ PhD Thesis1.

The following picture shows the DVB dongle (generic P160) + LNA + Active antenna setup.

• On the other hand, we also tested the direct connection of an active GPS antenna to the DVB dongle as well, using a standard bias-T network. This setup is shown in the following picture:

In those experiments, we used a Dell XPS M1530 laptop equipped with an Intel Core 2 Duo T9300 CPU with 4 GB of RAM. The operating system was Linux Ubuntu 12.04 and the GNU Radio version was 3.6.0.

GNSS-SDR was able to acquire, track, and obtain a position fix in both front-end setups. The antenna was placed on the roof of the CTTC building and remained static during the experiments.

The following pictures show some tracking data analysis using the GNSS-SDR intermediate data extraction and dump feature:

Tracking.dump=true
Tracking.dump_filename=./tracking_ch_


As a sanity check, we did some post-processing analysis using the Matlab script based on the ones on Key Borre’s book2 and available at

The figure clearly shows the GPS C/A navigation symbols, The PLL and DLL discriminator outputs are quite noisy, tough:

Finally, the obtained KML position file can be displayed by Google Earth as shown in the following picture. The yellow line represents the position evolution for a 10 seconds time-lapse. The red arrow represents the true antenna position. In addition, we plotted also the height evolution. Considering that the Position Velocity and Time (PVT) solutions were estimated using 4 satellites and a really low sampling frequency of 1.2 MSPS, the estimated position error was in the order of 200 m.

Summarizing this preliminary experiment, we can conclude that the GNSS positioning using low cost Realtek-based DVB-T dongles is feasible, and to the best of our knowledge, this is the first time that a GNSS software receiver supports the real-time operation with RTLSDR-based devices. This milestone enables access to the full potential of GNSS services using a standard laptop and extremely low-cost hardware. Further measurements and improved support for RTLSDR devices are planned.

Update: Those experiments and the results were finally published in a paper3 presented at ION GNSS+ 2013.

Update 2: New RTL-SDR Blog V3 dongles ship a < 1 PPM temperature compensated oscillator (TCXO), which is well suited for GNSS signal processing, and a 4.5 V powered bias-tee to feed an active antenna that can be enabled by software. Check out the Osmosdr_Signal_Source documentation for more details.

Full configuration file (updated for the current GNSS-SDR version):

[GNSS-SDR]

;######### GLOBAL OPTIONS ##################
GNSS-SDR.internal_fs_sps=2000000

;######### SIGNAL_SOURCE CONFIG ############
SignalSource.implementation=Osmosdr_Signal_Source
SignalSource.item_type=gr_complex
SignalSource.sampling_frequency=2000000
SignalSource.freq=1575420000
SignalSource.gain=50
SignalSource.rf_gain=40
SignalSource.if_gain=30
SignalSource.AGC_enabled=true
SignalSource.samples=0
SignalSource.repeat=false
SignalSource.dump=false
SignalSource.dump_filename=../data/signal_source.dat
SignalSource.enable_throttle_control=false

;# Please note that the new RTL-SDR Blog V3 dongles ship a < 1 PPM
;# temperature compensated oscillator (TCXO), which is well suited for GNSS
;# signal processing, and a 4.5 V powered bias-tee to feed an active antenna.
;# Whether the bias-tee is turned off before reception depends on which version
;# of gr-osmosdr was used when compiling GNSS-SDR. With an old version
;# (for example, v0.1.4-8), the utility rtl_biast may be used to switch the
;# bias-tee, and then call gnss-sdr.
;# See https://github.com/rtlsdrblog/rtl_biast
;# After reception the bias-tee is switched off automatically by the program.
;# With newer versions of gr-osmosdr (>= 0.1.4-13), the bias-tee can be
;# activated by uncommenting the following line:
;SignalSource.osmosdr_args=rtl,bias=1

;######### SIGNAL_CONDITIONER CONFIG ############
SignalConditioner.implementation=Pass_Through

;######### CHANNELS GLOBAL CONFIG ############
Channels_1C.count=8
Channels_1B.count=0
Channels.in_acquisition=1
Channel.signal=1C

;######### ACQUISITION GLOBAL CONFIG ############
Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition
Acquisition_1C.item_type=gr_complex
Acquisition_1C.coherent_integration_time_ms=1
Acquisition_1C.pfa=0.01
Acquisition_1C.doppler_max=5000
Acquisition_1C.doppler_step=250
Acquisition_1C.dump=false
Acquisition_1C.dump_filename=./acq_dump.dat

;######### TRACKING GPS CONFIG ############
Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking
Tracking_1C.item_type=gr_complex
Tracking_1C.dump=false
Tracking_1C.dump_filename=./tracking_ch_
Tracking_1C.pll_bw_hz=35.0;
Tracking_1C.dll_bw_hz=1.5;
Tracking_1C.pll_bw_narrow_hz=2.5;
Tracking_1C.dll_bw_narrow_hz=0.5;
Tracking_1C.extend_correlation_symbols=1;
Tracking_1C.dll_filter_order=2;
Tracking_1C.pll_filter_order=3;
Tracking_1C.early_late_space_chips=0.5;
Tracking_1C.early_late_space_narrow_chips=0.25

;######### TELEMETRY DECODER GPS CONFIG ############
TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder
TelemetryDecoder_1C.dump=false

;######### OBSERVABLES CONFIG ############
Observables.implementation=Hybrid_Observables
Observables.dump=false
Observables.dump_filename=./observables.dat
Observables.enable_carrier_smoothing=false
Observables.smoothing_factor=200

;######### PVT CONFIG ############
PVT.implementation=RTKLIB_PVT
PVT.positioning_mode=PPP_Static  ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic
PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad
PVT.enable_rx_clock_correction=false
PVT.output_rate_ms=100
PVT.rinexobs_rate_ms=100
PVT.display_rate_ms=500
PVT.dump_filename=./PVT
PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea;
PVT.flag_nmea_tty_port=false;
PVT.nmea_dump_devname=/dev/pts/4
PVT.dump=false
PVT.flag_rtcm_server=true
PVT.flag_rtcm_tty_port=false
PVT.rtcm_dump_devname=/dev/pts/1



## References

1. J. Arribas, GNSS Array-based Acquisition: Theory and Implementation, PhD Thesis, Universitat Politècnica de Catalunya, Barcelona, Spain, June 2012.

2. K. Borre, D. M. Akos, N. Bertelsen, P. Rinder, S. H. Jensen, A Software-Defined GPS and Galileo Receiver. A Single-Frequency Approach, 1st edition, Boston: Birkhäuser, November 2006.

3. C. Fernández-Prades, J. Arribas, P. Closas, Turning a Television into a GNSS Receiver, in Proc. of the 26th International Technical Meeting of The Satellite Division of the Institute of Navigation (ION GNSS+ 2013), Nashville, TN, Sep. 2013, pp. 1492 - 1507.

Tags:

Updated: