Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Radios

A Device node opens one radio: over USB, over the network, or through SoapySDR. It also plays recordings and generates test signals, see Other sources.

Supported radios

Packaged builds include every driver here except CR-8:

RadioConnects overNeeds
RTL-SDRUSBNothing
KrakenSDR, KerberosSDRUSBNothing
HackRFUSBNothing
Airspy R2, Mini, HF+, HF+ DiscoveryUSBNothing
FUNcube Dongle Pro+USBWinUSB on Windows
ESP32 with ESP-SDRUSB serial, Ethernet (S31)ESP-SDR firmware
AntSDREthernet or USBNothing
ADALM-Pluto, other AD936x boardsUSB or EthernetNothing
SDRplay RSP1, RSP1A, RSP1B, RSP2, RSPduo, RSPdx, RSPdx-R2USBSDRplay API 3.15+
SDRplay on another machineNetworkSDRconnect there
Aaronia SPECTRAN V6, V6 ECOUSBRTSA-Suite PRO, Windows or Linux
KiwiSDRNetworkNothing
rtl_tcp and SpyServer serversNetworkNothing
Dragon Labs CR-8USBVendor library, a build with cr8
bladeRF, LimeSDR, USRP, othersUSBA SoapySDR module

Making a radio? Write to hi@jhaag.me to get it supported and tested.

Compare radios

RadioTunesMax rateBandwidthBitsRXTXDC spike
RTL-SDR24 MHz to 1.766 GHz3.2 MS/s3.2 MHz810Small
RTL-SDR Blog V4500 kHz to 1.766 GHz3.2 MS/s3.2 MHz810Small
KrakenSDR lane24 MHz to 1.766 GHz2.56 MS/s2.56 MHz810Small
HackRF One1 MHz to 6 GHz20 MS/s20 MHz811Yes
Airspy R224 MHz to 1.8 GHz10 MS/s9 MHz1210No
Airspy Mini24 MHz to 1.8 GHz10 MS/s6 MHz1210No
Airspy HF+ Discovery1 kHz to 31 MHz, 60 to 260 MHz768 kS/s660 kHz1610Some rates
FUNcube Dongle Pro+150 kHz to 260 MHz, 410 MHz to 2.05 GHz192 kS/s192 kHz1610Yes
ESP32 with ESP-SDR2.4 GHz, 5 GHz on C580 MS/s, burstsPer chip, up to 69 MHz8 or 1010Yes
AntSDR E200, E31070 MHz to 6 GHz61.44 MS/s56 MHz1222Yes
ADALM-Pluto325 MHz to 3.8 GHz61.44 MS/s20 MHz1211Yes
SDRplay RSP1, RSP210 kHz to 2 GHz10.66 MS/s8 MHz1210Corrected
SDRplay RSP1A, RSP1B, RSPdx, RSPdx-R21 kHz to 2 GHz10.66 MS/s8 MHz1410Corrected
SDRplay RSPduo1 kHz to 2 GHz10.66 MS/s8 MHz1420Corrected
Aaronia SPECTRAN V6Per modelPer model and clockRate / 1.51611Unknown
Aaronia SPECTRAN V6 ECOPer model61.44 MS/s40 MHz1611Unknown
KiwiSDR0 to 30 MHz20 kS/s20 kHz1410No
Dragon Labs CR-824 MHz to 1.766 GHz12.5 MS/s8 MHz1280Unknown
bladeRF 2.0 micro70 MHz to 6 GHz61.44 MS/s56 MHz1222Yes
LimeSDR USB100 kHz to 3.8 GHz61.44 MS/s61.44 MHz1222Yes
LimeSDR Mini 2.010 MHz to 3.5 GHz30.72 MS/s30.72 MHz1211Yes
USRP B200, B205mini70 MHz to 6 GHz61.44 MS/s56 MHz1211Yes
USRP B21070 MHz to 6 GHz61.44 MS/s56 MHz1222Yes
  • Max rate is what the radio delivers. USB or Ethernet often carries less: a Pluto over USB streams about 4 MS/s without loss.
  • Bandwidth is the widest span received at once, set by the analog filter or the rate. RSPduo with both tuners gets 1.536 MHz each.
  • Bits are the ADC's. SDRplay drops to 12 bits above 6 MS/s and to 8 above 9.2 MS/s. The HF+ sends 16 bits after its own decimation.
  • RX counts lanes one Device node streams.
  • TX counts transmit channels on the hardware.
  • DC spike: Yes and Small start with DC block on, except through SoapySDR. Corrected means the SDRplay API removes it. On HF+ it appears only at rates that leave a spike at the centre.
  • Boards with an AD9363 instead of an AD9361 tune 325 MHz to 3.8 GHz.

