RTL-SDR Device Guide
Use this guide to attach an RTL2832U-based receive-only SDR to RemoteRF, whether it is owned by the main server or by a RemoteRF host.
RTL-SDR is natively supported through RemoteRF's built-in rtl_sdr schema. The base remoterf-server and remoterf-host packages include PyRtlSdr and the packaged native library. The machine that owns the physical USB dongle performs capture; clients receive a generated RtlSdr class and need no RTL-SDR installation.
Overview
RemoteRF exposes the common receive controls used by RTL2832U-based SDRs, bounded complex-sample and raw-byte reads, and device identity. This is a receive-only path: RTL-SDR hardware cannot transmit.
RTL-SDR describes a family rather than one completely uniform radio. Dongles can contain different tuners, and available native functions depend on the installed librtlsdr build. RemoteRF therefore probes optional controls when a session opens instead of assuming that bias tee, direct sampling, offset tuning, or dithering exists on every device.
The setup flow is:
- Optionally install the native RTL-SDR diagnostic tools on the Linux machine that owns the dongle. The Python runtime and packaged library are included with the base RemoteRF package.
- Verify that the same account used to run
serverrforhostrfcan open the dongle locally. - Register the dongle by its USB serial when possible, then restart that machine’s RemoteRF process.
- Reserve the device and let the client download or refresh the generated
RtlSdrwrapper.
Install and Detect
Install Diagnostic Tools
The base remoterf-server package already installs the supported Python wrapper and packaged native library. Install the command-line utilities in the same Conda environment only when you need local diagnostics. The client machine does not need them.
conda activate YOUR_REMOTERF_ENV
conda install -y -c conda-forge rtl-sdr
rtl_test diagnostic utility. The base RemoteRF package already includes PyRtlSdr and a compatible packaged native library, avoiding optional-symbol mismatches with an older system librtlsdr. For API details, see the official PyRtlSdr overview.
Verify Local Detection
Connect the dongle by USB, then confirm that native discovery works before changing the RemoteRF inventory.
rtl_test -t
Manifest Example
Register by serial whenever possible. A serial remains stable when USB enumeration order changes and prevents RemoteRF from silently opening the wrong dongle.
devices:
- device_id: 4
device_type: rtl_sdr
name: RTL-SDR FM Bench
init:
serial: "00000001"Alternatively, create the same entry with the server CLI:
serverrf --device --add --rtl-sdr "4:RTL-SDR FM Bench:serial=00000001"
serverrf --device --show
If the RTL-SDR is attached to a RemoteRF Host instead, use hostrf for the add command:
hostrf --device --add --rtl-sdr "4:RTL-SDR FM Bench:serial=00000001"
If a dongle has no useful unique serial, select its current zero-based USB index instead:
serverrf --device --add --rtl-sdr "4:RTL-SDR FM Bench:index=0"
On a RemoteRF Host, the same index-based command is:
hostrf --device --add --rtl-sdr "4:RTL-SDR FM Bench:index=0"
The index form writes init.device_index: 0. Use it only when serial selection is impossible, because unplugging or adding USB devices can change enumeration order. Restart serverrf after any inventory change.
Client Usage
After reserving the RTL-SDR, let the client automatically fetch or refresh the schema-generated driver, configure the receiver, and perform a bounded synchronous read:
from remoteRF.drivers import ensure_driver
token = "reservation-token"
ensure_driver(token=token)
from remoteRF.drivers.rtl_sdr import RtlSdr
sdr = RtlSdr(token)
sdr.sample_rate = 2_048_000
sdr.center_freq = 100_000_000
sdr.gain = "auto"
samples = sdr.read_samples(16_384)
print(samples.shape, samples.dtype)read_samples() returns normalized NumPy complex64 IQ. read_bytes() returns packed unsigned 8-bit interleaved IQ. A single response is limited to 4 MiB, so longer recordings should use repeated bounded reads and write or process each block as it arrives.
Remote callbacks are intentionally not exposed. PyRtlSdr’s asynchronous callback runs in the native process and cannot cross the RPC boundary as a normal Python callback; repeated synchronous reads provide explicit backpressure and bounded network payloads.
Troubleshooting
- Kernel driver is busy
- Linux may bind the dongle to
dvb_usb_rtl28xxu. A compatiblelibrtlsdrnormally detaches it while opening the radio. If your native build cannot, unload or blacklist that DVB module before starting RemoteRF. - Permission denied
- Install the RTL-SDR udev rules, reload them, reconnect the dongle, and confirm that
rtl_test -tsucceeds withoutsudofor the server account. - Undefined native symbol
- An error such as
undefined symbol: rtlsdr_set_ditheringmeans PyRtlSdr loaded an incompatible native library. Reinstall or upgrade the appropriate baseremoterf-serverorremoterf-hostpackage so the wrapper and packaged library agree; there is no RTL-SDR extra. - Serial not found
- Rerun
rtl_test -tand copy the reported serial exactly. Useindex=0only as a temporary fallback when the device has no stable serial. - Optional control fails
- An optional operation may be absent for the tuner or installed
librtlsdr; this is expected and is reported asNotImplementedErrorrather than emulated.