Airspy ADS-B decoder

I agree, but you know how assumptions work. Could be using a different cable, dog could have chewed on it, got crimped, faulty from factory. Free, easy to test and often overlooked.

2 Likes

Sorry, had power outage and then funeral to deal with.

Total time: 59.9690 s
Average speed 19.9980 MSPS Real

Total time: 59.9504 s
Average speed 16.3933 MSPS Real

Better:
$ ./throttled
Status: 0x0
Undervolted:
Now: NO
Run: NO
Throttled:
Now: NO
Run: NO
Frequency Capped:
Now: NO
Run: NO

MeanWell 10A 5V at 5.2V

I don’t think that is the issue, but can check later on if needed.
I’m not running with bias T enabled, using external power for LNA.

Yup
Linux RaspberryPi4 4.19.75-v7l+ #1270 SMP Tue Sep 24 18:51:41 BST 2019 armv7l GNU/Linux

So this shouldn’t be happening for the non-packed case.
Seems there is lacking USB bandwidth.

My RPi3B+ can do 20 MSPS without packing no problem.

Did you reboot after the kernel upgrade?

Just for good measure, install the firmware update in case it isn’t installed on your system (i wouldn’t know why this would be required but you never know)

Also let’s just make sure the airspy kernel module doesn’t load, i have been having some strange kernel messages because of it. It’s not required for airspy_rx or airspy_adsb.
Actually i don’t know what you need it for.

echo "blacklist airspy" | sudo tee /etc/modprobe.d/airspy.conf
sudo apt update
sudo apt dist-upgrade
sudo apt install rpi-eeprom
sudo reboot

Can you repeat this test after doing all that:

timeout -s INT 60 airspy_rx -r /dev/null -t 4 -a 20000000 -f 1090 -g 18

Probably already asked: The airspy is connected directly to the RPi?
How hot is it where you are?
Can you just for testing do the test after having the RPi swiched off for 5 minutes?

Finally you could do the test above on an RPi3B or other computer?
Maybe there is a problem with the Airspy device.

blacklisting seems to have helped.

Total time: 59.9530 s
Average speed 19.7400 MSPS Real

With packing
Total time: 59.9382 s
Average speed 20.0008 MSPS Real

$ sudo rpi-eeprom-update   
Bootloader EEPROM is up to date
CURRENT: Tue 10 Sep 2019 10:41:50 AM UTC (1568112110)
 LATEST: Tue 10 Sep 2019 10:41:50 AM UTC (1568112110)

Definitely up to date, and running cool.

Yes, connected directly with the USB cable that came with the R2.
I can try a power off and run, thought seems to be the airplay kernel driver you hinted at.

I can try an pi3b+, but it has always had trouble over 12.

Yeah i meant only for the test, not for actual usage.

20 MHz really needs to work without packing.

Does it give you MLAT now with packing and 20 MHz?
That would at least be something.

No clue what is happening though.
How old is the Airspy R2?
Maybe it needs a firmware update if it’s older than a year or two?

Oh now i see something.
Are you running dump978 on the same Pi?
That will somehow screw up the USB bus i think.
Those high USB bandwidths you really want the airspy to be the only USB device.

1 Like

@mikkyo - I’d like to learn how you added the “Avionics” section into rpi-monitor, or what went into the .conf. Can link some sort of info on that? Pretty slick! I don’t want to derail this thread with it more than I already just did. Thanks!

So far as running dump978 in tandem with the Airspy, perhaps if you separate between the USB 2.0 and USB 3.0 ports on the Pi4? Plugging a USB2 device into a USB3 port isn’t going to make it run faster, but I think each runs through it’s own pipeline so port saturation may not be as much of an issue if you plug one into the USB3 side and the other on USB2. Also, and perhaps more importantly, I’m almost certain each chipset is on a separate power fuse (at least left and right were on the Pi3+ and lower), so if you aren’t using a powered USB hub, plugging power hungry USB devices across from each other could help with power issues. Also, I haven’t seen the schem on the pi4, so I could be totally mistaken on this. Again, free and easy to test, and you may already be doing this and it may not be the issue to begin with, but wanted to toss more noodles to see if something sticks.

Probably still the same controller.
Also my guess it’s some problems with the programming or just latency because another device is using the USB system.
It’s annoying but that’s the way it is.
If you have an RPi4 and airspy, chances you have an old RPi3 you can use for 978.

The RPI4 should have bucket loads more USB bandwidth compared to older models. Ethernet and SD card are not shared with the USB ports anymore.

As i wrote, it might not be the USB bandwidth itself, but hiccup with the driver or something like that.
But it might be that the USB2 bandwidth is shared among all devices.