Connect a radio

USB

Plug it in and it appears in the Radios tab of every empty Device node.

On Linux, install your radio's udev rules and add the server's user to the group they name, usually plugdev. Reload udev and replug the radio. SDRmm never needs root. For containers, see USB devices.

Network radios

On an empty Device node, open the Network tab, pick the protocol under Via, and enter host:port. Without a port it uses the default:

ProtocolDefault port
rtl_tcp1234
SpyServer5555
SDRconnect5454
KiwiSDR8073
AntSDR / Pluto30431
ESP-SDR80

The address becomes the radio's identity in the workspace. The bookmark button next to Add saves it; saved radios are listed above the form.

Network IQ uses a lot of bandwidth. When the link cannot keep up, the node shows Lost with the share of samples missing: lower the rate.

Radio missing

Press Check hardware on an empty Device node, or run:

sdrmm --doctor

Both list compiled drivers, loaded libraries, SoapySDR modules, found radios, data paths, and Linux USB permissions. See also Troubleshooting.

Device controls

Controls mean the same thing on every radio:

ControlSets
RateSample rate
BW or FilterAnalog bandwidth before sampling. BW has an auto setting.
AntennaInput port, when there is a choice
AutoAGC, on the gain row. The slider shows the gain the radio chose, where it reports it.
AGCAGC mode, on radios that have several
LNA, Mixer, VGA, IF, RF, Tuner, AttenuatorOne gain stage each, in dB or firmware steps
AmpA switchable preamp
Bias teePower on the antenna port for an active antenna or LNA
PPMCrystal correction
ConvLocal oscillator of an up- or downconverter, in MHz
DC blockRemoves the radio's own DC spike

On a radio with several lanes, each lane's gain row is labelled iq1, iq2, and so on, and the All row sets every lane. On radios that can choose, the −/+ buttons on that row set how many lanes stream. The footer shows Queue delay, Drops, Lost samples, and Clipping.

With Conv set, every frequency shown is the one at the antenna. Enter a positive value for a downconverter, like 9750 for a Ku-band LNB, and a negative one for an upconverter, like -125 for a Ham It Up.

Settings only one radio has appear as extra chips. Some change the others: RTL-SDR direct sampling changes the tuning range. Radios that send are covered in Transmit.

Calibration

PPM and the converter offset belong to the radio, not the node: set them once and every Device node that opens that radio uses them. A USB radio is known by its serial, a network radio by its address. RTL-SDRs need serials of their own.

RTL-SDR

The built-in driver needs an R820T or R828D tuner; E4000, FC0012, FC0013, and FC2580 dongles are refused. On Windows, install the WinUSB driver with Zadig.

ControlDoes
TunerGain, in the tuner's own steps: 20 dB on an R820T becomes 19.7 dB
AutoTuner AGC
Bias teeAntenna-port power
Direct samplingoff, i, or q. Not on the RTL-SDR Blog V4 or V4 Lite, which upconvert HF.

Rates: 225 to 300 kHz, or 900 kHz to 3.2 MHz. BW: 290 kHz to 8 MHz.

Serials

Many dongles ship with the serial 00000001. Two dongles with one serial are told apart by USB port instead, shown with (bus/address) after the name, and their settings and calibration can follow the wrong one after a replug.

SDRmm asks once when it finds such a dongle. Yes writes a random serial, or one you type, to its EEPROM. Replug it afterwards. The dongle must be closed, and one without an EEPROM cannot keep a serial.

KrakenSDR

Five tuners on one clock, a Device each; KerberosSDR has four. SDRmm knows them by serial and USB hub, so the vendor Pi image is not needed, and names them KrakenSDR <hub> lane 1 to lane 5. Add a Device per lane and wire them to one Array in antenna order. Each lane reports the bank it shares, so the Array takes Shared clock from the hardware and not from what you declare. There is no direct sampling, and the rate tops out at 2.56 MS/s.

The lanes share a clock, not a phase. The Array switches on the built-in noise source to solve delay, phase, and gain after every retune and gain change, and checks them every minute. The antennas are cut off while the source is on; processors pause.

  • Switches: the noise source and all five bias tees hang off lane 1's tuner, so lane 1 has to be open and in the Array to move them.
  • Gain: lane phase moves by up to about 10° across the gain steps. The Array solves at the gain you run.
  • Clipping: the noise source clips at higher gain. Past 75% clipped samples the Array shows Noise clips, lower gain.
  • Starts: the lanes start one by one, so the Array searches its offsets on the first lock and again whenever a lane restarts.
  • Noise source: the Array needs every lane of the bank to run it, or it shows Noise needs all lanes.

