# Shortwave

At the end you have one receiver that hears every shortwave band at the same moment. It gives each program its own channel, and you hear a time signal from it. My other shortwave guides build on this one.

Spurious Emissions · Rev A · checked 2026-10-10 · https://spurious-emissions.net/guides/shortwave-receiver/

Some links are affiliate links: if you buy through them, I may earn a commission at no extra cost to you. As an Amazon Associate I earn from qualifying purchases.

## 1. What this guide builds

One receiver measures the antenna voltage 64.8 million times each second. So every signal below 30 MHz is in one stream of numbers. A program on an x86 PC cuts that stream into many channels, and each channel is a small stream that any program can read.

| Signal | Frequency | Antenna | Radio | Decoder | Computer |
|---|---|---|---|---|---|
| All of shortwave, and the bands below it | 0 to 30 MHz | Small active loop, outdoors | RX-888 Mk II, HF input | None in this guide: ka9q-radio makes the channels | `hf`, an x86 PC |
| First test signal: the WWV time signal | 2.5, 5, 10, 15, 20, 25 MHz | The same | The same | Your ears | The same |

This guide stops at a working receiver and one channel that you hear. The decoders are in my other guides: aircraft over the oceans (HFDL), WSPR and FT8, weather by radio, the other shortwave signals, and the sun. Each one adds channels to the receiver that you build here.

```
 outdoors                 cable entry                                  the PC named hf
 --------                 -----------                                  ---------------
 loop with      RG-6      power       30 MHz        RF         RX-888 Mk II      radiod (ka9q-radio)
 amplifier ----------- injector --- low-pass --- limiter --- HF input ---- USB 3 --- one stream, 0 to 30 MHz
 in its head            (DC goes     filter                  (own USB 3            |
                         up the                               socket, no hub)      +-- channel -- program
                         cable)                                                    +-- channel -- program
                                                                                   +-- channel -- your ears
```

Three terms that this guide uses:

- **Direct sampling.** The receiver does not tune. It measures the antenna voltage directly, and software selects the signals later.
- **Channel.** One slice of the stream: a frequency, a mode and a width. ka9q-radio makes many channels at the same time.
- **Multicast group.** A network address that a program can subscribe to. Each group of channels goes to one such address. One more subscriber costs the receiver nothing.

## 2. What you need

A part marked ◆ is what I use. A blank box is for your pencil. Prices are US dollars unless the cell says otherwise. Each price has its seller and the date I read it.

### Antenna