So both devices are USB2, none of the devices are USB3.
So the the USB2 part of the USB chip (it’s only one handling both protocols) needs to handle it.
This is probably be done via one internal USB2 hub, so you only have the USB2 bandwidth available once, it’s shared among all USB2 devices.
That’s my theory at least.
Airspy at 20 MHz and another dongle, not gonna work properly.

On a proper mainboard you might have multiple USB hubs so you can find ports where bandwith isn’t shared.
On these small boards i doubt it.

Anyway it’s easy to test, remove everything but the Airspy and check if it works then.
If it works with 20 MHz Airspy doing MLAT successfully and another device, please report back which device.
Somehow i’m doubting that this is a really stable setup.

Maybe there is enough bandwidth for 20 MHz with bit packing and an rtl-sdr dongle running 978.
But a second airspy, pretty sure that’s not gonna work.

From what I can find (and the published RPI4 schem is trash), all downstream USB ports are controlled by the VL805, which is natively a 4-port usb 3.0 controller, so bandwidth isn’t a problem within the controller itself…that said, no clue if it’s just a single PCIe lane that pipes to the SOC (even then, PCIe v1.0 specs out over 250MB/s full duplex single-lane, PCIe v5 is the latest spec). From there it’s up to the firmware/driver to sort out, so anyone’s guess.

Specs aside, nothing compares to real-world tests. Wish I had more than 1 Airspy to test, perhaps soon. Anyone selling? :rofl:

Do you know the internal layout of that device?
Might very well be that USB2 devices are handled by a different part of the chip, somehow sharing the USB2 bandwidth.
20 MSPS at 12 bit is 240 Mbit/s with bit packing and 320 Mbit/s without bit packing if i’m not mistaken.

While USB might theoretically have 480 Mbit/s, the real bandwidth achieved is much lower, probably not much above the 320 Mbit/s required for 20 MSPS without packing.

This quote is about an USB3 Hub, but as i said without knowing the exact layout of the USB chip, i would assume it’s only a single hub.

The four USB 2.0 devices will need to share a total of 480 Mbps between them, even if connected to a USB 3.0 hub. They will not be able to operate concurrently at full speed. Instead, they will only have one-quarter of the maximum USB 2.0 bandwidth available to them. This is because, effectively , a “USB 3 hub” is actually two dedicated hubs in one box – one for USB 2.0 data and another for USB 3.0 data.

[SOLVED] Total Bandwidth for Multiple USB 2.0 Devices in a USB 3.0 hub | Tom's Hardware Forum

I’m pretty sure the controller chip is the “root hub”, thus if the USB chip has only one USB 2.0 “root hub”, the USB 2.0 speed is shared.

Unfortunately, I don’t. Speculation, and this is about all I could find: https://www.via-labs.com/product_show.php?id=48

Either way, assumptions are the root of all evil, so it’s going to boil down to testing and feedback. I’m now on the hunt for 2 Airspy R2’s and another Mini, but need to find a deal somewhere, somehow - The wife’s gonna love this…

1 Like

Try airspy.us
They had them on special yesterday.

1 Like

Is it that beneficial to use an airspy for dump978-fa?
I’d say you might be better off with an uputronics 978 amp and an normal rlt-sdr dongle.

I seriously doubt it. Overkill in my opinion and a waste of a good radio, but regardless, I think the goal was to see if the Pi4 is capable of handling more than just a single Airspy hung off a port - whether it be another Airspy (anything > 12Msps is probably a waste for UAT), or a cheap rtl-sdr.

So far as myself, I do much more outside of ADSB, so a couple more solid radios to work with would be a good problem to have :slight_smile:

@jonhawkes2030 - I keep an eye out all the time on airspy.us, and I think the R2 have been up for $169 for some time now ($99 for the mini). Waiting for those to come down or find some used since that’s steep for their age and support level. Can get the HF discovery+ for the same price -granted for different use, but it’s just my angle I guess - for right or wrong. I still think they make great radios that seemingly fills the huge gap between hobby and professional.

2 Likes

This does appear to be how the Pi 4 is set up.

Here’s what lsusb -t looks like on a Pi 4 with no external devices connected:

/:  Bus 03.Port 1: Dev 1, Class=root_hub, Driver=dwc_otg/1p, 480M
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 480M
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M