A lane that is missing shows up in sdrmm --doctor under Coherent banks. Hardware tests has measurements.

Tested on hardware provided by KrakenRF. Thank you.

HackRF

ControlDoes
LNAGain in 8 dB steps
VGAGain in 2 dB steps
Amp+14 dB RF amplifier
BWBaseband filter, or auto
Bias teeAntenna-port power

Airspy

Built in, no vendor library needed. To use SoapySDR instead, build without airspy and airspyhf.

R2 and Mini: tunes 24 MHz to 1.8 GHz. LNA, Mixer, and VGA gain use firmware steps, not dB. AGC can run the LNA, the mixer, or both. Bias tee available.

HF+ and HF+ Discovery: tunes up to 31 MHz and 60 to 260 MHz. Controls are Amp (+6 dB), Attenuator in 6 dB steps down to -48 dB, AGC with a low or high threshold, and PPM, which starts from the calibration stored on the radio. A centre below 180 kHz (84 kHz at the narrower rates) tunes to that floor, and the band still shows it. DC block appears only at rates that leave a spike at the centre.

Tested on hardware provided by Airspy. Thank you.

FUNcube Dongle Pro+

Built in. Controls are LNA and Mixer (on or off), IF gain 0 to 59 dB, IF filter (BW, 200 kHz to 8 MHz), RF filter (auto or a fixed band), bias tee, and PPM. Rate is 192 kS/s. With LNA and Mixer on, IF gain above about 25 dB can overload it.

The dongle presents itself as a sound card, so each system needs one step:

  • Linux: SDRmm reads it over raw USB and takes it from the sound and HID drivers while it is open. The user needs access to the USB node, for example with SUBSYSTEM=="usb", ATTRS{idVendor}=="04d8", ATTRS{idProduct}=="fb31", MODE="0660", GROUP="plugdev".
  • Windows: raw USB through WinUSB. In Zadig, turn on List All Devices, turn off Ignore Hubs or Composite Parents, pick FUNcube Dongle V2.0 (Composite Parent), and install WinUSB. It then no longer shows up as a sound card.
  • macOS: samples come through Core Audio, since macOS keeps raw USB for its own driver. Allow Microphone for SDRmm (or the terminal running sdrmm) in System Settings, or the node reports silence.

Tested on hardware provided by FUNcube Dongle. Thank you.

ESP-SDR

An ESP32 running ESP-SDR firmware receives with its Wi-Fi radio. Flash it with the browser installer.

It captures bursts, not a stream: 4096 samples by default, then a pause while they cross the serial link, about 0.1 s at 921.6 kBd. Longer bursts update the Scope less often. The timeline marks each gap.

ControlDoes
Frequency100 MHz to 6 GHz in 1 MHz steps; only 2.4 GHz (and 5 GHz on C5) is reliable
Rate80, 40 or 16 MS/s on ESP32, per chip otherwise
TunerGain index, not dB. Auto is the hardware AGC.
BWAnalog bandwidth, or auto for widest
Bits8 or 10 bits per sample; 10 is slower over serial
BurstSamples per capture

SDRmm finds the firmware at 2 MBd, 1 MBd or 921.6 kBd. A CP2102 bridge cannot reach 1 MBd, so build the firmware with CONFIG_ESP_SDR_UART_BAUD=921600 for those boards. On Linux, add the server's user to dialout.

Ethernet: an ESP32-S31 board with the esp32s31-stream firmware streams without gaps: 2150 to 2800 MHz, 4 to 40 MS/s, 8 bits. Add it under Network as ESP-SDR with the IP its serial log prints. It needs a Gigabit link for 40 MS/s.

AntSDR

SDRmm talks to the iiod server of the AntSDR's Pluto firmware directly, with no libiio. The E310 has two receive lanes on one synthesizer, so they are phase coherent. UHD firmware is not supported. MicroPhase ships UHD images for the E200 and E316 only; the e310v2 target in antsdr_uhd is the E316 and does not run on an E310.

USB: connect the USB 2.0 port and the board appears with no network setup. Windows needs the PlutoSDR drivers.

Ethernet, direct cable: the board sits at 192.168.1.10. Give the computer's Ethernet port a fixed address in the same range once, and leave the router empty so the internet stays on Wi-Fi:

