RTL2832 (ISDB Mini) ADS-B Reception Field Test

After I realized that the RTL2832 TV dongles were capable of receiving and decoding ADS-B transmissions from aircraft using ADSB#, I really couldn’t resist testing it out further. It was a simple one-click (well, almost) procedure, unlike the early incarnations of the decoder.

I may have been a little brief in my discussion on RTL2832 dongles and their possibilities, but the guys at rtl-sdr.com have done a good job of keeping us up with the news of new software and decoding successes. Another great resource is superkuh.com where there are resources such as the datasheets for the front end tuner chips, normally available only under an NDA. This is aside from the main rtl-sdr section at Osmocom, where the initial development centred upon, and Balint Seeber’s excellent wiki pages which make it easy to get up and running on Windows.

The Second Attempt

In my last post, my first naive attempt at receiving ADS-B was achieved using ADSB# and something showed up under adsbScope. Great. But I wanted to push a bit further – what can be achieved in terms of range? How can we improve reception? What do all the options mean?

For a day, I ran ADSB# feeding data into adsbScope with my ISDB Mini (RTL2832U + E4000) dongle plugged into an old MobileOne SCABASE multi-band dipole scanner antenna. The antenna “claimed” to be a broadband dipole – which we should realize as “great for some bands, marginal for others” – was not a likely candidate to have been optimized for ADS-B reception. The antenna was attached to 3.6m of RG-58U 50 ohm coax. While RG-58U was quite popular for “thinnet” and radio scanner antennas with BNC connectors, it’s attenuation figures are shockingly high above 500Mhz or so. The loss is claimed to be 21.5dB at 1Ghz for 100 feet (i.e. 30.48m), so the loss through the cable alone is 2.5dB. Add to this, the possibly inefficient antenna, plus the loss through the BNC to MCX adapting pigtail and I could conceivably see that the antenna system gain would be about -5dBd.

Already, a potential for improvement can be made by building a dedicated ADS-B antenna and using coax which is more suitable for high frequencies. Because I also have a few hobby satellite dish installs, I have some left-over RG-6 rated to 2150mhz, which can have F-connectors terminated onto it and directly connect to an F-to-MCX adapter like this one making it easy! But I do have to build it … I’ll leave that to another time.

F to MCX adapter

One thing to note is that the antennas for ADS-B are to be vertically polarized and omnidirectional. High gain omnidirectional antennas are suitable, up to a point, as the gain is made by sacrificing sensitivity directly above and below the antenna (where the signal is strong) and increasing the gain towards the horizon (where the signal is likely to be weak). Too much gain may cause a “hole” effect where signals directly overhead are lost. High gain beam antennas (yagi, panel, dish) are rarely suitable unless you really want to focus on one small patch of sky … or maybe you have many receivers, and you’re digitally filtering/combining the packets from all of them. Another Frankenstein idea which I might pursue in the future.

Also worthy of note is the lack of availability of E4000 based tuners as Elonics underwent liquidation last year. The consensus is the Rafael Micro R820T is the next best thing (if not better in some respects), and support for it is available in the latest rtl-sdr builds.

With the antenna oriented for vertical polarization in the roof-space at home, I was receiving aircraft sporadically out to Richmond and Camden from Chester Hill. It wasn’t all smooth though – low level aircraft at Sydney Airport disappeared below 4000 feet (due to terrain and buildings shadowing the signal) and those flying on the approach circuit were very jumpy towards the north of Sydney. The range I was seeing was about 40km at home – noting that impulse interference from low quality power supplies, wireless routers and possibly mobile phones can overwhelm these cheap tuners from time to time (as 1090ES modulation is pulse-position modulation).

I left adsbScope running and put a screen recorder to capture the flight paths as plotted over the operating hours of Sydney Airport. I disabled flight path prediction (so, if the position updates, packets have been received) and set the drop-off time to 1 minute (so if no packets are received for 1 minute, the plane is taken off the screen). One thing to note is that the 1090Mhz frequency is also used by Secondary Surveillance Radar (Mode A/C and newer Mode S). For compatibility with these services, ADS-B in 1090ES (extended squitter) breaks up its data transmission into five packets – if we lose one of them, you will see the speed/heading/altitude update, but the position remain static or vice-versa. The recording has been sped up significantly to make it more “watchable” – 480 times real-time rate. (Note, available in HD where labels are readable.)