Empirically:

  • USB3 devices in a USB3 port use bus 02 @ 5Gbps:
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M
    |__ Port 2: Dev 3, If 0, Class=Mass Storage, Driver=usb-storage, 5000M
  • USB2 devices in either port type, and USB3 devices in USB2 ports, use the child hub on bus 01 @ 480Mbps
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 480M
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
        |__ Port 1: Dev 7, If 0, Class=Human Interface Device, Driver=usbhid, 12M
        |__ Port 1: Dev 7, If 1, Class=Human Interface Device, Driver=usbhid, 12M
        |__ Port 3: Dev 3, If 0, Class=Mass Storage, Driver=usb-storage, 480M
  • bus 03 is unused for external devices (I think that’s the SoC bus)

So if you have multiple USB2 devices (even in the USB3 ports) they do appear to share the 480M bandwidth available to bus 01.

It’s not going to benefit from an increased sample rate, the dump978-fa demodulator is hardwired for 2.08333MHz.

I have some prototype work for a higher rate demodulator around (probably at 6.mumble MHz for 6 samples/bit) but it’s relatively low priority currently.

2 Likes

Set up is here
https://xavierberger.github.io/RPi-Monitor-docs/11_installation.html

After that is setup, you can install and configure the avionics template.
(Sample one in German)

I believe I got my base template from
https://www.jeremybrown.co.nz/monitorADSB.php

but that site doesn’t seem to work anymore.
There used to be a tutorial in some forum post on some flight tracking site, but can’t find it now. :wink:

Template goes here
/etc/rpimonitor/template/avionics.conf

rpimonitor has an interactive mode, which helps make it easy to test commands and regexes to get the values you want to monitor. See
https://xavierberger.github.io/RPi-Monitor-docs/23_configuration_helper.html

If you want to crib off my template, feel free, its very hacky, due to many of these feeder bits all behaving differently, like for getting the version.
You’ll have to change local IPs to those of your pi(s), and likely mess with other things like URLs to your feeders on the various sites, update feedIDs, etc.

 $ cat /etc/rpimonitor/template/avionics.conf
########################################################################
# Extract information about Opened Port
#  Page: 1
#  Information               Status
#  - dump1090-fa port (8080)           - yes      - no
#  - Flightradar24 Feeder/Decoder port (8754)  - yes      - no
#  - FlightAware port (30104)          - yes      - no
#  - PlaneFinder port (30053)        - yes      - no
#  - Virtual Radar Server port (8081) - yes - no
#  - ModeSMixer2 port (8787) - yes - no
#  - lighttpd port (80) - yes - no
#  - collectd status - active - inactive|failed|activating|deactivating
#  - dump978-fa port (30978) -yes -no
#  - RadarBox status - active - inactive|failed|activating|deactivating
########################################################################
dynamic.1.name=dump1090
dynamic.1.source=netstat -nlt
dynamic.1.regexp=tcp .*:(8080).*LISTEN

dynamic.2.name=fr24
dynamic.2.source=netstat -nlt
dynamic.2.regexp=tcp .*:(8754).*LISTEN

dynamic.3.name=piware
dynamic.3.source=netstat -nlt
dynamic.3.regexp=tcp .*:(30104).*LISTEN

dynamic.4.name=finder
dynamic.4.source=netstat -nlt
dynamic.4.regexp=tcp .*:(30053).*LISTEN

dynamic.5.name=vrs
dynamic.5.source=netstat -nlt
dynamic.5.regexp=tcp .*:(8081).*LISTEN

dynamic.6.name=modesmixer2
dynamic.6.source=netstat -nlt
dynamic.6.regexp=tcp .*:(8787).*LISTEN

dynamic.7.name=lighttpd
dynamic.7.source=netstat -nlt
dynamic.7.regexp=tcp .*:(80).*LISTEN