SystemWhere
macOSSystem Settings, Network, the Ethernet adapter, Details, TCP/IP. Configure IPv4 Manually, IP 192.168.1.100, subnet mask 255.255.255.0
WindowsSettings, Network & internet, Ethernet, IP assignment, Edit. Manual, IPv4 on, IP 192.168.1.100, subnet mask 255.255.255.0
Linuxnmcli connection add type ethernet ifname <port> con-name antsdr ipv4.method manual ipv4.addresses 192.168.1.100/24

Ethernet, through your router: if your network already uses 192.168.1.x and nothing else sits at .10, plug the board into the router and it works from every computer on it. Otherwise give the board a free address in your range: connect it over USB, open the drive it shows, set ipaddr_eth and netmask_eth in config.txt, and eject. Over SSH the login is root / analog.

Empty Device nodes look for a board at ant.local, 192.168.1.10, pluto.local, and 192.168.2.1; enter any other address in the Network tab. If nothing is found, ping 192.168.1.10: no answer means the cable or the computer's address.

Ethernet carries far more than USB 2.0, and two lanes split the link. The RX1 and RX2 toggles pick which receivers stream, one or both. The E310 locks its antenna and TX ports in firmware, so those menus are hidden. The other controls are the AD936x ones.

Faster streaming: sdrmm-iqlinkd runs on the board and sends samples over UDP, about 20 MS/s on one lane instead of 15 with iiod. SDRmm uses it by itself when it answers on port 30432, and iiod otherwise. Install it once:

rustup target add armv7-unknown-linux-musleabihf
cargo build --release --target armv7-unknown-linux-musleabihf -p sdrmm-iqlinkd
scp -O target/armv7-unknown-linux-musleabihf/release/sdrmm-iqlinkd root@192.168.1.10:/mnt/jffs2/
ssh root@192.168.1.10 'echo "/mnt/jffs2/sdrmm-iqlinkd > /tmp/iqlinkd.log 2>&1 &" > /mnt/jffs2/autorun.sh; reboot'

Tested on hardware provided by MicroPhase. Thank you.

PlutoSDR and other AD936x boards

Talks to iiod directly over USB or Ethernet, with no libiio or SoapySDR. USB boards appear automatically, and network boards at pluto.local, 192.168.2.1, ant.local, or 192.168.1.10.

The board reports its range: typically 70 MHz to 6 GHz on an AD9361, 325 MHz to 3.8 GHz on an AD9363. Rates run from about 260 kS/s to 61.44 MS/s; below 2.08 MS/s the FPGA decimates. The link sets the real limit. On a 2×2 board both RX lanes share a clock and are phase coherent.

ControlDoes
−/+1 or 2 lanes on a 2×2 board. Starts at 1, which gets the whole link
TunerReceive gain per lane. The range follows the band
TXTransmit attenuation per lane
AGCPer lane: fast attack, slow attack, or hybrid
FilterAnalog bandwidth
TrackingQuadrature, RF DC and baseband DC corrections
ToneTwo DDS test tones on every TX lane, with offset and level. Transmits without a stream
AGCHigh and low thresholds of the gain loop, in dBFS
ChipRate governor, calibration (auto or manual), and state: run, alert, wait or sleep
LOExternal RX or TX LO
Antenna, TX portShown only if the board lets the port change

The face shows chip and FPGA temperature and RSSI per lane, refreshed every second.

A frequency tuned before is recalled from one of 8 fast-lock profiles instead of recalibrating the synthesizer, so a scanner hopping between known channels retunes in about 2 ms instead of 10. The TX synthesizer sleeps while nothing transmits and no tone is on.

Linux needs the libiio udev rules. sdrmm --doctor checks for them.

SDRplay

Install the SDRplay API 3.15 or newer and keep sdrplay_apiService running. No SoapySDR module needed. If an RSP is missing, see the SDRplay API section of sdrmm --doctor. For containers, see SDRplay receivers. For NixOS, see Nix.

Both gain sliders raise gain when moved up:

SliderSets
RFLNA gain. The steps depend on frequency, port, and HDR mode.
IF0 to 39 dB

AGC runs the IF gain at 5, 50, or 100 Hz.

Rates run from 62.5 kS/s to 10.66 MS/s on one tuner.

RSPduo: each mode is its own entry: Tuner 1, Tuner 2, Dual Tuner, Master (on either tuner), and Slave. Modes in use by another program are hidden. Dual Tuner gives two independent streams at up to 2 MS/s each. Slave waits for a master program, which owns the clock.

SDRconnect