I personally was happy with this given the price, but it should be even better. At least most of the Sydney terminal control area was covered. The software had a few options to tweak –


Port is quite self explanatory – it controls what port the data is output on. Share with ADSBHub controls whether you’re sharing the data and with which host. More important are the Decoder and RTL-SDR Control options. The Confidence number describes how many frames with a given ICAO address have to be decoded within the Timeout time to have its address whitelisted and packets matching that address forwarded on. This is because the modulation decoding can have many false decodes – if you are really in range of a plane, you expect to receive a packet every second – so the default of 4 is adequate. The lower range of 3 will result in an increase in the frames/sec count, but those frames are likely all garbage. The defaults are sensible.

The RTL-SDR Control option allows you to select a tuner (if you have many) and control whether the RTL AGC (automatic gain control) is on, and whether the Tuner (in this case, mine is an E4000) AGC is on. There is a bit of a debate whether both on results in better decodes or not – try it and see. Unticking both will allow you to set gain manually using the slider – which I’ve always found to be a compromise. Some positions increase the frames/sec dramatically, but are all garbage frames (i.e. no increased plane activity or range observed), and often a setting which is good to receive a given plane at a given slant range (distance, flight level) would saturate on others or be insufficient for others. The AGC seems to work adequately as it is.

Then you can optimize the offset – most of my dongles are about 40-80ppm offset. You can get a crude measurement by firing up an SDR application, looking around 1090Mhz for your pulses (sometimes hard to detect) – and seeing what the reported frequency by the SDR program is.

The formula to compute PPM would be:

( ( reported frequency / nominal frequency ) – 1 ) * 1 000 000

More information on the settings can be had from the ADSB# Quick Start Guides.

If I wanted to get more data – where else to go but Sydney Airport?

Field Data Collection

The challenge was – how to collect data near Sydney Airport? It would be obvious to some that you could just carry a laptop, the tuner dongle and antenna there, sit down and watch the pretty display but I had a dilemma.

Most of my laptops weren’t available for use – they were tied up in other projects and they were relatively dated and underpowered. The more powerful laptops were also heavy, clunky and had short battery life. In the field, you rarely have access to power – and I wanted to observe for a moderate period.

What I had available to use was my Asus R011CX Intel Atom N2600 based netbook with 1Gb of RAM running Windows 7 Ultimate. Most people familiar with Software Defined Radio will realize that this sounds like a useless pile of junk as SDR applications are typically very DSP heavy, requiring oodles of CPU time to perform mathematical transformations on the samples to extract the signals that we’re looking for.

If you were skeptical this could ever work – I wouldn’t blame you. I was skeptical myself. But the ADS-B signal proved to be a saving grace – it’s simplicity as pulse-position modulation lends itself to a simplified amplitude-sensing decoding scheme which could be very efficient. It certainly didn’t appear to involve exotic filters as per the flow diagram, so I gave it a shot.

No luck. ADSB# hogs the CPU (one of them) entirely, and produces erratic sporadic bursts of output. But all hope is not lost – as an alternate software existsRTL1090. The website is a bit tricky to navigate – scroll down and you will see the software.

The RTL1090 software is a lot lower on CPU usage, and its decoding performance is just as adequate. One thing to note is that ADSB# uses AVR format output, whereas RTL1090 defaults to BEAST (binary) format output. Luckily adsbScope now accepts both – set to normal for AVR and binary for BEAST, and make sure you have the right port and you’re good to go!

RTL1090 also seems to filter any bad packets, so adsbScope always reports 100% data quality, whereas ADSB# will let any that pass its confidence filter go to adsbScope – so it sometimes hovers between 60-90%. RTL1090 can also produce AVR format output if you invoke it with the /avr switch. RTL1090 comes pre-set for most users, there’s really no need to touch any settings – just hit start! The recommended setting is to have both AGCs enabled which is what it comes set at as a default.


It’s easier to set up RTL1090 by unzipping it into the same folder where you have ADSB#. This allows you to share the rtlsdr.dll between the two, as RTL1090 doesn’t have this bundled in with their package.