dynamic.8.name=collectd
dynamic.8.source=service collectd status
dynamic.8.regexp=Active: (.*) \(

dynamic.9.name=dump978
dynamic.9.source=netstat -nlt
dynamic.9.regexp=tcp .*:(30978).*LISTEN

dynamic.10.name=rbfeeder
dynamic.10.source=service rbfeeder status
dynamic.10.regexp=Active: (.*) \(

dynamic.11.name=adsbexchange
dynamic.11.source=ps awwux | grep socat | grep -v grep | grep feed
dynamic.11.regexp=feed.adsbexchange.com:(.*)

dynamic.12.name=opensky
dynamic.12.source=service opensky-feeder status
dynamic.12.regexp=Active: (.*) \(

static.1.name=dump1090ver
static.1.source=dump1090-fa --help
static.1.regexp=dump1090-fa (.*\b)

static.2.name=fr24ver
static.2.source=fr24feed --help
static.2.regexp=Version: (.*)/

static.3.name=piwarever
static.3.source=piaware -v
static.3.regexp=(^.*)

static.4.name=finderver
static.4.source=pfclient -v
static.4.regexp=version:(.*)

static.5.name=modesmixer2ver
static.5.source=/home/pi/mm2/modesmixer2 --help
static.5.regexp=ModeSMixer2 v\.(.*)

static.6.name=lighttpdver
static.6.source=lighttpd -v
static.6.regexp=lighttpd/(.*) \(

static.7.name=collectdver
static.7.source=collectd -h
static.7.regexp=collectd(.*)\.git\,

static.8.name=dump978ver
static.8.source=dump978-fa --version 2>&1 | grep dump | awk '{print $2}'
static.8.regexp=(.*)

static.9.name=rbfeederver
static.9.source=/usr/bin/rbfeeder --help 2>&1 | grep "Version " | awk '{print $4}'
static.9.regexp=(.*)

static.10.name=openskyver
static.10.source=journalctl -u opensky-feeder --no-pager
static.10.regexp=Version (.*)

web.status.1.content.1.name=Avionics
web.status.1.content.1.icon=daemons.png
web.status.1.content.1.line.1="<table class='table'><thead><tr><th>Application</th><th>Status</th><th>Version</th><th>Web interface</th></tr></thead><tbody>"
web.status.1.content.1.line.2="<tr>"
web.status.1.content.1.line.3="<td><a href='https://github.com/flightaware/dump1090' target=_blank>dump1090-fa</a></td><td>" + Label(data.dump1090,"==8080","active","success") + Label(data.dump1090,"!=8080","inactive","danger") + "</td><td>" + data.dump1090ver + "</td><td><a href='http://127.0.0.1:8080/' target=_blank>DUMP1090</a></td>"
web.status.1.content.1.line.4="</tr>"
web.status.1.content.1.line.5="<tr>"
web.status.1.content.1.line.6="<td><a href='http://feed.flightradar24.com/#raspberry-pi' target=_blank>fr24feed</a></td><td>" + Label(data.fr24,"==8754","active","success") + Label(data.fr24,"!=8754","inactive","danger") + "</td><td>" + data.fr24ver + "</td><td><a href='http://127.0.0.1:8754' target=_blank>FR24 Feeder Status</a><br /><a href='https://www.flightradar24.com/premium/' target=_blank>Flightradar24.com Premium</a></td>"
web.status.1.content.1.line.7="</tr>"
web.status.1.content.1.line.8="<tr>"
web.status.1.content.1.line.9="<td><a href='http://ja.flightaware.com/adsb/piaware/' target=_blank>piaware</a></td><td>" + Label(data.piware,"==30104","active","success") + Label(data.piware,"!=30104","inactive","danger") + "</td><td>" + data.piwarever + "</td><td><a href='https://flightaware.com/adsb/stats/user/you' target=_blank>FlightAware</a></td>"
web.status.1.content.1.line.10="</tr>"
web.status.1.content.1.line.11="<tr>"
web.status.1.content.1.line.12="<td><a href='https://planefinder.net/sharing/client' target=_blank>pfclient</a></td><td>" + Label(data.finder,"==30053","active","success") + Label(data.finder,"!=30053","inactive","danger") + "</td><td>" + data.finderver + "</td><td><a href='http://127.0.0.1:30053' target=_blank>Plane Finder Client</a></td>"
web.status.1.content.1.line.13="</tr>"
web.status.1.content.1.line.14="<tr>"
web.status.1.content.1.line.15="<td><a href='http://www.virtualradarserver.co.uk/Download.aspx' target=_blank>VirtualRadar</a></td><td>" + Label(data.vrs,"==8082","active","success") + Label(data.vrs,"!=8082","inactive","danger") + "</td><td>2.4<br />31-JUL-2016</td><td><a href='http://127.0.0.1:8082/VirtualRadar/WebAdmin/Index.html' target=_blank>VRS Web Admin</a><br /><a href='http://127.0.0.1:8082/VirtualRadar' target=_blank>Virtual Radar Server</a><br /><a href='http://www.adsbexchange.com/' target=_blank>ADS-B Exchange</a></td>"
web.status.1.content.1.line.16="</tr>"
web.status.1.content.1.line.17="<tr>"
web.status.1.content.1.line.18="<td><a href='http://xdeco.org/?page_id=30#mm2' target=_blank>modesmixer2</a></td><td>" + Label(data.modesmixer2,"==8787","active","success") + Label(data.modesmixer2,"!=8787","inactive","danger") + "</td><td>" + data.modesmixer2ver + "</td><td><a href='http://127.0.0.1:8787' target=_blank>ModeSMixer2</a><br /></td>"
web.status.1.content.1.line.19="</tr>"
web.status.1.content.1.line.20="<tr>"
web.status.1.content.1.line.21="<td>lighttpd</td><td>" + Label(data.lighttpd,"==80","active","success") + Label(data.lighttpd,"!=80","inactive","danger") + "</td><td>" + data.lighttpdver + "</td><td><a href='http://127.0.0.1:8080/3d/' target=_blank>MyRadar24</a></td>"
web.status.1.content.1.line.22="</tr>"
web.status.1.content.1.line.23="<tr>"
web.status.1.content.1.line.24="<td>collectd</td><td>" + Label(data.collectd,"=='active'","active","success") + Label(data.collectd,"!='active'","inactive","danger") + "</td><td>" + data.collectdver + "</td><td><a href='127.0.0.1/collectd/' target=_blank>dump1090-tools</a></td>"
web.status.1.content.1.line.25="</tr>"
web.status.1.content.1.line.26="<tr>"
web.status.1.content.1.line.27="<td><a href='https://github.com/flightaware/dump978' target=_blank>dump978-fa</a></td><td>" + Label(data.dump978,"==30978","active","success") + Label(data.dump978,"!=30978","inactive","danger") + "</td><td>" + data.dump978ver + "</td><td><a href='http://127.0.0.1/skyaware978' target=_blank>dump978-fa</a></td>"
web.status.1.content.1.line.28="</tr>"
web.status.1.content.1.line.29="<tr>"
web.status.1.content.1.line.30="<td><a href='https://www.radarbox24.com/raspberry-pi/guide' target=_blank>RadarBox</a></td><td>" + Label(data.rbfeeder,"=='active'","active","success") + Label(data.rbfeeder,"!='active'","inactive","danger") + "</td><td>" + data.rbfeederver + "</td><td><a href='https://www.radarbox24.com/stations/EXTRPI00000' target=_blank>RadarBox</a></td>"
web.status.1.content.1.line.31="</tr>"
web.status.1.content.1.line.32="<tr>"
web.status.1.content.1.line.33="<td><a href='https://www.adsbexchange.com/active-feeds/' target=_blank>ADSBExchange</a></td><td>" + Label(data.adsbexchange,"==30005","active","success") + Label(data.adsbexchange,"!=30005","inactive","danger") + "</td><td>N/A</td><td><a href='http://www.adsbexchange.com/coverage-1D/?new' target=_blank>ADSBExchangeFeeder</a></td>"
web.status.1.content.1.line.34="</tr>"
web.status.1.content.1.line.35="<tr>"
web.status.1.content.1.line.36="<td><a href='https://opensky-network.org' target=_blank>OpenSkyNetwork</a></td><td>" + Label(data.opensky,"=='active'","active","success") + Label(data.opensky,"!='active'","inactive","danger") + "</td><td>" + data.openskyver + "</td><td><a href='https://opensky-network.org/receiver-profile?s=00000' target=_blank>OpenSkyFeeder</a></td>"
web.status.1.content.1.line.37="</tr>"
web.status.1.content.1.line.38="</tbody></table>"

then you edit

/etc/rpimonitor/data.conf

and add the avionics.conf template

include=/etc/rpimonitor/template/avionics.conf

Restart rpimonitor and collectd

sudo systemctl stop collectd rpimonitor
sudo systemctl start collectd rpimonitor
2 Likes

This does look to be the case from experimenting.
Plug in another dongle and start receiving data, or an old crappy usb thumb drive and start copying stuff, and then try the airspy and there isn’t enough bandwidth to sustain 20 MSPS.
So if you run an airspy, don’t use usb for anything else.
Sucks.

I’d love to get airspy_adsb compiled for my Mac mini, which has tons of bandwidth.
I be happy to do that for the airspy folks.

@mikkyo - Thanks a ton for the silver spoon, I’ll use wisely :slight_smile:

I also just did a little preliminary test by plugging a GPS unit in along with the mini running 20 MSPS and it spooked mlat as well… Will need to test more.

A couple years ago I saw much of the same problem when I booted and ran a Pi3 off a mini usb stick (no sdcard at all), I could never get MLAT to sync when using a flightstick even. Drive IO was almost non-existent since I always run log2ram. Go figure that one… That couldn’t have been a bandwidth issue, and I know it for sure wasn’t a power issue because the same would happen when running through a powered USB hub. MLAT must be terribly sensitive to any sort of buffering/interrupts due to it’s timestamp requirement. Wonder if it could be loosened up without bringing down the entire house of cards? Albeit, I have an FA Orange (978) and an FA Blue (1090) running through a powered USB hub on my test setup on a Pi3 and it has zero issues with MLAT, so not every device plays mean…

Grasping at straws still evidently.