Reach an RSP on another machine through SDRconnect, with no local SDRplay API. Enable its WebSocket API, or run SDRconnect_headless --websocket_port=5454. On a Device node pick Network → SDRconnect and enter host:5454, or host:5454/secondary for an RSPduo's second tuner.

The link is unencrypted ws://. Use it on a trusted network or through a tunnel.

SDRmm receives raw IQ and does its own demodulation. Settings:

SettingDoes
LNARF gain over the LNA states; lower means more gain. There is no IF gain.
Device VFOSDRconnect's VFO inside the sampled window
FilterSDRconnect's channel filter
ReceiverWhich radio: name, slot, or serial
Network modeStream quality
Device profileLoad a saved SDRconnect profile
RecordingRecord on the SDRconnect machine

The driver follows the public SDRplay API specification. No vendor code is included.

Aaronia SPECTRAN V6

Install the RTSA-Suite PRO. SDRmm loads its RTSA API at runtime; nothing else is needed. Aaronia ships no macOS version. On Linux, run the suite's setup_udev.sh once. Set SDRMM_AARONIA_DIR to the suite's folder if it is not in the default place, and check it with sdrmm --doctor. Close the RTSA-Suite before opening the radio here.

ControlSets
GAINThe reference level, reversed: 20 dB gain is a -20 dBm reference, which reads as full scale
AntennaRx1 or Rx2, V6 only
Amplifier, RX filter, USB compressionAs the radio lists them

The rate is the span times 1.5, so the clean part is two thirds of the rate. The slowest receiver clock that carries the rate is picked for you.

Transmit is half duplex: the radio reopens as a transmitter and back. Full scale sends 0 dBm before the TX gain.

The driver follows the public RTSA API interface. No vendor code is included.

KiwiSDR

Pick Network → KiwiSDR and paste the receiver's address, http:// or https://. Public receivers are listed at rx.kiwisdr.com. A private Kiwi, or one whose time limits a password lifts, takes password@host:8073. The password becomes part of the radio's address in the workspace.

A Kiwi streams 12 or 20 kHz of IQ anywhere in 0 to 30 MHz: enough for SSB, CW, AM and the narrowband decoders. Wider channels show the width they need. Gain is the Kiwi's AGC or a manual RF gain.

Public Kiwis are shared. When one is full, kicks you, or hits its time limit, SDRmm stops and does not reconnect. A dropped connection is retried.

Dragon Labs CR-8

Eight phase-coherent lanes on one Device, iq1 to iq8. All lanes tune together, 24 MHz to 1.766 GHz, at a fixed 12.5 MS/s, with LNA, Mixer, and VGA gain per lane in firmware steps. Clock source is internal or external.

The packaged builds leave CR-8 out. Build the server with cr8, install the vendor library, and check it with sdrmm --doctor. Set SDRMM_DLCR_LIBRARY if the library is somewhere unusual.

SoapySDR

SoapySDR covers radios without a built-in driver. Install the core and a module for your radio:

RadioModule
bladeRFSoapyBladeRF
LimeSDRSoapyLMS7
USRPSoapyUHD
Remote SoapySDR serverSoapyRemote
SystemCoreExample module
Debian, Ubuntu, Raspberry Pi OSsudo apt install libsoapysdr0.8soapysdr-module-bladerf
Fedorasudo dnf install SoapySDRsoapy-uhd
Archsudo pacman -S soapysdrsoapybladerf
macOSbrew install soapysdrpothosware/pothos/soapybladerf
WindowsPothosSDR, default install folderIncluded
NixOSsoapyPlugins

Packaged builds load SoapySDR at runtime and work without it. The container ships the core with bladeRF, LimeSDR, and SoapyRemote modules. A remote SoapySDRServer shows up in the normal radio list, through SoapyRemote.

SDRmm needs SoapySDR 0.9 or 0.8 and modules built for it. For unusual install locations:

VariableValue
SDRMM_SOAPY_LIBRARYFull path to the core library
SOAPY_SDR_ROOTSoapySDR install prefix
SOAPY_SDR_PLUGIN_PATHExtra module folders

SoapySDRUtil --find shows what SoapySDR itself sees. It knows nothing about the built-in drivers, which SDRmm prefers when both could open a radio.

SDRmm probes SoapySDR in a child process, so a crashing module cannot take it down. Set SDRMM_SOAPY_PROBE=in-process to turn that off while debugging.

Other sources

An empty Device node picks these from its own tabs, the same way it picks a radio.

TabGives
RecordingPlays a SigMF recording
VirtualThe signal generator: test signals, from a carrier tone to DVB-T and ATV

Debug builds also list synthetic radios.