Set up a receiver: Raspberry Pi + RTL-SDR with rtl_tcp

This is the quickest way to put a radio behind the SDR-SLC client. An RTL-SDR dongle on a Raspberry Pi becomes a network receiver, using rtl_tcp, the standard server most SDR programs already understand. Put the Pi wherever the antenna is, and tune the bands from your Mac anywhere in the house.

What you get: a receiver from HF to about 1.7 GHz, with spectrum, waterfall and multiple slices in the client. AM, FM, SSB and CW, and with the optional codec server also DMR, YSF and D-STAR.

Time: about half an hour. Nothing needs compiling.

What you need

ItemNotes
Raspberry Pi 3B+, 4 or 5rtl_tcp is light, so any recent Pi will do.
Official Pi power supplyAn RTL-SDR draws around 300 mA, more with the bias tee on.
microSD card, 16 GB or more
RTL-SDR Blog V4Also works with a V3 or a V4L. See the notes on each in step 2.
Ethernet cableThe stream is about 33 Mbit/s and runs continuously. Wi-Fi often drops samples.
An antennaA long wire for HF, a vertical or discone for VHF/UHF.
A Mac with the SDR-SLC client 1.2From the Mac App Store.

Step 1: Raspberry Pi OS

  1. On your Mac, install Raspberry Pi Imager from raspberrypi.com/software.
  2. Choose your Pi model, then Raspberry Pi OS (other) → Raspberry Pi OS Lite (64-bit). This guide used the Debian 13 “trixie” release.
  3. In the customisation step, set:
    • a hostname, e.g. slc-rtl;
    • your username and password;
    • your time zone;
    • Enable SSH.
  4. Write the card, start the Pi with Ethernet connected, and log in from Terminal on your Mac:
ssh <user>@slc-rtl.local
sudo apt update && sudo apt full-upgrade -y
sudo reboot

Tip: if every login prints setlocale: LC_CTYPE: cannot change locale (UTF-8), that’s macOS Terminal sending a locale name Linux doesn’t know. It’s harmless, but it clutters your logs. Stop the Pi from accepting it:

sudo sed -i 's/^AcceptEnv LANG LC_\*/#&/' /etc/ssh/sshd_config
sudo systemctl restart ssh

Step 2: the RTL-SDR driver

Install

Debian ships the driver and rtl_tcp, including support for the RTL-SDR Blog V4:

sudo apt install -y rtl-sdr

Keep the TV driver away from the dongle

Linux sees an RTL-SDR as a DVB-T television stick and loads a TV driver for it, and that driver then blocks rtl_tcp. Block it, then reboot:

echo 'blacklist dvb_usb_rtl28xxu' | sudo tee /etc/modprobe.d/blacklist-rtl-sdr.conf
sudo reboot

Plug in and test

Plug the dongle in after the reboot, then run:

lsusb | grep -i realtek          # ... 0bda:2838 Realtek Semiconductor Corp. RTL2838 DVB-T
rtl_test -t

Run rtl_test as your normal user, without sudo. That also checks you have permission to use the dongle. A V4 answers with:

Found 1 device(s):
  0:  RTLSDRBlog, Blog V4, SN: 00000001
...
RTL-SDR Blog V4 Detected

If you get usb_open error -3: the dongle isn’t accessible to your user. Debian’s rule gives the plugdev group access. Check that you’re in that group, and add yourself if not, then log out and back in:

groups | grep -o plugdev
sudo usermod -aG plugdev $USER

If you get Kernel driver is active: the TV-driver block didn’t take effect. Check the file from the previous step and reboot again.

A V3 works with the same steps. It reaches HF only through direct sampling, which is less sensitive than the V4’s built-in upconverter. The V4 switches to its upconverter by itself whenever you tune below about 28.8 MHz.

Only for the RTL-SDR Blog V4L

The V4 went out of production in May 2026. Its successor, the V4L, needs driver version 2.0.3, which is newer than the one Debian ships. Build that version instead of using the Debian package:

sudo apt remove -y rtl-sdr librtlsdr2
sudo apt install -y git cmake build-essential pkg-config libusb-1.0-0-dev
git clone --branch v2.0.3 https://github.com/osmocom/rtl-sdr ~/rtl-sdr
cd ~/rtl-sdr && mkdir build && cd build
cmake .. -DINSTALL_UDEV_RULES=ON -DDETACH_KERNEL_DRIVER=ON
make -j4 && sudo make install && sudo ldconfig

rtl_test -t then reports RTL-SDR Blog V4 Lite Detected. The program is now /usr/local/bin/rtl_tcp, so use that path in the service in step 3.

If rtl_test then reports usb_open error -3, the rules installed by this build may not use plugdev. Add Debian’s rule yourself, then unplug and replug the dongle:

echo 'SUBSYSTEMS=="usb", ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="2838", MODE="0660", GROUP="plugdev"' \
  | sudo tee /etc/udev/rules.d/60-rtl-sdr-plugdev.rules