That’s the software for decoding sorted – but how was I to view the data? On the puny netbook screen? No. I didn’t want to do that. Aside from eating up the CPU time of the netbook, making the decoding even more unstable, I wouldn’t be able to get much detail on it, nor would I be able to do any screen-recording.

The solution was a simple networking problem – the RTL1090 (and ADSB#) are running a simple TCP socket server. If I could get my computer from home to connect to the TCP socket served by my netbook, this would be a cinch! This was made easy by the fact that I’m a mobile data user with a Wi-Fi modem (on Kogan, and fairly happy with it), but then I’d still have potential issues with carrier grade NAT (some mobile ISPs do it), firewalls (again, some ISPs do it) and port forwarding (which my Wi-Fi modem might not reliably do).

The answer to that problem was to use a VPN tunnel to push the data between endpoints. This way, all my computers will appear to be on the same network making connections between adsbScope running on my home computer and RTL1090 on my netbook in the field easy. Not all VPN solutions are created equal – I’ve run a PPTP VPN system at home behind a NAT only to find the NAT on the other side is hostile. NAT traversal is a tricky business, but Hamachi is a common solution to the problem. It is free for up to 5 computers in unmanaged mode, and offers authentication, encryption and compression (if you enable it, which I did) and the ability to ride out transient network connectivity issues (making it valuable because 3G mobile connections can be a pain). Its NAT traversal is transparent to the end user – and generally is in the category of just works. If you feel inclined, you could try running OpenVPN and setting that up …

Hamachi allocates an IP in the 25.x.x.x region, so as long as you use the right Hamachi allocated IP, the traffic will flow over the tunnel transparently.

But how about viewing the data? Sure, I can send the data at home and have it plotted at home, but it’s pretty boring sitting near an airport twiddling your thumbs. To that end, I had ports opened at home, a dynamic DNS server (to give us a DNS name to use) and VNC servers running on my machine. This allows for remote administration of the computer at home – so I can watch the screen remotely, and command the screen recorder etc. I bought along my old iPad (original) which hooked up to the same 3G mobile connection, making a direct connection to home.

I rode 36km from Chester Hill to Botany Bay (right next to the airport – location with a perfect view of the runways and a good view of the ground), where I sat myself down on the park benches next to the Grand Parade. Sorry, the panorama was taken with the Samsung Galaxy S3 phone I had with me – not quite the quality I normally would show.

Port Botany Panorama

And just in case you noticed, yes, that’s a crappy K-Mart bike I’m riding, with decent Schwalbe Marathon Plus tyres on it. It’s a rubbish bike at a cheap price – not recommended unless you really want to have something break on every ride and you’re mechanically inclined.

Of course, I couldn’t bring any massive antenna, so I just used the short stick that the tuner came with, but I trimmed it to about 69mm which is the quarter wave length of 1090Mhz.

The Setup at the Grand Parade

It’s a bit crazy, but it works! Surprisingly, with the thin stick provided and its crappy coax, we were able to receive planes at a much more respectable 100km+ distance, although only reliably out to about 50km. Still much better than home. Here’s a little more than an hour’s observation played back at 60 times real time speed. It’s great to see that even some terminal activity can be seen with the planes taxiing around the runways. (Note, available in HD where labels are readable.)

I’m totally chuffed that a $11 tuner stick with the included antenna trimmed down has such good range. If only I could have this mounted permanently up high somewhere nearby – and have the data piped out …

The next step may just be to build a new antenna at home, mount it higher, and see just how much better it can get … but if you have any interest in plane spotting, it’s definitely much more interesting with a virtual radar in front of you. Each and every take-off is visible (with a 1-2 second delay due to VPN/3G/VNC delay), with its flight code. Its path visible right out to when your eyes can’t resolve the plane anymore. Incoming planes to land (on good reception) would show up before landing. It’s amazing. I didn’t know what an A380 sounded like taking off – but I do now because now I know what took off was positively identified as an A380.

About lui_gough

I'm a bit of a nut for electronics, computing, photography, radio, satellite and other technical hobbies. Click for more about me!
This entry was posted in Computing, Radio and tagged , , , . Bookmark the permalink.

14 Responses to RTL2832 (ISDB Mini) ADS-B Reception Field Test

  1. Pingback: ADSB# Range Testing with the RTL2832U+R820T Tuner | Gough's Tech Zone

  2. Pingback: Project: ADSBpi with dump1090 | Gough's Tech Zone

  3. Pingback: Combining Multiple RTL-SDRs for Improved ADS-B Reception - rtl-sdr.com

  4. Very interesting, thank you. I built one of these:


    It is in the loft of our bungalow and hooked up to an uncased RTL2832 via a Raspberry Pi. We are at about 750 feet AMSL about an hour west of London, UK, and I can see ADS-B traffic out to the French coast, Dover, middle of Wales and up around Birmingham. I am pretty sure I am missing some, though!

    I use dump1090 and send the data via TCP to local clients.

    What next? Well, the dongle is bound for a die-cast box for a start. I have hopes of trying DF and/or multilateration!


    • lui_gough says:

      Great work!

      You may lose traffic sometimes because of purely the noise from having a high air traffic density (Europe is fairly packed compared to Australia) – all of the nearer planes could be obscuring weaker pulses from further planes.

      Of course, shielding is a great idea to minimise the noise from outside getting into the RF chain.

      As for multilateration, I’m not too sure this will happen per-se. It requires pretty precise timing to give good resolution – with different USB latencies, buffer sizes, and tuner crystal offsets – it may still be possible using sample number as a timing source, but accuracy would be unknown. I await someone to code this up 🙂

      – Gough

  5. Thank you.

    The Flightradar24 and Planeplotter communities seem to apply multilateration, though I’ve no idea how well it works. GPS-grade timing as close to the dongle seems pretty important, I’d guess.

    I have also been musing on trying to do D/F along Watson Watt/Adcock lines just for the hell of it but the theory is beyond me at the moment!

    I just ran up the software and it shows 27 ADS-B responders and 40 using other modes, so you can imagine why trying to track some of those gets tempting.

    All the best,


    • lui_gough says:

      Dear Ben,

      I might be wrong, but as I understand it, multilateration in the “hardware” (i.e. expensive”) radar boxes uses a free running clock at one of many rates (e.g. 12Mhz). The idea is that many receivers with relatively large geographic spread will send their copy of a given packet tagged with the timestamp of their free running clock.

      If you collect multiple packets with different time-stamps, they’re no good unless you synchronize them. So I think that they look for multiple trains of packets which are commonly received by more than one other receiver. As the packets are sent spaced in time (say, if they had 1000ms between them, this will remain constant no-matter where you were), this can be used to determine the offset of the clock from one radar box to the other. Once you know the offset – then you look at the packets of interest (say Mode A/C radar returns), and see the difference in time between reception at a number of known locations. This gives you a mathematical locus of possible positions – if you have enough receivers receiving from a vast geographic spread, you can “narrow down” the area which the signal could have been emanated from – subject to accuracy of clock signals.

      Now, conceptually, to implement multilateration using RTL2832 in software by looking at the times decoded packets come out of the decoder is not a good idea. There’s so many variables – USB bus latency, buffering, transaction size, and CPU decoding speed. So I’d say if we are to get multilateration, the answer most probably lies in looking at the time the message started relative to the 2Mhz sample clock. If you assign each sample a 32-bit number as a time stamp, you can try to implement something similar as I suggested above.

      But I’m not sure if the sticks are stable enough … and I’m not really an expert in this field so I guess someone else might work it out.

      – Gough

  6. Thank you for that – most enlightening. I wondered how they did it using ‘absolute’ timings, and seems as if they don’t! Often the case that if one subconsciously queries something, it often sin’t so…

    Ah well, if I had a drawing board, I could go back to it!


  7. http://www.coaa.co.uk/multilat.pdf refers – sorry if you’ve seen it already.


  8. My readings suggest the following:

    1. A USB GPS will give at best a 1 second precision.

    2. The Raspberry Pi has an accessible clock with a resolution of 1 microsecond.

    3. A shared absolute time with 1 microsecond accuracy ought therefore to be on the cards.

    4. My sums (done at least twice, in two sets of units, as I make so many mistakes!) suggests that theoretical perfect use of these would allow a pulse sequence to be timed to correspond to a distance of 300 metres, or 982 feet by the other route!

    In theory, theory and practice are the same thing, whereas in practice they are different. So I am not suggesting that miracles could be wrought, especially in light of e.g. network transit times, but a limited experiment might be possible. I shall continue musing!

    All the best,


    • lui_gough says:

      1 microsecond would be nice, time-wise, but if you take the time from the Pi itself, then you’re going to suffer USB bus jitters, latency from buffering and “multitask scheduling”. To me, the whole idea of taking the time has to be integrated with the “stick” itself – COAA uses a 24Mhz MLAT clock, which implies 4*10^-8 seconds might be a more preferable aim!

      That being said, the reason why I keep suggesting “sample number” is because this could very easily be produced and is directly related to the reception of the signal itself. Just keep a 32-bit (or whatever is used in AVR-MLAT or other MLAT capable protocols) counter which counts every 8-bit sample as it’s going by the decoder – and as soon as a frame is detected as valid, “copy” the counter value into the packet and we’ve got a stream that’s MLAT compatible to some extent. (With the knowledge that our MLAT clock is different to the others – with a bit of multiplication, you may be able to get it to mesh with others, but then you might degrade the accuracy.) Then you need the client software to “read and calculate” based on the time stamps from several sources – this will need a bit of a “rethink” as well. Fundamentally, the challenges seem to lie in software – the accuracy of the system will be interesting to see.

      Sure, it’s a 2Mhz sampling rate – but 1/2Mhz (frequency to period conversion) gives 0.5uS – twice as short as the Pi’s own clock with the advantage that it is *definitely* accurate to the pulses received, provided that no samples are dropped (which happens infrequently after the tuner is started – with the exception of an overloaded computer).

      I’m not sure, but the idea sounds great that it’s 300m (yes, I agree with you here, speed of light * time interval), however, there is another enemy although it’s probably not too bad and that’s clock drift. Anything with a crystal will “shift” its timing accuracy with the influence of temperature, driving conditions and so-forth. The crystals may have an absolute accuracy about 150ppm (the expensive ones can get 5ppm with TCXO, or much better with OCXO). They could ride up and down within short (seconds) of 0.1-1ppm. Although that being said, this error is probably fairly tiny compared to timing intervals, still worth a thought.

      And said from that, the need to get enough receivers in the right configuration – it’s like GPS in some regards – the geometric arrangement of the receivers (as opposed to transmitters in GPS) will determine the locus that will be generated, and the “further” they are with common view of packets of interest, the more accurate the intersections may be.

      – Gough

  9. Hmm. I don’t think we’re very far apart on this. Unlike geo-location – can’t think of two more badly placed sites for any experimental work!

    I was proposing to use the Pi 1usec clock, concatenated with real time from the GPS, as a sample time with which to label successful recognition of an SSR pulse train. Since the GPS is accurate enough by definition (? bold statement ?) then one is worried only by any drift in the Pi for a period of one second, or whatever interval one chose to re-sample the GPS time. One wouldn’t need to transmit the whole string as internet latency would confer an upper bound on the utility of the data. (This last has the feel of one of those statements one might eventually regret, along the lines of ‘640K ought to be enough for anybody.’).

    I quite agree that the inability to synchronise the actual clock with the RF activities directly will affect precision but submit that errors in that part of the chain will be of two components, the one ‘fixed’ due to latency and the other ‘jittery’ as a result of e.g. USB vagaries.

    Errors of the first sort would manifest themselves in an inability of the data fusion software to arrive at a small position envelope for the target – the ‘cocked hat’ as it was called in RDF days. The other sort will cause sudden variations in reported position.

    Now, the latter might well yield to filtering by the correlator; and if the former were fixed enough they might be susceptible to being adjusted out over time – visions of tweaking pots!

    As you say – a software problem! Oh, and the small matter of (me) recruiting suitably placed folk willing to host a ground station…

    • lui_gough says:

      You know what? I just looked at here: https://github.com/antirez/dump1090/pull/23

      Looks like –net-beast should already insert the clock based on samples into the (now BEAST binary encoded) stream. This might mean MLAT in your client might work just fine – I will try and investigate this if I get the chance.

      EDIT: Just realized the MLAT clock options inside ADSBscope (a free virtual radar display software) does not have a 2Mhz option. I think this in itself would rule out the ability to use the time-stamped data properly. Maybe if the guys behind ADSBscope could add that in, it might work?

Error: Comment is Missing!