| ☐ | Part | Job | Connector | Price | Note |
|---|---|---|---|---|---|
| ☐ | ◆ [MLA-30+ active loop](https://www.amazon.com/dp/B095K89WND?tag=spuriousemiss-20) with its power injector | Receives 0 to 30 MHz | SMA | See listing, Amazon, 2026-10-07. See the listing for a US price | The amplifier is in the loop head. The injector sends its power up the signal cable |
| ☐ | A mast, a post or a bracket | Holds the loop | | See seller | Section 4 says where |

### Filter and protection

| ☐ | Part | Job | Price | Note |
|---|---|---|---|---|
| ☐ | ◆ [Turn Island Systems F3060](https://turnislandsystems.com/product/f3060-filter-shelf-30-60-mhz-lpf/) low-pass filter | Removes every signal above 30 MHz before the receiver | $80, Turn Island Systems, 2026-10-10 | Required at 64.8 million samples each second. Section 5 says why |
| ☐ | ◆ [TAPR RF Limiter](https://tapr.org/product/rf-limiter/) | Last part before the receiver. Limits strong signals to less than +10 dBm | $20, TAPR, 2026-10-10 | Needed if you also transmit. Cheap insurance if you do not[^limiter] |

### Radio

| ☐ | Part | Job | Price | Note |
|---|---|---|---|---|
| ☐ | ◆ [RX-888 Mk II](https://opensourcesdrlab.com/products/rx888-mkii-16bit-sdr-receiver-radio-ltc2208-adc-upgrade-rx888?DIST=QU5PHQ%3D%3D), 16-bit, 10 kHz to 64 MHz direct | Measures the whole antenna signal | $152.79, OpenSourceSDRLab, 2026-10-11, 2026-10-07 | Counterfeit units exist. The maker's page has a purchase link: use it |

### Computer

| ☐ | Part | Job | Price | Note |
|---|---|---|---|---|
| ☐ | ◆ 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) | `hf` | Used market | Requirements in section 6 |
| ☐ | SATA solid-state drive, 120 GB or more | Storage for `hf` | See seller | The decoders in the later guides write files all day |
| ☐ | Ethernet cable to your router or switch | Network for `hf` | See seller | Do not use Wi-Fi for this computer |

### Cable and small parts

| ☐ | Part | Job |
|---|---|---|
| ☐ | RG-6 quad-shield coax, and two F to SMA adapters | Loop to the injector. On shortwave, 10 to 20 m of it loses under 1 dB |
| ☐ | Short SMA plug-to-plug jumpers, 3 or more | Injector to filter to limiter to receiver |
| ☐ | Snap-on ferrites | Both ends of the loop cable, and the USB cable |
| ☐ | Grounding block for the cable where it enters the house, and bonding wire | Section 4, "Ground the cable" |
| ☐ | 50 ohm SMA terminator | The noise test in section 11 |
| ☐ | The USB 3 cable that comes with the receiver | Receiver to `hf` |

### Lowest-cost path

Section 15 gives the steps and the limits. It is a different station: one tuned radio that hears one slice at a time.

| ☐ | Part | Job | Price | Note |
|---|---|---|---|---|
| ☐ | [RTL-SDR Blog V4L](https://www.rtl-sdr.com/buy-rtl-sdr-dvb-t-dongles/) | A tuned radio. The seller lists a built-in converter for shortwave | $37.95, rtl-sdr.com, 2026-10-10 | I have not tried it on shortwave |
| ☐ | Airspy HF+ Discovery | A tuned radio for shortwave, 768 kHz wide in ka9q-radio | Not checked | The radio I first planned to use. I give no link, because I checked no listing |
| ☐ | Any antenna you own for shortwave, or the loop above | | | The antenna rules in section 4 are the same |
| ☐ | The computer you own | Runs one SDR program | | |

## 3. Before you start

**Skills.** You connect coax parts with SMA connectors. You install Linux on a PC from a USB stick. You type commands in a terminal over SSH and edit a text file. No soldering is necessary.

**Time.** I give no total, because I did not time my build. One step has a known length: the speed tables in section 10 took 36 minutes on my PC. The ka9q-radio documents say that step can take hours.

**Accounts.** None. Nothing in this guide sends data to the internet.

**Values to choose first.**

| Placeholder | Meaning | Example form |
|---|---|---|
| `<NAME>` | A short text that describes the receiver. It contains no personal detail | `loop on the fence` |
| `<IFACE>` | The name of the wired network interface of `hf`. Only section 13 uses it | from `ip address show` |

The computer has the name `hf` in this guide. The receiver instance also has the name `hf`. So the service is `radiod@hf` and the control address is `hf.local`.

**The law.** This guide receives only. It tells you to transmit nothing. I am not a lawyer, and this is what I read for the United States. 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. It makes exceptions for broadcasts to the public, for amateur and CB radio, and for messages about ships, aircraft or people in distress. Other countries differ.

## 4. The antenna

The antenna is a small loop with an amplifier in its head. I use the MLA-30+. Power reaches the amplifier through the signal cable, from a small box named a power injector.

### Where the loop must stand

1. Put the loop outdoors.
2. Put it as far from the electronics in your house as you can. Power supplies, network gear, lamps and computers make most of the noise on shortwave.
3. Do not buy a tall mast for it. For a loop like this, height matters little.
4. Keep it away from metal fences and gutters if you can.
5. Mount it so that you can turn it by hand. A small loop has a null, and you can turn the null toward a noise source.

Distance is the rule that matters. The designer of one well-known loop amplifier says to put the antenna at least several meters from electrical equipment. He ran his own tests with the loop center about 2 m above the ground.[^lz1aq]

My own loop is still indoors, next to the computer. That is the worst place for it. Even there, the antenna noise is 20 to 30 dB above the receiver's own noise. So the receiver is not the limit. The location of the antenna is the limit.

### Run the cable

1. Connect the RG-6 cable to the loop head with an F to SMA adapter.
2. Put one snap-on ferrite on the cable near the loop head.
3. Run the cable to the place where it enters the house.
4. Put one snap-on ferrite on the cable near the indoor end.

Result: one cable from the loop reaches the receiver's location. 10 to 20 m of RG-6 loses under 1 dB on shortwave.

### Ground the cable

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.[^nec] Use a licensed electrician if you are not sure.

## 5. The radio-frequency chain

Build the chain in this order, antenna first.

```
loop -- RG-6 -- power injector -- F3060 (30 MHz low-pass in,
        shelf filter bypassed) -- RF limiter -- RX-888 Mk II, HF input
```

> **Caution.** Direct current on the wrong part can damage it or stop the signal. Put the power injector first on the loop cable. Add no second source of direct current. The ka9q-radio document for this receiver lists no setting for a bias tee.

1. Connect the loop cable to the antenna side of the power injector.
2. Connect the radio side of the power injector to the input of the F3060.
3. Set the F3060 to its 30 MHz low-pass filter.
4. Set the F3060 shelf filter to bypass. The F3060 manual shows how.
5. Connect the output of the F3060 to the RF limiter.
6. Connect the RF limiter to the HF input of the RX-888 Mk II.
7. Connect the power supply of the injector last.

Result: the loop has power, and no direct current reaches the filter, the limiter or the receiver.

The reasons for the order:

- **Injector first.** Every part after it then sees no direct current. I treat the limiter as a part that blocks it.
- **Low-pass filter before the limiter.** A limiter is a diode, and it makes spurious signals when it clamps. TAPR says to filter ahead of it.
- **The 30 MHz filter is not optional.** The receiver takes 64.8 million samples each second. So it cannot tell a signal above 32.4 MHz from one below it. A signal from 32.4 to 64.8 MHz folds back onto shortwave. The receiver's own filter is at 64 MHz, so it does not help.
- **What the F3060 does.** By its manual, it is 36 dB down at 32.5 MHz and 64 dB down at 51 MHz. It costs 3.7 dB at 28 MHz.
- **Leave the 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.
- **No amplifier.** The loop has one. Add another only to pay for a loss that you measured.

Keep the receiver in its case, and keep air around it. It runs hot.

## 6. The computer

I can only state what I measured. The table says which numbers are mine and which are the project's.

| Requirement | I recommend | Where the number comes from |
|---|---|---|
| Processor | x86-64, 4 cores of Intel Haswell class (2013) or newer | My Core i5-4570 (4 cores, 2013) ran about 150 channels and dropped no data in a 19-hour test |
| Memory | 8 GB | Memory in use on mine was under 2.5 GB |
| USB | A USB 3.0 socket on the main board. No hub | At 64.8 million 16-bit samples each second, the receiver sends about 1 gigabit each second |
| Storage | A solid-state drive | The decoders in the later guides write files all day |
| System | Ubuntu Server 24.04 LTS | What my station runs |
| Network | Wired Ethernet | Section 13 |

The ka9q-radio documents say that a Raspberry Pi 5 can also run this receiver at 64.8 million samples each second, "but just barely". They say that it leaves little for decoders. I did not test a Pi 5. That is why this guide uses an x86 PC.

### Prepare the PC

1. Install Ubuntu Server 24.04 LTS. Set the host name to `hf`. Turn SSH on.
2. Connect `hf` to your router or switch with an Ethernet cable.
3. In the PC's firmware settings, set it to start again after a power cut.
4. Give `hf` a fixed address on your network, set on the computer itself.
5. Log in with SSH and update the system.

   ```bash
   sudo apt update && sudo apt full-upgrade -y && sudo reboot
   ```

   Result: the PC starts again, and you can log in with `ssh <you>@hf.local` or with its fixed address.

## 7. Install ka9q-radio

Receiver program: [ka9q-radio](https://github.com/ka9q/ka9q-radio), by Phil Karn. It is free and open source (GPL-3.0). Its `radiod` service reads the whole stream from the receiver and makes the channels. 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 also offers ready-made packages. I have not used them.

1. Add the author's package source. Two of the libraries are only there.

   ```bash
   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
   ```

   Result: `apt update` ends with no error about `ka9q.net`.

2. Install the build tools and libraries. The list is from the project's `docs/INSTALL.md`, plus the FFT tools and the clock service.

   ```bash
   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
   ```

3. Build and install.

   ```bash
   cd ~ && git clone https://github.com/ka9q/ka9q-radio.git && cd ka9q-radio
   git checkout b5bbb9aa
   make -j && sudo make install
   ```

   Result: the programs `radiod` (in `/usr/local/sbin`) and `control`, `monitor`, `tune` and `pcmrecord` (in `/usr/local/bin`) exist.

4. Add yourself to the group `radio`.

   ```bash
   sudo adduser $(whoami) radio
   ```

5. Turn on multicast for the computer's internal network.

   ```bash
   sudo systemctl enable --now set_lo_multicast
   ```

6. Log out. Log in again.

   Result: the command `groups` shows `radio` in its list.

The install also creates the user `radio`, the service files in `/etc/systemd/system`, the settings folder `/etc/radio`, and the device rules in `/etc/udev/rules.d`.

## 8. Connect the receiver

The RX-888 Mk II has no program of its own in permanent memory. The computer loads a small program, the firmware, into it after each power-on. You do not download the firmware. It comes with ka9q-radio, and a device rule from the install loads it when you plug the receiver in.

> **Caution.** A hub or a USB 2 socket cannot carry 1 gigabit each second. `radiod` then drops data. Use a USB 3.0 socket on the PC's main board, and give the receiver that socket alone.

1. Connect the chain from section 5 to the HF input of the receiver.
2. Connect the receiver to a USB 3.0 socket on the PC. These sockets are usually blue.
3. Check that the firmware loaded.

   ```bash
   lsusb | grep 04b4          # expect 04b4:00f1 "RX888mk2". 00f3 means the firmware did not load
   ```

4. Check the USB speed.

   ```bash
   lsusb -t | grep -B2 usbfs  # the receiver's line must end in 5000M
   ```

   Result: the receiver is at `04b4:00f1`, and its line ends in `5000M`. A line that ends in `480M` means a USB 2 connection.

## 9. The configuration file

`radiod` reads one file for each receiver: `/etc/radio/radiod@hf.conf`. The file has a section `[global]`, a section for the hardware, and one section for each group of channels.

1. Copy the project's example.

   ```bash
   sudo cp ~/ka9q-radio/config/examples/radiod@rx888-generic.conf /etc/radio/radiod@hf.conf
   sudoedit /etc/radio/radiod@hf.conf
   ```

2. Make the first two sections read as follows. Leave the rest as it is for now.

   ```ini
   [global]
   hardware = rx888
   status = hf.local
   data = hf-pcm.local
   samprate = 12k
   mode = usb

   [rx888]
   device = "rx888"
   description = "<NAME>"
   samprate = 64m8
   gain = 10
   ```

3. Find the section `[WSPR]`. Delete the two frequencies above 30 MHz from its `freq` line: `50m293000` and `144m488500`.
4. Save the file.

What each line does:

| Line | Meaning |
|---|---|
| `hardware = rx888` | The name of the section that describes the radio |
| `status = hf.local` | The name of the multicast group for status and commands. `control` uses this name |
| `data = hf-pcm.local` | The default multicast group for channels that name no group of their own |
| `samprate = 12k` in `[global]` | The default sample rate of a channel's output. 12 kHz is correct for sideband voice |
| `mode = usb` | The default mode of a channel: upper sideband |
| `device = "rx888"` | The type of radio. Required |
| `description` | A free text. `radiod` announces it on your network. Later guides send it to networks as your station name |
| `samprate = 64m8` in `[rx888]` | The receiver's own rate: 64.8 million samples each second |
| `gain = 10` | The gain of the amplifier in front of the converter, in dB. Section 11 sets it |

Four rules for this file:

- **Always write `samprate = 64m8`.** One of the project's default files uses the full rate, 129.6 million. That makes more heat and needs a faster PC.
- **Write frequencies with a unit letter.** `7m074` is 7.074 MHz and `518k` is 518 kHz. A number with no letter is a guess: in ka9q-radio, `22500` means 22.5 MHz. For 22.5 kHz, write `22k5`.
- **A wrong word gives no error.** `radiod` ignores a line that it does not know. Check your spelling.
- **`disable = yes` turns a section off.** The example has many sections that are off. A section with no such line is on.

The example has `gain = 20`. The project's document on this radio says the default is 10 dB and that its author generally uses +10 dB. I run 10 dB.

## 10. Speed tables and the first start

`radiod` sorts the whole stream by frequency with one large calculation, about 50 times each second. The FFTW library does that calculation. It can measure the fastest method for your processor and keep the result in a file. The project names that file "wisdom". I name it the speed tables.

1. Make sure that `radiod` does not run.

   ```bash
   systemctl is-active radiod@hf        # expect "inactive"
   ```

2. Make the speed tables. This took 36 minutes on my Core i5-4570. Do not use the PC for other work during it.

   ```bash
   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 wisdomf
   ```

   Result: the file `/etc/fftw/wisdomf` exists and is not empty.

   Do not leave out `-T 1`. Do not copy the file from another computer. The first name, `rof1620000`, is the large calculation for 64.8 million samples each second. The other names are the small ones that the channels use.

3. Start the receiver.

   ```bash
   sudo systemctl enable --now radiod@hf
   systemctl is-active radiod@hf        # expect "active"
   ```

   The service name is `radiod@hf`, not `radiod@hf.conf`.

4. Read the start messages.

   ```bash
   systemctl status radiod@hf
   ```

   Result: the state is `active (running)`, and the time since the start goes up. If the time stays near zero, the service starts again every 5 seconds. Then go to section 17.

To test a changed file by hand, stop the service and run `radiod -v /etc/radio/radiod@hf.conf`. It prints its errors on the screen. Press Ctrl+C to stop it, then start the service again.

## 11. Set the gain and check the stream

The program `control` shows a live panel for one channel and for the receiver.

1. Start the panel.

   ```bash
   control hf.local
   ```

   Result: a list of channels with the columns `SSRC`, `preset`, `samprate`, `freq, Hz`, `SNR` and `output channel`. The last line asks you to choose an SSRC. An SSRC is the number that identifies one channel.

2. Type one SSRC from the list. Press Enter.

   Result: the panel opens. It has a row `A/D` with a level in dBFS, a row `Drops`, and a row `Overranges`.

3. Read the `A/D` level. The project's rule is an average of -20 to -25 dBFS.
4. If `Overranges` keeps rising, lower `gain` in the file by 3 dB. Then run `sudo systemctl restart radiod@hf`.
5. Read `Drops`. It must stay at 0.
6. Press `q` to leave the panel.

I run 10 dB of gain. That gives about -32 dBFS here, below the project's rule. It leaves room for strong stations at night.

### Test that the antenna sets the noise

1. Open the panel on a channel with no signal. Note the noise level in the row `N₀`.
2. Disconnect the cable at the receiver's HF input.
3. Connect the 50 ohm terminator to the HF input.
4. Read the noise level again.
5. Remove the terminator. Connect the cable again.

Result: the noise falls by 6 dB or more with the terminator. On my station it fell by 30 to 40 dB at first, and by 20 to 30 dB after I lowered the gain. If it does not fall on some band, the receiver sets the noise there. Then a better antenna location does not help on that band, and an amplifier may help.

If the cursor in the panel moves to the wrong digit, set a locale that groups digits: `export LANG=en_US.UTF-8`.

## 12. The first channel: a time signal

The example file has a section for WWV, the time signal of the US standards institute. It sends on 2.5, 5, 10, 15 and 20 MHz with plain AM. A sixth transmitter on 25 MHz is experimental and can be off. It is a good first test in North America: one of the six frequencies is open at most hours. Outside North America, put a strong broadcast station near you in the `freq` line.

### Add the channels

1. Open the file.

   ```bash
   sudoedit /etc/radio/radiod@hf.conf
   ```

2. Find the section `[WWV]`. Delete its line `disable = yes`. The section then reads:

   ```ini
   [WWV]
   data = wwv-pcm.local
   mode = am
   freq = "2500k 5000k 10000k 15000k 20000k 25000k"
   ```

3. Restart the receiver.

   ```bash
   sudo systemctl restart radiod@hf
   ```

4. Look at the new channels.

   ```bash
   control hf.local
   ```

   Result: the list has six more lines with the preset `am`. Their SSRC numbers are `2500`, `5000`, `10000`, `15000`, `20000` and `25000`. `radiod` makes the SSRC from the digits of the frequency.

5. Read the column `SNR` for the six lines. The line with the highest number is the best one at this hour.
6. Type the SSRC of the best line. Press Enter. Watch the `SNR` row for one minute.

Result: the signal-to-noise ratio stays above zero and moves slowly, as shortwave signals fade. You received a station.

### Listen to it

The program `monitor` plays a multicast group through a sound output. A server has no speakers, so choose one of three methods. I did not run method A or method B as written.

**Method A: headphones in the PC.**

1. Connect headphones to the audio socket of `hf`.
2. Start the player.

   ```bash
   monitor wwv-pcm.local
   ```

   Result: a list of the six channels with frequency, mode and signal-to-noise ratio. You hear all of them mixed.

3. Select a line with the up and down arrow keys. Press `m` to mute it. Press `u` to unmute it.
4. Press `h` for the list of keys. Press `Q` to stop the player.

If there is no sound, run `monitor -L`. It lists the sound outputs that the program sees.

**Method B: record a file and play it on another computer.**

1. Record for about 30 seconds.

   ```bash
   mkdir -p ~/rec && pcmrecord -d ~/rec wwv-pcm.local
   ```

2. Press Ctrl+C.
3. Copy the files in `~/rec` to your own computer. Play one.

   Result: one sound file for each channel. You hear a tick each second, and a voice that says the time.

**Method C: listen on another computer on your network.** This needs section 13.

### Make a channel at run time

A channel does not need a line in the file. `control` can make one while `radiod` runs. This works because `[global]` has a `data` line and a `mode` line. I did not run these steps as written.

1. Run `control hf.local`.
2. At the question, type an SSRC that is not in the list, for example `7200`. Press Enter.
3. Press `f`. Type a frequency, for example `7m200`. Press Enter.
4. Press `m`. Type a mode, for example `lsb`. Press Enter.
5. In a second terminal, run `monitor hf-pcm.local`.

Result: a channel that you tune by hand. The arrow keys change the digit under the cursor. Press `h` in the panel for the list of keys.

## 13. The streams on the network (optional)

Each channel leaves `radiod` as a stream to a multicast group. A program subscribes to the group by its name, such as `wwv-pcm.local`. `radiod` announces the names on the network with multicast DNS (the Avahi service).

**By default nothing leaves the PC.** The setting `ttl` is 0, so the streams stay on the computer's internal network. Every decoder in my other guides runs on `hf` itself, so this is enough. Leave it at 0 unless you need the streams on another computer.

### The trap with home switches and Wi-Fi

> **Caution.** With `ttl = 1`, every stream goes onto your home network. A low-cost switch with no management sends multicast traffic to every socket. A Wi-Fi base station then tries to send it over the air. The ka9q-radio documents say this can cause lost traffic and erratic operation on your entire network. Read this section to the end before you change `ttl`.

The size of the traffic decides if you have a problem. One voice channel at 12 kHz with 16-bit samples is 192 kilobits each second. The six WWV channels are about 1.2 megabits each second. The channels for the decoders in the later guides are wider, and there are many of them.

Do this before you set `ttl = 1`:

1. Connect `hf` to a managed switch that has IGMP snooping, and turn that function on. IGMP snooping is a function that sends a multicast group only to the sockets that ask for it.
2. If you do not have such a switch, turn off every channel section that you do not need on the network.
3. Do not subscribe from a computer on Wi-Fi.
4. For a channel that you only listen to, add the line `encoding = opus` to its section. The project gives about 15 kilobits each second for sideband voice with this setting. Do not use it for a channel that a decoder reads.

### Send the streams to the network

1. Find the name of the wired interface.

   ```bash
   ip address show
   ```

2. Add two lines to `[global]` in `/etc/radio/radiod@hf.conf`.

   ```ini
   ttl = 1
   iface = <IFACE>
   ```

   The `iface` line is necessary only if the PC also has Wi-Fi. If Wi-Fi starts first, Linux can send all the streams there.

3. Restart the receiver.

   ```bash
   sudo systemctl restart radiod@hf
   ```

4. On the second computer, a Linux computer on wired Ethernet, do steps 1 to 4 of section 7.
5. On the second computer, run the player or the panel.

   ```bash
   monitor wwv-pcm.local
   control hf.local
   ```

   Result: the same list and the same sound as on `hf`.

If the second computer has a firewall, allow `5004/udp` (the streams) and `5006/udp` (status and commands). With the `ufw` firewall of Ubuntu the commands are `sudo ufw allow 5004/udp` and `sudo ufw allow 5006/udp`.

Anyone on your network can then listen to the streams and send commands to `radiod`. I found no password or other access control in the project's documents. Do not set `ttl` above 1, and do not forward these streams to the internet.

## 14. Run it unattended, and the load

The command `systemctl enable` in section 10 already makes `radiod` start with the PC. If `radiod` fails, the service starts it again after 5 seconds.

1. Restart the PC.

   ```bash
   sudo reboot
   ```

2. Log in again after two minutes. Check the service and the USB speed.

   ```bash
   systemctl is-active radiod@hf        # expect "active"
   lsusb -t | grep -B2 usbfs            # expect 5000M
   ```

3. Check the clock service. The decoders in the later guides need correct time.

   ```bash
   chronyc tracking | grep "System time"
   ```

   Result: an offset far below one second.

### The load on my computer

| What ran | Load | Source |
|---|---|---|
| `radiod` alone, 64.8 million samples each second, about 150 channels | About 69 % of one core. The whole machine was about 17 % busy | My 19-hour test |
| The same, plus the HFDL decoders | The whole machine 22 % busy | My station, 2026-10-07 |
| The same, plus every decoder I run | About 29 % to 31 % busy | My station, 2026-10-06 and 2026-10-07 |
| Dropped blocks of samples | 0 in 19 hours | My 19-hour test |
| Memory in use | Under 2.5 GB | My station, 2026-10-07 |

The large calculation is the main cost, and it does not grow with the number of channels. One more channel adds little. One more subscriber to a channel adds nothing to `radiod`.

Do not run other heavy work on `hf`. The ka9q-radio documents report lost data on a small computer when other programs took the processor.

## 15. Lowest-cost start: one tuned radio

You can try shortwave for the price of one small radio before you buy any part in section 2. This is a different kind of station. Be clear about what it is.

### What you do

1. Buy one tuned radio that covers shortwave. The lowest-cost one in the table in section 2 is the RTL-SDR Blog V4L.
2. Connect it to the best antenna you have, outdoors. The rules in section 4 apply.
3. Install the driver that the radio's maker gives for your system.
4. Install one SDR program with a screen on the computer you own. I name [SDR++](https://github.com/AlexandreRouma/SDRPlusPlus) because it is free and runs on Windows, Linux and macOS.
5. Tune to 10 MHz, AM. Listen for the time signal.

I have not tried the V4L on shortwave. Its seller says that it needs updated drivers and that some programs do not support it yet. Read the seller's page before you buy.

### What this path cannot do

- **It hears one slice.** A tuned radio sees a slice from a few hundred kilohertz to about 2 MHz wide. Shortwave is 30 MHz wide. The radio I first planned to use sees less than 1 MHz.
- **Jobs take turns.** One kind of signal now, another kind later. The bands open and close with the sun, so a job that waits its turn misses traffic.
- **The later guides do not fit it as written.** They assume that every channel exists all day. With one slice, you can run one decoder on one band at a time.
- **A low-cost radio has less range between weak and strong.** The ka9q-radio documents say that the main drawback of an RTL radio is its 8-bit converter. Strong broadcast stations at night can cover weak signals.

### The middle path

ka9q-radio also runs tuned radios. It has a driver for the Airspy HF+. Its example file `radiod@airspyhf-generic.conf` runs that radio 768 kHz wide. So sections 7 and 9 to 14 work with that radio, for the channels that fit in one slice. The project's own example turns on one WSPR frequency for this reason. I did not run this. The project's document for RTL radios lists a range that starts at 24 MHz. So I do not know if a V4L works with ka9q-radio on shortwave.

## 16. Check that it works

| No. | Check | Command or action | Pass | Wait |
|---|---|---|---|---|
| 1 | The firmware loaded | `lsusb \| grep 04b4` | `04b4:00f1` | A few seconds after you plug it in |
| 2 | The USB speed | `lsusb -t \| grep -B2 usbfs` | The line ends in `5000M` | None |
| 3 | The service runs | `systemctl is-active radiod@hf` | `active`, and the same after 1 minute | 1 minute |
| 4 | The channels exist | `control hf.local` | A list of channels with their frequencies | A few seconds |
| 5 | The level at the converter | The `A/D` row of the panel | -20 to -35 dBFS, and `Overranges` does not rise | 1 minute |
| 6 | No data is lost | The `Drops` row of the panel | 0 | 10 minutes |
| 7 | The antenna sets the noise | The terminator test in section 11 | The noise falls by 6 dB or more | None |
| 8 | A real signal | The `SNR` column for the six WWV lines | One line or more clearly above 0 dB | Try again at another hour if none |
| 9 | Sound | Method A, B or C in section 12 | A tick each second | None |
| 10 | It survives a restart | Section 14, steps 1 and 2 | `active` and `5000M` | 2 minutes |

Then note the `A/D` level and the `N₀` level on one quiet frequency, by day and by night. Those numbers are your baseline. When you move the loop, compare with them.

## 17. If it does not work

| Symptom | Likely cause | What to do |
|---|---|---|
| `lsusb` shows `04b4:00f3` | The firmware did not load | Unplug the receiver and plug it in again. Check that `/etc/udev/rules.d/70-rx888-boot.rules` exists. If not, run `sudo make install` again |
| `lsusb` shows nothing with `04b4` | Cable, socket or power | Use the cable that came with the receiver. Use another USB 3.0 socket on the main board |
| The receiver's line ends in `480M` | A USB 2 socket, a USB 2 cable or a hub | Use a USB 3.0 socket on the main board and a USB 3 cable |
| The log of `radiod` contains the words "not at least SuperSpeed" | The same | The same |
| `radiod` reports dropped data, or `Drops` rises | The receiver is on a hub or a USB 2 socket, or other work takes the processor | Use a USB 3.0 socket on the main board. Stop the other work. Make the speed tables (section 10) |
| The service starts again every 5 seconds | `radiod` does not find the receiver, or the file has an error | Run `systemctl status radiod@hf`. Then stop the service and run `radiod -v /etc/radio/radiod@hf.conf` to see the message |
| `systemctl` says the unit `radiod@hf.conf` does not exist | The `.conf` ending is in the service name | Use `radiod@hf` |
| `control` says "No radiod instances or Avahi not running" | `radiod` does not run, or multicast on the internal network is off | Check step 3 of section 10. Run `sudo systemctl enable --now set_lo_multicast`, then restart `radiod@hf` |
| A program cannot find a name that ends in `.local` | Multicast DNS does not answer | Check that the `avahi-daemon` service runs. The project's `docs/notes.md` has a fix for old Ubuntu versions |
| Permission errors in `/etc/fftw` or `/etc/radio` | Your login is not in the group `radio` yet | Log out and log in again after step 4 of section 7 |
| The log of `radiod` has lines that start with "suggest running" | No speed table for one calculation | Stop the service. Run the command that the line gives. Start the service |
| 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 5) |
| The loop has no signal | The loop amplifier has no power | Injector first on the loop cable. Check its power supply. Check that no part before the injector blocks direct current |
| `Overranges` keeps rising, mostly at night | Too much gain for the strong broadcast stations | Lower `gain` by 3 dB. If that is not enough, turn on the F3060 shelf filter |
| The bands below 4 MHz are weak | The F3060 shelf filter is on | Bypass it |
| The noise does not fall with the terminator | The receiver sets the noise on that band | Raise `gain` in small steps and watch `Overranges` |
| Noise everywhere, the same by day and by night | The loop is too near the house electronics | Move the loop. Turn it to put its null on the noise. Add ferrites to the cable and the USB cable |
| A channel for 22.5 kHz hears nothing | In ka9q-radio, `22500` means 22.5 MHz | Write `22k5` |
| A channel does not appear after you edit the file | A wrong word in the section, or `disable = yes` is still there | `radiod` ignores a line it does not know. Compare with the example file |
| The cursor in `control` moves to the wrong digit | The locale does not group digits | `export LANG=en_US.UTF-8` |
| `monitor` shows channels and there is no sound | No sound output, or the wrong one | `monitor -L` lists the outputs. Use method B in section 12 |
| After `ttl = 1`, the home network or the Wi-Fi is slow | A switch sends the streams to every socket | Set `ttl = 0` and restart `radiod@hf`. Read section 13 again |
| After a restart of the PC, the second computer gets no stream | Wi-Fi started before Ethernet, and Linux sends the streams there | Set `iface = <IFACE>` in `[global]`, or turn Wi-Fi off on `hf` |

## 18. What I did wrong

- **I planned for a narrow radio.** My first plan used a radio that sees less than 1 MHz at a time. The jobs had to take turns: weak beacons, then weather charts, then aircraft at night. I wanted all of them, all day. One wide receiver removed the schedule.
- **My loop is still indoors, next to the computer.** That is the worst place for it. The station works, and the antenna noise is still 20 to 30 dB above the receiver's own noise. The fix is distance from the house, not a new part.
- **I started with more gain than I needed.** I lowered it to 10 dB. The antenna still sets the noise, and strong stations at night have room.
- **I wrote a frequency with no unit letter.** `22500` meant 22.5 MHz, not 22.5 kHz. The channel was silent, and `radiod` gave no error.

## 19. Not run and not confirmed

- No step in this guide was run on a new, empty computer as written. The settings are the ones on my station, checked against the project's documents on 2026-10-10.
- That the newest ka9q-radio builds with these exact steps. I built the commit named in section 7. The project had new commits on the day of this check.
- The ready-made ka9q-radio packages. I have not used them. The project's own source list file now selects Debian 13 by default, and you must edit it for Ubuntu.
- Which firmware file the device rule loads at the commit named in section 7. Today's code has a setting file for it, `/etc/radio/rx888_bootfile.conf`. On my station the receiver shows `04b4:00f1` after I plug it in.
- The line `data = hf-pcm.local` in `[global]`, and section 12, "Make a channel at run time". The project's documents describe both. I did not run them as written.
- Section 12, methods A and B, and the names of the files that `pcmrecord` writes. I read the options in the program's source, and I did not run these commands as written.
- The six WWV channels as a first test. The section is in the project's example file. I do not state which of the six you hear at your location.
- The `chronyc` command in section 14. It is a standard command of the clock service. I did not run it for this guide.
- Section 13 as a whole. On my station `ttl` is 0 and every decoder runs on `hf`. The warnings about switches and Wi-Fi are from the ka9q-radio documents. The `ufw` commands are standard Ubuntu commands that I did not run for this purpose.
- That the RX-888 Mk II has a bias tee on its HF input, and what state it is in at power-on. The maker's page does not mention one.
- That the TAPR RF Limiter blocks direct current. Its product page does not say. So the injector goes before it in every case.
- The F3060 figures in section 5 are from its manual, which I read on 2026-10-07. Its product page gives no figures. I did not measure them. I also do not describe how to bypass the shelf filter: read the manual.
- The loss of the RG-6 cable. I did not measure it.
- The rule on loop height and distance. It comes from two loop designers. I re-read one page on 2026-10-10. I did not test it, because my loop is still indoors.
- A Raspberry Pi 5 for this receiver. The project says it works "just barely". I did not test it.
- The price of the RX-888 Mk II, and the US price of the MLA-30+.
- Everything in section 15. I have not used an RTL-SDR Blog V4L or SDR++ on shortwave, and I did not run ka9q-radio with an Airspy HF+.
- The load figures in section 14 are from my computer on the named days. A different processor gives different numbers.
- The block time of 20 ms ("about 50 times each second") is the default in the project's documents. I did not read the value on my station.

## 20. Sources

Read on 2026-10-10, unless the line gives another date.

**ka9q-radio.** <https://github.com/ka9q/ka9q-radio>: `README.md`, `docs/INSTALL.md`, `docs/SDR/rx888.md`, `docs/SDR/rtlsdr.md`, `docs/SDR/airspy.md`, `docs/FFTW3.md`, `docs/ka9q-radio.md` (the `[global]` section), `docs/ka9q-radio-2.md` (hardware), `docs/ka9q-radio-3.md` (channels), `docs/NETWORK-NOTES.md`, `docs/notes.md`, `config/examples/radiod@rx888-generic.conf`, `config/examples/radiod@airspyhf-generic.conf`, `ka9q-sources.list`, `share/help.txt` and `share/monitor-help.txt` (the keys), the service files `radiod@.service.in`, `set_lo_multicast.service.in` and `rx888_boot.service.in`, the device rules `70-rx888-boot.rules` and `71-rx888.rules`, and the option lists in `src/control.c`, `src/monitor.c`, `src/tune.c`, `src/pcmrecord.c` and `src/rx888.c`. The manual pages for `control`, `monitor`, `tune` and `pcmrecord` are empty templates today. License: GPL-3.0 (read 2026-10-09).

**The full-station guide.** [Build the station](/guides/build-the-station/), sections 2, 3, 4, 11 and 17. Its commands were checked against my station on 2026-10-07.

**Parts.** RX-888 Mk II: <https://www.rx-888.com/rx/>. TAPR RF Limiter: <https://tapr.org/product/rf-limiter/>. Turn Island Systems F3060: <https://turnislandsystems.com/product/f3060-filter-shelf-30-60-mhz-lpf/> (the page today, the manual on 2026-10-07). RTL-SDR Blog V4L: <https://www.rtl-sdr.com/buy-rtl-sdr-dvb-t-dongles/>. MLA-30+: the listing linked in section 2 (2026-10-07).

**Antenna location.** Chavdar Levkov, "Wideband Active Small Magnetic Loop Antenna": <https://www.lz1aq.signacor.com/docs/wsml/wideband-active-sm-loop-antenna.htm>.

**The lowest-cost path.** SDR++: <https://github.com/AlexandreRouma/SDRPlusPlus> (its README).

**Background.** NOAA on the ionosphere: <https://www.swpc.noaa.gov/phenomena/ionosphere> (linked from the episode, not re-read today). Heat in the RX-888: <https://ka7oei.blogspot.com/2023/08/improving-thermal-management-of-rx-888.html> (read 2026-10-07).

**The test signal.** NIST, radio station WWV: <https://www.nist.gov/pml/time-and-frequency-division/time-distribution/radio-station-wwv>.

**Rules.** 47 U.S.C. 605: <https://www.law.cornell.edu/uscode/text/47/605> (read 2026-10-07).

[^limiter]: I transmit on shortwave from the same property, at 5 to 20 watts. The limiter is there for that, and for static. TAPR says it limits strong signals to less than +10 dBm, with less than 1 dB of loss through 54 MHz for small signals.
[^lz1aq]: Chavdar Levkov. His page describes his own amplifier, not the MLA-30+. The general rule for small loops is the same. I learned the same rule from a second loop maker. I did not re-read those pages for this guide.
[^nec]: Mike Holt's summary of NEC 810.21, 2020 edition: <https://www.mikeholt.com/files/PDF/20BG_810.21.pdf>.