sudo udevadm control --reload-rules

Step 3: run rtl_tcp as a service

Running rtl_tcp as a service means it starts by itself with the Pi, and restarts if the dongle is briefly unplugged. It runs as its own user, rtltcp, which only has access to the dongle:

sudo useradd --system --no-create-home --shell /usr/sbin/nologin --groups plugdev rtltcp

Create the service file:

sudo tee /etc/systemd/system/rtl-tcp.service >/dev/null <<'EOF'
[Unit]
Description=rtl_tcp I/Q server for the SDR-SLC client
After=network-online.target
Wants=network-online.target

[Service]
User=rtltcp
ExecStart=/usr/bin/stdbuf -oL /usr/bin/rtl_tcp -a 0.0.0.0 -p 1234
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target
EOF

Start it and check the log:

sudo systemctl daemon-reload
sudo systemctl enable --now rtl-tcp
journalctl -u rtl-tcp -n 15 --no-pager
ss -ltn | grep 1234

The log should name your dongle and end with listening..., and ss should show port 1234 open.

stdbuf -oL in the ExecStart line makes rtl_tcp write its messages to the log straight away instead of holding them back. If you built the driver yourself for a V4L, change the second path on that line to /usr/local/bin/rtl_tcp.

Powering an LNA from the dongle? Add -T to the end of the ExecStart line to switch on the bias tee. Then run sudo systemctl daemon-reload && sudo systemctl restart rtl-tcp. Only do this with an LNA or filter that is meant to be powered over the coax.

Give the Pi a fixed address

rtl_tcp doesn’t announce itself on the network, so the client needs the Pi’s address, and that address shouldn’t change. Look it up:

hostname -I

Then give the Pi a fixed address in your router, often called a DHCP reservation. The .local name (slc-rtl.local) usually works too, but a fixed address is the most reliable.

Step 4: connect the client

  1. In the SDR-SLC client on your Mac, open the connection settings and choose RTL-TCP as the protocol.
  2. Enter the Pi’s address and port 1234.
  3. Click Connect.
  4. Tune to a signal you know is there, such as a broadcast FM station or your local repeater’s output. Start with a sample rate of 2.048 MS/s.

The V4 runs reliably up to 2.4 MS/s. Higher rates drop samples.

The client gets Discover results only from SDR-SLC devices, so this receiver doesn’t appear there. That’s expected with rtl_tcp.

rtl_tcp serves one client at a time. While the SDR-SLC client is connected, other programs can’t use the receiver, and the other way round.

Optional: the codec server for digital voice

For DMR, YSF and D-STAR, add the vocoder service. It can run on this same Pi:

sudo apt install -y git build-essential cmake pkg-config libjson-c-dev libavahi-client-dev avahi-daemon
mkdir -p ~/src && cd ~/src
git clone --recursive https://github.com/pa2ix/sdr-slc-vocoderd
cd sdr-slc-vocoderd
make mbelib && make && make test 2>&1 | tail -1
sudo make install
sudo systemctl daemon-reload
sudo systemctl enable --now sdr-slc-vocoderd

The vocoder service, unlike rtl_tcp, does announce itself on the network. Click Discover in the client and add it from the list. A DVSI AMBE-3000 stick (DVstick30, ThumbDV) is optional. Without one, the open-source mbelib-neo decoder does the work, and you can plug a stick in later without restarting anything.

Security

rtl_tcp has no password. Anyone who can reach port 1234 can use your receiver and retune it. On a home network that’s usually fine. Never forward port 1234 from the Internet.

Troubleshooting

SymptomCause and fix
rtl_test: usb_open error -3Your user isn’t in plugdev, or you haven’t logged out and in since being added.
rtl_test: Kernel driver is activeThe TV driver still claims the dongle. Check /etc/modprobe.d/blacklist-rtl-sdr.conf and reboot.
journalctl -u rtl-tcp: No supported devices found, repeatingThe dongle isn’t plugged in or isn’t recognised. Check lsusb. The service retries every 3 seconds.
The client can’t connectCheck the address with hostname -I and the service with systemctl status rtl-tcp. Only one client can be connected at a time, so close any other SDR program that’s connected.
Audio stutters, or gaps appear in the waterfallUse Ethernet instead of Wi-Fi, and keep the sample rate at 2.4 MS/s or lower.
HF is deaf on a V3A V3 needs direct sampling for HF, and a long wire works best.

Next step: let the client find the receiver by itself

This setup works with almost any SDR program, but you type in its address by hand. Swap rtl_tcp for sdr-slc-rtld, the SDR-SLC daemon for RTL-SDR, and the same dongle shows up under Discover, already configured. The dongle, the Pi and the driver from step 2 all stay as they are.

Set up a Raspberry Pi + RTL-SDR with sdr-slc-rtld →

Or see all options on the Station setups page.

73, Ivo PA2IX