1. What this guide builds
Two computers and five radios. Each radio sits where its antenna cable enters the house. Each computer decodes the signal there and sends only data over the home network. Antenna cable loses signal with every meter. Network cable loses nothing.
| Signal | What you get | Frequency | Antenna | Radio | Decoder | Computer |
|---|---|---|---|---|---|---|
| ADS-B | Aircraft positions | 1090 MHz | 1090 MHz vertical | FlightAware Pro Stick Plus | readsb (in ultrafeeder) | vhf |
| AIS | Ship positions | 161.975 and 162.025 MHz | AIS-band vertical | Airspy Mini | AIS-catcher (in shipfeeder) | vhf |
| ACARS | Aircraft text messages | 129 to 132 MHz | Discone, splitter leg A | Airspy R2 | acarsdec | vhf |
| VDL Mode 2 | Aircraft text messages, newer system | 136.650 to 136.975 MHz | Discone, splitter leg B | RTL-SDR Blog V4L | dumpvdl2 | vhf |
| HFDL | Aircraft messages over oceans | 12 bands, 2.9 to 21.9 MHz | Active loop | RX-888 Mk II | dumphfdl | hf |
| FT8 and FT4 | Amateur stations, worldwide | 1.8 to 28 MHz | Active loop | RX-888 Mk II | decode_ft8 | hf |
| WSPR | Low-power beacons, worldwide | 0.136 to 28 MHz | Active loop | RX-888 Mk II | wsprd | hf |
The two computers have these names in this guide:
vhf: a Raspberry Pi 5. It runs four radios in Docker containers.hf: an x86 desktop PC. It runs the RX-888 Mk II with ka9q-radio, as system services.
My own station uses four computers, for reasons of history.1 Section 15 lists the signals I receive with my own programs, which are not public, and a free program for each job.
roof cable entry home network
---- ----------- ------------
1090 MHz vertical ---------------- Pro Stick Plus --+
AIS vertical ------ FM filter ---- Airspy Mini -----+-- USB hub -- vhf (Pi 5, Docker)
discone -- FM filter -- splitter + Airspy R2 -------+ | maps, message log,
+ RTL-SDR V4L -----+ | feeds to networks
|
loop -- injector -- 30 MHz filter -- limiter -- RX-888 Mk II -- hf (x86 PC)
(own USB 3 socket) HFDL by UDP to vhf
Values to choose first
Write these down. The steps use them as placeholders.
| Placeholder | Meaning | Example form |
|---|---|---|
<LAT> <LON> |
Antenna position, decimal degrees | xx.xxxxx |
<ALT_M> |
Antenna height above sea level, meters | 45 |
<TZ> |
Time zone, TZ database name | America/Los_Angeles |
<NAME> |
A station name with no personal detail | my-station |
<UUID> |
One random ID for the aircraft networks | from cat /proc/sys/kernel/random/uuid |
<SER_ADSB> <SER_VDL2> |
Serial numbers you write to the two RTL radios | 1090, 136 |
<SER_MINI> <SER_R2> |
Factory serial numbers of the two Airspy radios | 16 hexadecimal characters |
Your position becomes public. Most tracking networks show their feeder stations on a map. Multilateration needs your exact position, so you cannot give a false one. Choose a station name that does not name you or your street. Sections 7 and 9 show the settings that hide the station mark on your own maps.
2. Bill of materials
Prices are US dollars, as listed by the named seller on 2026-10-07. They change. “See listing” means the price is on the linked page. A part marked ◆ is what I use; “an example” or “a similar one” is a link to a part like mine, not the one I have. A blank box is for your pencil.
Antennas
| ☐ | Part | Job | Connector | Price | Note |
|---|---|---|---|---|---|
| ☐ | ◆ FlightAware 1090 MHz antenna, 66 cm, 5.5 dBi | Aircraft | N type | $49.99, FlightAware store | Mast bracket included |
| ☐ | ◆ AIS-band vertical, tuned near 162 MHz | Ships | See listing | See listing | A low-cost one is enough to start2 |
| ☐ | ◆ Diamond D-130J discone, 25 to 1300 MHz receive, 1.7 m | ACARS and VDL2 | SO-239 (the D-130NJ has N type) | See listing, Amazon | One wide antenna, two radios |
| ☐ | ◆ MLA-30+ active loop with its power injector | Shortwave | SMA | See listing, Amazon | The amplifier is in the loop head3 |
Filters and protection
| ☐ | Part | Job | Price | Note |
|---|---|---|---|---|
| ☐ | ◆ RTL-SDR Blog FM band-stop filter, 88 to 108 MHz, over 50 dB | First part after the discone | See listing, Amazon | Loss under 0.5 dB below 1 GHz |
| ☐ | ◆ Nooelec Flamingo FM, over 40 dB typical | On the AIS antenna | See listing, Amazon | Optional4 |
| ☐ | ◆ Mini-Circuits ZX10-2-12-S+ 2-way splitter, 2 to 1200 MHz, SMA | Feeds two radios from the discone | $42.20, Mini-Circuits | Each leg gets a little less than half5 |
| ☐ | ◆ Turn Island Systems F3060 low-pass filter | In front of the RX-888 | $80, Turn Island Systems | Required at 64.8 MS/s (section 4) |
| ☐ | ◆ TAPR RF Limiter | Last part before the RX-888 | $20, TAPR | Needed if you also transmit6 |
Do not buy an amplifier at the start. Section 17 says why.
Radios
| ☐ | Part | Job | Price | Note |
|---|---|---|---|---|
| ☐ | ◆ FlightAware Pro Stick Plus | ADS-B | $45.99, FlightAware store | Amplifier (19 dB) and 1090 MHz filter are built in |
| ☐ | ◆ Airspy Mini, 24 to 1700 MHz, 12-bit | AIS | $99, airspy.us (out of stock that day) | An RTL-SDR also works7 |
| ☐ | ◆ Airspy R2, 24 to 1700 MHz, 12-bit | ACARS | $169, airspy.us | An RTL-SDR also works7 |
| ☐ | ◆ RTL-SDR Blog V4L | VDL2 | $37.95, rtl-sdr.com | Needs a 2026 driver (section 17). The older V4 is no longer made |
| ☐ | ◆ Stick-on aluminum heat sinks, 50 x 25 x 10 mm (mine, a pack of two) | On the dongles. Optional | See seller | My own addition, not part of the radios as sold. They run warm |
| ☐ | ◆ RX-888 Mk II, 16-bit, 10 kHz to 64 MHz direct | All of shortwave at once | $152.79, OpenSourceSDRLab, 2026-10-11 | Copies exist. Mine is from OpenSourceSDRLab. Without it, see the note8 |
Computers and USB
| ☐ | Part | Job | Price | Note |
|---|---|---|---|---|
| ☐ | ◆ Raspberry Pi 5, 8 GB | vhf |
$175 list (4 GB: $110) | Requirements in section 3 |
| ☐ | ◆ Raspberry Pi 27 W USB-C power supply | Power for vhf |
See seller | With a weaker supply the Pi limits its USB sockets to 600 mA in total |
| ☐ | microSD card, 32 GB or more (an example), or an NVMe drive with a Pi 5 adapter | Storage for vhf |
See seller | |
| ☐ | ◆ Powered USB hub with its own power supply (mine: Rosonway RSH-A10) | The four vhf radios |
See seller | A Pi alone can power about three radios |
| ☐ | ◆ x86-64 desktop PC with a USB 3.0 socket on the main board (mine: HP EliteDesk 800 G1 SFF, Core i5-4570, 12 GB, bought used; a similar one) | hf |
Used market | Requirements in section 3 |
| ☐ | ◆ SATA solid-state drive, 120 GB or more (mine: Crucial MX500 500 GB, bought used) | Storage for hf |
See seller | The FT8 recorder writes files all day |
| ☐ | ◆ Battery backup (UPS), 1500 VA (mine: CyberPower CP1500PFCLCD) | Keeps almost the whole station running through a short power cut | See seller | Optional. A long cut still stops the station: section 11, step 2 covers that |
Cable and small parts
| ☐ | Part | Job |
|---|---|---|
| ☐ | Low-loss 50 ohm coax for 1090 MHz, with an N plug at the antenna end and an SMA plug at the radio end (an example) | Aircraft antenna. Keep the loss under 6 dB and the length under 15 m (FlightAware’s advice) |
| ☐ | 50 ohm coax with a PL-259 plug (an example), and an SMA plug or adapter at the radio end (an example) | Discone |
| ☐ | Coax to suit the AIS antenna, SMA at the radio end | AIS antenna |
| ☐ | ◆ RG-6 quad-shield coax (an example), and two F to SMA adapters (an example) | Loop to hf. On shortwave, 10 to 20 m of it loses under 1 dB |
| ☐ | Short SMA plug-to-plug jumpers, 5 or more (an example) | Filter to splitter to radios |
| ☐ | ◆ Snap-on ferrites (an example) | Both ends of the loop cable, and the USB cables |
| ☐ | ◆ Grounding block for each cable where it enters the house (an example), and bonding wire | Section 4, “Ground the cables” |
| ☐ | 50 ohm SMA terminator (an example) | The noise test in section 11 |
| ☐ | Short USB extension cables (an example) | So wide radios do not block the next hub socket |
3. Computer requirements
I can only state what I measured. The table says where a number is measured and where it is an estimate.
| Computer | I recommend | What I measured on my station (2026-10-07) |
|---|---|---|
vhf |
Raspberry Pi 5 with 8 GB, 64-bit Raspberry Pi OS, wired Ethernet, a powered USB hub. Any 64-bit ARM or x86 computer that runs Docker also works. | A Pi 5 with the AIS, ACARS and VDL2 containers used 1.6 GB of memory and a load average near 1 on 4 cores. The aircraft containers run on another computer here. There they used about 1.5 GB more. The screenshot container alone used 0.66 GB. So 4 GB is tight, and I did not test it. |
hf |
x86-64, 4 cores of Intel Haswell class (2013) or newer, 8 GB, a USB 3.0 socket on the main board, a solid-state drive, Ubuntu Server 24.04 LTS, wired Ethernet. | A Core i5-4570 (4 cores, 2013) ran the receiver at 64.8 MS/s with about 150 channels. The receiver program used 69 % of one core. The whole machine was 22 % busy with HFDL and 29 % busy with every decoder. It dropped no data in a 19-hour test. Memory in use was under 2.5 GB. |
Rules for both:
- Use wired Ethernet. Multilateration needs steady timing.
- Give each computer a fixed address on your network, set on the computer itself.
- Keep the clocks synchronized. The ultrafeeder project recommends
chrony. - Do not run the aircraft receiver in a virtual machine. Multilateration often fails there (ultrafeeder README).
- Plug the RX-888 Mk II into a USB 3.0 socket on the PC itself. Never use a hub for it. At 64.8 MS/s it sends about 1 gigabit each second.
4. The radio-frequency chains
Build each chain in this order, antenna first.
A. Aircraft 1090 MHz vertical -- coax -- Pro Stick Plus
(the radio has its own amplifier and filter: add nothing)
B. Ships AIS vertical -- coax -- [Flamingo FM, optional] -- Airspy Mini
C. Messages discone -- coax -- FM band-stop filter -- 2-way splitter
|-- leg A -- Airspy R2 (ACARS)
`-- leg B -- RTL-SDR V4L (VDL2)
D. Shortwave loop -- RG-6 -- power injector -- F3060 (30 MHz low-pass in,
shelf filter bypassed) -- RF limiter -- RX-888 Mk II, HF input
The reasons for the order:
- Filter before splitter. One filter then cleans both legs.
- No amplifier on a short, direct run. Add one only to pay for a loss you have measured, and count messages before and after.
- Bias tee off on every radio behind the splitter and on the RX-888. A radio that puts DC on the cable can feed it into the other leg. The loop takes its power from its own injector.
- Injector first on the loop cable. Every part after it then sees no DC. The limiter blocks DC, so it must come after the injector.
- Low-pass filter before the limiter. A limiter makes harmonics when it clamps. TAPR’s manual says to filter ahead of it.
- Why the 30 MHz filter is not optional. At 64.8 million samples each second, the receiver cannot tell a signal above 32.4 MHz from one below it. A signal from 32 to 65 MHz folds back onto shortwave. The F3060 removes it: 36 dB down at 32.5 MHz and 64 dB down at 51 MHz, by its manual. It costs 3.7 dB at 28 MHz.
- Leave the F3060 shelf filter bypassed. It cuts 28 dB below 1 MHz and 20 dB at 3.5 MHz. Turn it on only if strong AM broadcast stations overload the receiver at night.
Put the antennas outside
This matters more than any part on the list. My ship antenna heard about 5 messages a minute indoors. The same radio and program heard about 30 a minute with a low-cost antenna on the roof. For the loop, height matters little. Distance from the electronics in the house matters a lot.
Ground the cables
An outdoor antenna cable needs a path to ground where it enters the building. In the US the rule is National Electrical Code Article 810. Bond the grounding block to the building’s own grounding electrode system. If you add a ground rod, bond it to that system with 6 AWG copper or heavier. Never use a rod that stands alone: a surge then goes through your equipment. I read a published summary of the rule, not the code text.9 Use a licensed electrician if you are not sure.
5. Accounts
Create these as each phase asks for them. All are free. Most give a paid-level account in return for your data.
| Network | Phase | What identifies your station | Where to sign up |
|---|---|---|---|
| adsb.fi, airplanes.live, ADS-B Exchange | 7 | <UUID>, no account |
Nothing to do |
| FlightAware | 7 | A feeder ID that the container prints | https://flightaware.com/adsb/piaware/claim |
| Flightradar24 | 7 | A sharing key from the sign-up command | Section 7 |
| Plane Finder, AirNav Radar, OpenSky Network, plane.watch | 7 | A share code, key, user name or API key | Each container’s README (section 19) |
| aiscatcher.org | 9 | Nothing: sharing is one setting | Nothing to do |
| MarineTraffic, AISHub, VesselFinder, ShipXplorer | 9 | A host and number that the network sends you | Each network’s “add a station” page |
| airframes.io | 10 | The station ID you choose | https://app.airframes.io |
| PSK Reporter, WSPRnet | 13, 14 | A callsign and a grid locator | Sections 13 and 14 |
| Discord | 8 | A channel webhook address | Channel, Edit Channel, Integrations, Webhooks |
Keep every key in a password manager. The compose file on vhf will hold them in plain text: do not publish that file.
6. Phase 1: prepare vhf
-
Write Raspberry Pi OS Lite (64-bit) to the card with Raspberry Pi Imager. In the Imager settings, set the host name to
vhf, turn SSH on, and add your public key. -
Start the Pi on wired Ethernet. Log in with SSH.
-
Update the system.
sudo apt update && sudo apt full-upgrade -y && sudo reboot -
Install Docker with the sdr-enthusiasts script. It also stops the kernel’s TV drivers from taking the RTL radios.
bash <(curl -s https://raw.githubusercontent.com/sdr-enthusiasts/docker-install/main/docker-install.sh) sudo reboot -
Check Docker and the driver block.
docker compose version cat /etc/modprobe.d/exclusions-rtl2832.conf # expect 9 "blacklist" lines lsmod | grep -c dvb_usb_rtl28xxu # expect 0 -
Install the Airspy tools and the clock service.
sudo apt install -y airspy chrony -
Connect the powered hub. Plug in one RTL radio at a time and write its serial number. Do the Pro Stick Plus first, then the V4L with
136.docker run --rm -it --device /dev/bus/usb --entrypoint rtl_eeprom \ ghcr.io/sdr-enthusiasts/docker-adsb-ultrafeeder -s 1090Change only the serial number. Do not change the maker or product text on an RTL-SDR Blog radio: its driver looks for that text. Then unplug every radio and plug it in again. A restart of the computer does not load the new serial numbers.
-
Plug in the two Airspy radios, one at a time, and read each factory serial number.
airspy_info | grep -i serialLabel each radio. Both Airspy models report the same USB identity (
1d50:60a1). Only the serial number tells them apart. -
Make the project folder. Every container in this guide goes into one compose file, so the containers can find each other by name.
sudo mkdir -p -m 777 /opt/station && cd /opt/station cat /proc/sys/kernel/random/uuid # this is <UUID> -
Create
/opt/station/.envwith your values.FEEDER_TZ=<TZ> FEEDER_LAT=<LAT> FEEDER_LONG=<LON> FEEDER_ALT_M=<ALT_M> FEEDER_NAME=<NAME> FEEDER_UUID=<UUID> ADSB_SDR_SERIAL=1090 VDL2_SDR_SERIAL=136 AIS_SDR_SERIAL=<SER_MINI> ACARS_SDR_SERIAL=<SER_R2> ACARS_STATION_ID=<STATION_ID>
7. Phase 2: aircraft (ADS-B)
Program: docker-adsb-ultrafeeder. One container owns the radio, decodes, draws the map and feeds the networks.
-
Create
/opt/station/docker-compose.yml.services: ultrafeeder: image: ghcr.io/sdr-enthusiasts/docker-adsb-ultrafeeder container_name: ultrafeeder hostname: ultrafeeder restart: unless-stopped device_cgroup_rules: - "c 189:* rwm" ports: - 8080:80 environment: - TZ=${FEEDER_TZ} - READSB_DEVICE_TYPE=rtlsdr - READSB_RTLSDR_DEVICE=${ADSB_SDR_SERIAL} - READSB_GAIN=auto - READSB_LAT=${FEEDER_LAT} - READSB_LON=${FEEDER_LONG} - READSB_ALT=${FEEDER_ALT_M}m - READSB_RX_LOCATION_ACCURACY=2 - ULTRAFEEDER_CONFIG= adsb,feed.adsb.fi,30004,beast_reduce_plus_out; adsb,feed.airplanes.live,30004,beast_reduce_plus_out; adsb,feed1.adsbexchange.com,30004,beast_reduce_plus_out; mlat,feed.adsb.fi,31090; mlat,feed.airplanes.live,31090; mlat,feed.adsbexchange.com,31090 - UUID=${FEEDER_UUID} - MLAT_USER=${FEEDER_NAME} - UPDATE_TAR1090=true - TAR1090_ENABLE_AC_DB=true volumes: - /opt/station/ultrafeeder/globe_history:/var/globe_history - /opt/station/ultrafeeder/graphs1090:/var/lib/collectd - /proc/diskstats:/proc/diskstats:ro - /dev/bus/usb:/dev/bus/usb tmpfs: - /run:exec,size=256MEach
ULTRAFEEDER_CONFIGline ends with a semicolon, except the last. The README lists more networks in the same form. -
Start it and check.
cd /opt/station && docker compose up -d docker ps --filter name=ultrafeeder # expect "(healthy)" after a few minutes curl -s http://localhost:8080/data/aircraft.json | head -c 300The map is at
http://vhf:8080/. The performance graphs are athttp://vhf:8080/graphs1090/. -
To hide the station mark on your own map, set
READSB_RX_LOCATION_ACCURACY=1(two decimal places) or0. The networks still receive the exact position.
More networks, one container each
Each of these reads the decoded stream from ultrafeeder at 30005/tcp and sends it to one network. Add each as a service in the same file. FlightAware and Flightradar24 show the pattern.
piaware:
image: ghcr.io/sdr-enthusiasts/docker-piaware:latest
container_name: piaware
restart: unless-stopped
environment:
- TZ=${FEEDER_TZ}
- RECEIVER_TYPE=relay
- BEASTHOST=ultrafeeder
- BEASTPORT=30005
- FEEDER_ID=${PIAWARE_FEEDER_ID}
- MLAT_RESULTS_BEASTHOST=ultrafeeder
- MLAT_RESULTS_BEASTPORT=31004
tmpfs:
- /run:exec,size=64M
- /var/log
fr24:
image: ghcr.io/sdr-enthusiasts/docker-flightradar24:latest
container_name: fr24
restart: unless-stopped
dns_search: .
environment:
- BEASTHOST=ultrafeeder
- FR24KEY=${FR24_KEY}
- MLAT=no
| Network | Image | Required settings | How to get the key |
|---|---|---|---|
| FlightAware | ghcr.io/sdr-enthusiasts/docker-piaware |
RECEIVER_TYPE=relay, BEASTHOST, FEEDER_ID |
timeout 30 docker run --rm ghcr.io/sdr-enthusiasts/docker-piaware:latest | grep "my feeder ID", then claim it on the FlightAware page |
| Flightradar24 | ghcr.io/sdr-enthusiasts/docker-flightradar24 |
BEASTHOST, FR24KEY |
docker run -it --rm --entrypoint /usr/bin/fr24feed ghcr.io/sdr-enthusiasts/docker-flightradar24:latest --signup --configfile=/tmp/config.txt |
| Plane Finder | ghcr.io/sdr-enthusiasts/docker-planefinder:5.0.161_arm64 on a Pi 5 |
BEASTHOST, SHARECODE, LAT, LONG |
See its README |
| AirNav Radar | ghcr.io/sdr-enthusiasts/docker-airnavradar |
BEASTHOST, LAT, LONG, ALT (meters, no unit), SHARING_KEY |
The first run prints a key in the log. On a Pi 5, read section 17 first |
| OpenSky Network | ghcr.io/sdr-enthusiasts/docker-opensky-network |
BEASTHOST, OPENSKY_USERNAME, OPENSKY_SERIAL, LAT, LONG, ALT |
The first run creates the serial. Save it, or each start makes a new station |
| plane.watch | ghcr.io/plane-watch/docker-plane-watch |
BEASTHOST, API_KEY, LAT, LONG, ALT |
https://atc.plane.watch |
Three rules from the ultrafeeder README:
- Never send multilateration results on to any network.
- If you feed several networks, leave multilateration off for Flightradar24 (
MLAT=no). They ask for this. - Set
FEEDER_IDfor FlightAware. Without it, each start creates a new site.
8. Phase 3: alerts for unusual aircraft
Program: docker-planefence. It keeps a log of aircraft that pass low and close. Its plane-alert part compares every aircraft with a public watch list, plane-alert-db.
-
Add two services to the compose file.
planefence: image: ghcr.io/sdr-enthusiasts/docker-planefence container_name: planefence hostname: planefence restart: unless-stopped ports: - 8088:80 - 9999:9999 environment: - TZ=${FEEDER_TZ} volumes: - /opt/station/planefence/config:/usr/share/planefence/persist - /opt/station/planefence/html:/usr/share/planefence/html tmpfs: - /run:rw,nosuid,nodev,exec,relatime,size=512M - /tmp:rw,nosuid,nodev,noexec,relatime,size=128M screenshot: image: ghcr.io/kx1t/screenshot container_name: screenshot hostname: screenshot restart: unless-stopped shm_size: 1gb environment: - MAP_ARGS=zoom=7&hideSidebar&hideButtons&mapDim=0.2&monochromeMarkers=ff0000&outlineColor=505050&iconScale=1.5&enableLabels&extendedLabels=2&trackLabels&screenshot&rangerings=0 - LOAD_SLEEP_TIME=25 - BASE_URL=http://ultrafeeder - MAXTIME=60 - CANVAS_SIZE=800,1200The host name of the second container must be
screenshot. Planefence looks for that name. -
Run
docker compose up -d. Then copyplanefence.config.RENAME-and-EDIT-metoplanefence.configin/opt/station/planefence/config/, or use the settings page athttp://vhf:9999/. -
Set these lines in
planefence.config.FEEDER_LAT=<LAT> FEEDER_LON=<LON> PF_SOCK30003HOST=ultrafeeder PF_MAXDIST=2.0 PF_MAXALT=5000 PF_ALERTLIST=https://raw.githubusercontent.com/sdr-enthusiasts/plane-alert-db/main/plane-alert-pia.csv,https://raw.githubusercontent.com/sdr-enthusiasts/plane-alert-db/main/plane-alert-db-images.csv PF_PA_SQUAWKS=7400,7500,7600,7700 PA_DISCORD=ON PA_DISCORD_WEBHOOKS=<your webhook address> PF_DISCORD=OFF DISCORD_FEEDER_NAME=<NAME> DISCORD_MEDIA=screenshot+photo PF_SCREENSHOTURL=http://screenshot:5042This file spells the longitude
FEEDER_LON. The.envfile spells itFEEDER_LONG. -
Apply and check.
docker compose up -d planefence --force-recreate docker exec planefence curl -s -o /tmp/t.png http://screenshot:5042/snap/<hex> # <hex> from aircraft.jsonThe log page is at
http://vhf:8088/. The alert page is athttp://vhf:8088/plane-alert.
Notes from my station:
- Lists match first to last. I put the list of aircraft that hide their identity (
plane-alert-pia.csv) first. - I keep
PF_DISCORD=OFF. With it on, every low aircraft near the house sends a message. zoom=7andLOAD_SLEEP_TIME=25are my values. At the default 15 seconds the map tiles had not loaded, and the picture was grey.DISCORD_FEEDER_NAMEappears in every alert. Do not put your town in it if the channel is shared.
9. Phase 4: ships (AIS)
Program: docker-shipfeeder, which runs AIS-catcher.
-
Add the service.
shipfeeder: image: ghcr.io/sdr-enthusiasts/docker-shipfeeder container_name: shipfeeder hostname: shipfeeder restart: unless-stopped environment: - SDR_TYPE=AIRSPY - RTLSDR_DEVICE_SERIAL=${AIS_SDR_SERIAL} - STATION_NAME=${FEEDER_NAME} - FEEDER_LAT=${FEEDER_LAT} - FEEDER_LONG=${FEEDER_LONG} - AISCATCHER_SHAREDATA=true # one line for each network, as each sends you its host and number: # - MARINETRAFFIC_UDP_PORT=<host>:<number> # - AISHUB_UDP_PORT=<host>:<number> # - VESSELFINDER_UDP_PORT=<host>:<number> # - SHIPXPLORER_UDP_PORT=<host>:<number> ports: - 90:80 device_cgroup_rules: - "c 189:* rwm" tmpfs: - /tmp volumes: - /opt/station/shipfeeder/data:/data - /dev:/dev:rwThe setting names say
RTLSDR, but they apply to an Airspy too whenSDR_TYPE=AIRSPY. LeaveSITESHOWunset: when set, the map shows your station as a dot. -
Start and check.
docker compose up -d docker logs shipfeeder 2>&1 | grep "Searching for device" # must name <SER_MINI>, not <SER_R2>The ship map is at
http://vhf:90/. Near salt water, the first messages arrive within minutes. -
Sign up with each network. Each one sends a host name and a number. Put them in the matching line, remove the
#, and rundocker compose up -dagain. -
For ShipXplorer on a Pi 5, choose “NMEA over UDP” when you add the station, and use
SHIPXPLORER_UDP_PORT. Its sharing-key program does not run on the standard Pi 5 kernel (section 17). Never set both methods.
10. Phase 5: aircraft messages (ACARS and VDL Mode 2)
Four containers: acarsdec and dumpvdl2 decode, acars_router removes duplicates and sends the messages on, and ACARS Hub stores and shows them. The HFDL lines are ready for section 12.
-
Choose
<STATION_ID>. The airframes.io form isXX-YYYY: your initials, then the code of the nearest large airport. This ID is public. -
Add the services.
acarsdec: image: ghcr.io/sdr-enthusiasts/docker-acarsdec:latest container_name: acarsdec restart: unless-stopped environment: - TZ=${FEEDER_TZ} - AIRSPY_SERIAL=${ACARS_SDR_SERIAL} - FEED_ID=${ACARS_STATION_ID}-ACARS - FREQUENCIES=130.025;130.425;130.450;131.125;131.550 - OUTPUT_SERVER=acars_router - OUTPUT_SERVER_PORT=5550 - OUTPUT_SERVER_MODE=udp tmpfs: - /run:exec,size=64M - /var/log device_cgroup_rules: - "c 189:* rwm" volumes: - /dev/bus/usb:/dev/bus/usb:ro dumpvdl2: image: ghcr.io/sdr-enthusiasts/docker-dumpvdl2:latest container_name: dumpvdl2 restart: unless-stopped environment: - TZ=${FEEDER_TZ} - RTL_SERIAL=${VDL2_SDR_SERIAL} - FEED_ID=${ACARS_STATION_ID}-VDL2 - GAIN=40 - FREQUENCIES=136.650;136.700;136.800;136.975 - ZMQ_MODE=server - ZMQ_ENDPOINT=tcp://0.0.0.0:45555 tmpfs: - /run:exec,size=64M - /var/log device_cgroup_rules: - "c 189:* rwm" volumes: - /dev/bus/usb:/dev/bus/usb:ro acars_router: image: ghcr.io/sdr-enthusiasts/acars_router:latest container_name: acars_router restart: unless-stopped ports: - 5556:5556/udp # HFDL arrives here from the hf computer environment: - TZ=${FEEDER_TZ} - AR_OVERRIDE_STATION_NAME=${ACARS_STATION_ID} - AR_ENABLE_DEDUPE=true - AR_RECV_ZMQ_VDLM2=dumpvdl2:45555 - AR_SKEW_WINDOW=30 - AR_SEND_UDP_ACARS=feed.airframes.io:5550 - AR_SEND_TCP_VDLM2=feed.airframes.io:5553 - AR_SEND_TCP_HFDL=feed.airframes.io:5556 tmpfs: - /run:exec,size=64M - /var/log:size=64M acarshub: image: ghcr.io/sdr-enthusiasts/docker-acarshub:latest container_name: acarshub restart: unless-stopped ports: - 8081:80 volumes: - /opt/station/acars_data:/run/acars tmpfs: - /database:exec,size=64M - /run:exec,size=64M - /var/log:size=64M environment: - TZ=${FEEDER_TZ} - ENABLE_ACARS=true - ACARS_CONNECTIONS=zmq://acars_router:45550 - ENABLE_VDLM=true - VDLM_CONNECTIONS=zmq://acars_router:45555 - ENABLE_HFDL=true - HFDL_CONNECTIONS=zmq://acars_router:45556 - ENABLE_ADSB=true - ADSB_URL=http://ultrafeeder/data/aircraft.json - ADSB_LAT=${FEEDER_LAT} - ADSB_LON=${FEEDER_LONG} -
Start and check.
docker compose up -d docker logs acarsdec 2>&1 | grep "Starting:" # must show --airspy <SER_R2> docker logs dumpvdl2 2>&1 | grep -i "detected" # a V4L must be named hereThe message log is at
http://vhf:8081/. Near a large airport, expect the first VDL2 messages in minutes. ACARS is slower and comes in bursts. -
Find your station on https://app.airframes.io by its ID.
Facts to know:
- Frequencies. These are the airframes.io lists for North America. An RTL radio covers about 2 MHz, so every channel of one decoder must fit in 2 MHz. The Airspy R2 covers more: I add 129.125 MHz to the ACARS list on mine.10 Always include 136.975 MHz, the worldwide calling channel for VDL2. Other regions use other lists.
AR_SKEW_WINDOW=30. The default is 5 seconds. HFDL messages arrive later than that and would be dropped.- Gain on an Airspy. I run acarsdec with the container’s default gain and it works. The decoder’s own README gives the Airspy a different gain scale (0 to 21). I did not compare the two.
- After you unplug the hub, run
docker restart acarsdec. On my station the two Airspy radios come back in a race, and acarsdec can hold the wrong one. Then both feeds stop.
11. Phase 6: prepare hf and the receiver
Receiver program: ka9q-radio. Its radiod service reads the whole of shortwave from the RX-888 Mk II and gives each decoder its own channel over the computer’s internal network. Nothing here uses Docker.
The project changes every week, and some of its documents are behind the code. These steps build the same version that my station runs (commit b5bbb9aa, 2026-09-25). The project now also offers ready-made packages for Ubuntu 24.04. I have not used them.
-
Install Ubuntu Server 24.04 LTS. Set the host name to
hf. Turn SSH on. Use wired Ethernet. -
In the PC’s firmware settings, set it to start again after a power cut. A UPS rides through a short cut; this setting covers a long one.
-
Add the author’s package source. Two of the libraries are only there.
sudo wget -P /usr/share/keyrings http://www.ka9q.net/debian/ka9q-radio.asc echo "deb [signed-by=/usr/share/keyrings/ka9q-radio.asc arch=amd64] http://www.ka9q.net/debian noble main" \ | sudo tee /etc/apt/sources.list.d/ka9q.list sudo apt update -
Install the build tools and libraries (the list is from the project’s
docs/INSTALL.md).sudo apt install -y git avahi-utils build-essential make gcc libairspy-dev libairspyhf-dev \ libbsd-dev libfftw3-dev libfftw3-bin libhackrf-dev libiniparser-dev libncurses-dev libopus-dev \ librtlsdr-dev libusb-1.0-0-dev libusb-dev portaudio19-dev libasound2-dev rsync libogg-dev \ libsamplerate0-dev libliquid-dev libncursesw5-dev libbladerf-dev libhydrasdr-dev libfobos-dev \ libcsv-dev libsoapysdr-dev chrony -
Build and install.
cd ~ && git clone https://github.com/ka9q/ka9q-radio.git && cd ka9q-radio git checkout b5bbb9aa make -j && sudo make install sudo adduser $(whoami) radio sudo systemctl enable --now set_lo_multicastThe install creates the user and group
radio, the service files, and the rules that load the receiver’s firmware when you plug it in. Log out and in again so the new group applies. -
Connect the chain from section 4. Plug the RX-888 Mk II into a USB 3.0 socket on the PC. Check it.
lsusb | grep 04b4 # expect 04b4:00f1 "RX888mk2". 00f3 means the firmware did not load lsusb -t | grep -B2 usbfs # the receiver's line must end in 5000M -
Write the receiver settings. Start from the project’s example.
sudo cp ~/ka9q-radio/config/examples/radiod@rx888-generic.conf /etc/radio/radiod@hf.conf sudoedit /etc/radio/radiod@hf.confSet these lines in the first two sections. Leave the rest as it is for now.
[global] hardware = rx888 status = hf.local [rx888] device = "rx888" description = "<STATION_ID>-HFDL" samprate = 64m8 gain = 10Always write
samprate = 64m8. One of the project’s default files uses the full rate, which makes more heat and needs a faster PC. Thedescriptiontext is sent to airframes.io as your HFDL station name. -
Make the speed tables for this PC. This took 36 minutes on my Core i5-4570.
radiodmust not run during it.cd /etc/fftw && sudo touch nwisdom && sudo chown $(whoami):radio nwisdom wisdomf 2>/dev/null time fftwf-wisdom -v -T 1 -o nwisdom rof1620000 cob1920 cob1200 cob960 cob800 cob600 \ cob480 cob320 cob300 cob200 cob160 cob150 ls -l nwisdom && cp nwisdom wisdomfDo not leave out
-T 1. Do not copy the file from another computer. -
Start the receiver and look at it.
sudo systemctl enable --now radiod@hf systemctl is-active radiod@hf # expect "active" control hf.local # the live panel. Press q to leaveThe service name is
radiod@hf, notradiod@hf.conf. -
Set the gain. In the panel, read the level of the analog-to-digital converter. The project’s rule is an average of -20 to -25 dBFS. I run 10 dB of gain, which gives about -32 dBFS here and leaves room for strong stations at night. A count of “overranges” that keeps rising means too much gain.
-
Test that the antenna, not the receiver, sets the noise. Note the noise level on a quiet frequency. Replace the antenna cable with the 50 ohm terminator. The noise must fall by 6 dB or more. On my station it fell by 30 to 40 dB. If it does not fall on some band, an amplifier may help on that band, and a filter will not.
-
Keep the receiver in its case, and keep air around it. It runs hot.
12. Phase 7: aircraft over the oceans (HFDL)
Decoder: dumphfdl. The hfdl service of ka9q-radio starts one copy for each of 12 bands.
-
Build dumphfdl. Ubuntu 24.04 has no package for it.
sudo apt install -y cmake pkg-config libglib2.0-dev libconfig++-dev libacars2-dev cd ~ && git clone https://github.com/szpajder/dumphfdl.git && cd dumphfdl git checkout v1.7.0 mkdir build && cd build && cmake ../ && make && sudo make install dumphfdl --version # expect 1.7.0 -
Give
radiodthe 12 HFDL channels. In/etc/radio/radiod@hf.conf, add the linedisable = yesto the section[HFDL]. Then add the project’s HFDL file at the end.cat ~/ka9q-radio/config/examples/fragments/hfdl.conf | sudo tee -a /etc/radio/radiod@hf.conf >/dev/null sudo systemctl restart radiod@hf -
Make the helper send each message to the router on
vhf, not straight to airframes.io. Work on a copy, so a later install does not undo it.sudo cp /usr/local/sbin/start-hfdl /usr/local/sbin/start-hfdl-local sudo sed -i 's/decoded:json:tcp:address=feed.airframes.io,port=5556/decoded:json:udp:address=vhf.local,port=5556/' \ /usr/local/sbin/start-hfdl-local grep -c "udp:address=vhf.local" /usr/local/sbin/start-hfdl-local # expect 1If
hfcannot find the namevhf.local, use the fixed address ofvhf. -
Point the service at the copy. Run
sudo systemctl edit hfdland enter these three lines.[Service] ExecStart= ExecStart=/usr/local/bin/pcmrecord --raw -v --exec "/usr/local/sbin/start-hfdl-local \"$k\" \"$d\" \"$r\"" ${MCAST} -
Set the decoder’s location and give it the ground-station table. In
/etc/radio/hfdl.conf, change theDUMPHFDLline toDUMPHFDL=/usr/local/bin/dumphfdl.sudo install -D -o radio -g radio -m 664 ~/dumphfdl/etc/systable.conf /var/lib/hfdl/systable.conf sudo systemctl enable --now hfdl tail -f /var/log/hfdl.log -
Check on
vhf: the HFDL list of ACARS Hub fills. My first message came 20 minutes after the first start, with the loop indoors. Low bands carry traffic at night and high bands by day.
To skip the router, leave out steps 3 and 4. The messages then go to airframes.io only.
13. Phase 8: amateur stations (FT8 and FT4)
Decoder: decode_ft8 from ka9q/ft8_lib. Uploader: ftlib-pskreporter. The method is in the project’s docs/ft8.md.
-
Build the decoder.
cd ~ && git clone https://github.com/ka9q/ft8_lib.git && cd ft8_lib make && sudo make install ls /usr/local/bin/decode_ft8 -
Give
radiodthe channels. In/etc/radio/radiod@hf.conf, adddisable = yesto the section[FT8]. Then add the two files.cd ~/ka9q-radio/config/examples/fragments cat ft8.conf ft4.conf | sudo tee -a /etc/radio/radiod@hf.conf >/dev/null -
In the lines you added, and in the section
[WSPR], delete every frequency above 30 MHz (50.310, 50.318, 50.293 and 144.489 MHz). The receiver cannot hear them at this rate. It would report false stations. -
Start the recorders and decoders.
sudo systemctl restart radiod@hf sudo systemctl enable --now ft8-record ft4-record ft8-decode@1 ft4-decode@1 tail -f /var/log/ft8.log # new lines every 15 seconds on an open band -
Optional: report what you hear to PSK Reporter.
cd ~ && git clone https://github.com/pjsg/ftlib-pskreporter.git && cd ftlib-pskreporter sudo apt install -y python3-docopt sudo install -m 755 pskreporter-sender /usr/local/bin/ sudo install -m 644 pskreporter.py /usr/local/lib/python3.12/dist-packages/ sudo cp pskreporter@.service /etc/systemd/system/ sudo cp ft8-pskreporter.conf ft4-pskreporter.conf /etc/radio/ sudoedit /etc/radio/ft8-pskreporter.conf /etc/radio/ft4-pskreporter.conf # CALLSIGN, LOCATOR, ANTENNA sudo systemctl daemon-reload && sudo systemctl enable --now pskreporter@ft8 pskreporter@ft4 sudo ss -tnp | grep 4739 # an open connection means it uploads
Facts to know:
- No licence is needed to report. PSK Reporter says a listener can pick a name with the country prefix, such as
W/SWL/BOSTON. I hold a licence and report with my callsign and a number after a dash. That keeps the receiver apart from my transmitting station. - The locator is public and needs 6 characters. That places you within a few kilometers. The antenna text is public too.
- The reports carry no signal strength. The decoder’s number is a score, not a measurement.
- The recorders write short sound files all day. That is why
hfhas a solid-state drive.
14. Phase 9: low-power beacons (WSPR)
Decoder: wsprd, from the WSJT-X package. ka9q-radio’s wspr-decoded service records two minutes on each band and runs it.
-
Install the decoder.
sudo apt install -y wsjtx ls /usr/bin/wsprd -
Make the two names agree. Find the
data =line in the section[WSPR]of/etc/radio/radiod@hf.conf. Put the same name afterMCAST=in/etc/radio/wspr-decode.conf. On my station they did not match after the install, and nothing was decoded. -
Start it.
sudo systemctl enable --now wspr-decoded grep -v DecodeFinished /var/log/wspr.log | tail # lines with a time, a level in dB, a frequency, a callsignExpect about 10 stations an hour at night on an indoor loop, and far more outdoors.
-
To report: ftlib-pskreporter has a
wspr-pskreporter.confthat sends these to PSK Reporter in the same way as step 5 of section 13. I have not tested it. For reports to WSPRnet, the usual public program is wsprdaemon. It installs and manages its own copy of ka9q-radio, so do not add it to this build without a plan. I upload with a small program of my own.
15. Other signals: what I receive with my own programs
On the same receiver I also decode the signals below. I wrote those programs for my own station and they are not public. Each one asks ka9q-radio for one more channel and reads the sound from it. This table names a free public program for each job, and says so where I found none that runs without a screen.
| Signal | Frequencies | Free public program | Limits |
|---|---|---|---|
| Weather fax, US Coast Guard station NMC | 4346, 8682, 12786, 17151.2, 22527 kHz. Tune 1.9 kHz lower, upper sideband | fldigi (WEFAX mode), or Isobar, which decodes a recording from the command line | fldigi needs a screen and a sound input. Isobar is a new project, and I have not tested it |
| NAVTEX warnings for ships | 518 kHz | fventuri/navtex, which reads a sound stream with no screen, or fldigi | Mostly a night signal here. Keep the F3060 shelf filter bypassed |
| SSTV pictures from amateurs | 14.230, 21.340, 28.680 MHz | QSSTV | Needs a screen. colaclanth/sstv decodes one recording at a time, in fewer modes |
| DSC distress and calling | 2187.5, 4207.5, 6312, 8414.5, 12577, 16804.5 kHz | SDRangel, or YaDD on Windows | I found no free public decoder for Linux that runs without a screen |
| NCDXF/IARU beacons | 14.100, 18.110, 21.150, 24.930, 28.200 MHz | Faros, on Windows, $25 after a 30-day trial | ka9q-radio includes a channel file for these (ibp.conf), but no program that measures them |
| US Air Force voice messages (HFGCS) | 4724, 8992, 11175, 15016 kHz, upper sideband. Hobby lists add 6739 and 13200 | pcmrecord from ka9q-radio to record, then whisper.cpp or faster-whisper to make text |
I found no finished public program that does both |
| The sun’s effect on very low frequencies | 24.8 kHz (NLK) and other navy transmitters | SuperSID, with NOAA’s X-ray data to compare | SuperSID reads a sound card. I did not confirm that it can read an SDR |
| One screen for the whole station | Homepage with docker-socket-proxy (read-only) shows which containers are healthy | Never open the proxy to the internet |
16. Final checks
Run these after the last phase. Each line is one feed.
| Feed | Check on | Command or page | Pass |
|---|---|---|---|
| Aircraft | vhf |
docker ps --filter name=ultrafeeder |
(healthy) |
| Aircraft | browser | http://vhf:8080/ |
Aircraft on the map |
| Alerts | Discord | The screenshot test in section 8 | A picture with a map |
| Ships | browser | http://vhf:90/ |
Ships on the map |
| Ships | vhf |
docker logs shipfeeder 2>&1 | grep "Searching for device" |
Names <SER_MINI> |
| ACARS, VDL2 | browser | http://vhf:8081/ |
New messages in both lists |
| HFDL | browser | http://vhf:8081/ |
Messages in the HFDL list. Night and day use different bands |
| Receiver | hf |
systemctl is-active radiod@hf |
active |
| FT8, WSPR | hf |
tail /var/log/ft8.log /var/log/wspr.log |
New lines every 15 seconds and every 2 minutes |
| USB | both | lsusb -t |
The RX-888 at 5000M. No radio missing |
Then write down the message rate of every feed for one normal day. That number is your baseline. Change one thing at a time, and compare with it.
17. Known traps
Each of these cost me time.
| Symptom | Cause | What to do |
|---|---|---|
usb_claim_interface error -6, “Device or resource busy” |
The kernel’s TV driver took an RTL radio | Check step 5 of section 6. Restart the computer |
| The ship feed stops when the ACARS decoder starts, or the reverse | Two Airspy radios with one USB identity, and a decoder that opened “the first one” | Give every container its radio’s serial number. Never leave one unset |
| After the hub was unplugged: no ACARS, and the ship log repeats “cannot open device” | acarsdec holds the wrong Airspy | docker restart acarsdec |
| An RTL-SDR Blog V4L opens, the container is “healthy”, and it decodes nothing | A driver older than August 2026 does not know its tuner | docker compose pull && docker compose up -d. The log must name the V4L |
| Fewer messages after you add an amplifier | The strong signals now overload the radio, and the weak ones are lost | Remove it. On my station a 20 dB amplifier cut ACARS from 95 to 42 messages an hour |
| AirNav Radar or the ShipXplorer key program stops at once on a Pi 5 | Those programs need 4 kB memory pages. getconf PAGE_SIZE shows 16384 |
Add kernel=kernel8.img to /boot/firmware/config.txt and restart. For ShipXplorer, the UDP method avoids this |
| Plane Finder fails on a Pi 5 | Same kind of problem | Use the image tag 5.0.161_arm64 (sdr-enthusiasts guide) |
| A new FlightAware or OpenSky station appears at every start | The feeder ID or serial is not in the compose file | Save it in the file after the first run |
| The alert picture is a grey map | The map tiles had not loaded | Raise LOAD_SLEEP_TIME |
| Shortwave is full of signals that should not be there | No 30 MHz low-pass filter, so signals above 32.4 MHz fold back | Fit the filter (section 4) |
radiod reports dropped data |
The RX-888 is on a hub or a USB 2 socket | Use a USB 3.0 socket on the main board |
| The loop has no signal, or a radio behind the splitter runs hot | DC is wrong: the limiter blocks it, or a bias tee is on | Injector first on the loop cable. Bias tee off everywhere else |
| NAVTEX and the low bands are weak | The F3060 shelf filter is on | Bypass it |
| A decoder for 22.5 kHz hears nothing | In ka9q-radio, 22500 means 22.5 MHz |
Write 22k5 |
18. Law and manners
- I am not a lawyer. This is what I read, for the United States. Other countries differ.
- US law (47 U.S.C. section 605) says that a person who receives a radio message not meant for the public must not tell others its contents, or use it for gain. It makes exceptions for broadcasts to the public, for amateur and CB radio, and for messages about ships, aircraft or people in distress.
- So I show that a message arrived, and what kind it was. I do not publish the text of real aircraft messages.
- Each network has terms for the data it gives back to you. Read them before you republish a map or a list.
- A feeder station is a small public service. Keep it running, keep its clock right, and keep its position honest.
19. Sources
Every repository and page that this guide depends on. All were read on 2026-10-07.
Host preparation. sdr-enthusiasts guide: https://sdr-enthusiasts.gitbook.io/ads-b. Install script: https://github.com/sdr-enthusiasts/docker-install.
Aircraft. https://github.com/sdr-enthusiasts/docker-adsb-ultrafeeder · https://github.com/sdr-enthusiasts/docker-piaware · https://github.com/sdr-enthusiasts/docker-flightradar24 · https://github.com/sdr-enthusiasts/docker-planefinder · https://github.com/sdr-enthusiasts/docker-airnavradar · https://github.com/sdr-enthusiasts/docker-opensky-network · https://github.com/plane-watch/docker-plane-watch
Alerts. https://github.com/sdr-enthusiasts/docker-planefence · https://github.com/sdr-enthusiasts/plane-alert-db · https://github.com/kx1t/browser-screenshot-service
Ships. https://github.com/sdr-enthusiasts/docker-shipfeeder · https://github.com/jvde-github/AIS-catcher
Aircraft messages. https://github.com/sdr-enthusiasts/docker-acarsdec · https://github.com/f00b4r0/acarsdec · https://github.com/sdr-enthusiasts/docker-dumpvdl2 · https://github.com/szpajder/dumpvdl2 · https://github.com/sdr-enthusiasts/acars_router · https://github.com/sdr-enthusiasts/docker-acarshub · https://docs.airframes.io
Shortwave. https://github.com/ka9q/ka9q-radio (read docs/INSTALL.md, docs/SDR/rx888.md, docs/FFTW3.md, docs/hfdl.md, docs/ft8.md) · https://github.com/szpajder/dumphfdl · https://github.com/ka9q/ft8_lib · https://github.com/pjsg/ftlib-pskreporter · https://github.com/rrobinett/wsprdaemon · Heat in the RX-888: https://ka7oei.blogspot.com/2023/08/improving-thermal-management-of-rx-888.html
Parts. The maker or seller page linked from each row of section 2. Filter figures: the Turn Island F3060 manual and the TAPR RF Limiter manual.
Rules. 47 U.S.C. 605: https://www.law.cornell.edu/uscode/text/47/605. Weather fax schedule: https://www.weather.gov/media/marine/rfax.pdf. NAVTEX: https://www.navcen.uscg.gov/navtex-maritime-safety-broadcasts. DSC frequencies: https://www.law.cornell.edu/cfr/text/47/80.359. Beacons: https://www.ncdxf.org/beacon/.
What I could not confirm
- That 4 GB is enough for
vhf. I measured an 8 GB Pi 5. - The connector of the low-cost AIS antenna, and its price on the day. Read the listing.
- That the Mini-Circuits splitter passes or blocks DC. Its data sheet does not say. So keep every bias tee off.
- The best gain setting for acarsdec on an Airspy R2.
- The Airspy prices at the maker. Its site did not answer that day, so the prices are the US distributor’s.
- The price of the RX-888 Mk II. I found no seller page I could read. The maker warns of copies and names the sellers it trusts: read https://www.rx-888.com before you buy.
- That the newest ka9q-radio builds with these exact steps. I built the commit named in section 11.
- The ready-made ka9q-radio packages, the WSPR path to PSK Reporter, Isobar, and every program in section 15. I have not run them.
- The rule of WSPRnet for a listener with no callsign. Its site did not answer.
- No step in this guide was run on a new, empty computer as written. The settings are the ones on my station, checked against each project’s documents.
Footnotes
-
My aircraft radio is on a Raspberry Pi 4 with FlightAware’s own PiAware system. A small server (an Intel Atom E3950 with 16 GB) runs ultrafeeder, the other feeder containers and planefence, and reads the Pi 4 over the network. A Raspberry Pi 5 with 8 GB runs the ship and message containers. An HP EliteDesk 800 G1 runs the shortwave receiver. I built it in that order, one part at a time. One Pi 5 for all of the first three is simpler, and section 3 gives the numbers I have for it. ↩
-
I started with a small whip indoors, then put a low-cost AIS-band vertical on the roof. The rate went up about six times. A marine-grade antenna is a later step, if at all. ↩
-
My loop is still indoors, near the computer, and that is the worst place for it. I own a second one as a spare. The amplifier in the loop head is the part most open to static. ↩
-
I added it and the message rate did not change. I left it in as cheap protection. On the wide discone, the FM filter is not optional. ↩
-
I bought mine from a surplus dealer. I have not measured what the split costs me in messages. ↩
-
I transmit on shortwave from the same property, at 5 to 20 watts. The limiter is there for that, and for static. If you never transmit, it is still cheap insurance for an expensive receiver. ↩
-
For ships, ACARS and VDL2, three RTL-SDR radios do the job in place of the two Airspy radios: set
RTL_SERIALin place ofAIRSPY_SERIALfor acarsdec, and leaveSDR_TYPEunset for shipfeeder. I ran VDL2 on a Nooelec NESDR SMArt v5 for six weeks. I use the Airspy radios because I owned them. ↩ ↩2 -
I use and recommend the RX-888 Mk II because it hears all of shortwave at once, so every decoder runs all day. A narrow radio hears one slice. An Airspy HF+ Discovery (768 kHz wide) can run dumphfdl on one HFDL band at a time. The dumphfdl README also calls the RTL-SDR Blog V4 a decent low-budget choice; I have not tried its replacement, the V4L, on shortwave. That is a real station, at a fraction of the cost. It is not the build in sections 11 to 14. ↩
-
Mike Holt’s summary of NEC 810.21, 2020 edition: https://www.mikeholt.com/files/PDF/20BG_810.21.pdf. ↩
-
My six ACARS channels run from 129.125 to 131.550 MHz. That is wider than 2 MHz, and it works on the Airspy R2. My VDL2 list has eight channels from 136.650 to 136.975 MHz, which includes channels that airframes.io lists for Europe. I have not checked which of the eight carry traffic here. ↩