Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/EttusResearch/uhd/llms.txt

Use this file to discover all available pages before exploring further.

This guide walks you through installing UHD, preparing your USRP device, and running a real receive-to-file example using both the Python and C++ APIs. By the end you will have confirmed that UHD can discover your device and stream complex baseband samples to the host.
1

Install UHD

Choose the installation method that matches your platform and toolchain.Linux (Ubuntu/Debian) — package manager
sudo apt-get update
sudo apt-get install libuhd-dev uhd-host
Linux (Fedora/RHEL) — package manager
sudo dnf install uhd uhd-devel
macOS — Homebrew
brew install uhd
Windows — Download the prebuilt installer from the Ettus Research files server and run it. The installer registers UHD in the system PATH and places the Python bindings in the active Python environment.Build from source — See the UHD build guide for CMake configuration options and dependency lists on all supported platforms.
UHD requires Boost, libusb (for USB devices), and Python 3 with NumPy for the Python bindings. Full dependency lists are in the official build guide.
2

Download FPGA images

USRP devices require FPGA bitfiles that are distributed separately from the UHD driver. After installation, run the bundled downloader to fetch the images that match your installed UHD version:
sudo uhd_images_downloader
The tool downloads only the images for the UHD version you installed and places them in the default image directory (typically /usr/share/uhd/images/ on Linux). Pass --help to see filtering options if you only want images for specific device families.
If your host has no internet access, download the image archive on a connected machine from files.ettus.com/binaries/uhd_images/ and extract it manually to the images directory.
3

Connect your device and verify discovery

Connect your USRP to the host:
  • USB devices (B-Series): Connect the USB 3.0 cable. No IP configuration is required.
  • Ethernet devices (N-Series, X-Series): Connect the 1 GbE or 10 GbE cable. Set the host interface to a static IP in the same subnet as the device (default device IPs are documented per model in the manual).
  • Embedded devices (E-Series): Access over the USB UART or SSH; UHD is pre-installed on the device.
Verify that UHD can discover the device:
uhd_find_devices
A successfully connected device prints output similar to:
[INFO] [UHD] linux; GNU C++ version 11.4.0; Boost_107400;
--------------------------------------------------
-- UHD Device 0
--------------------------------------------------
Device Address:
    serial: 3180E2A
    addr: 192.168.10.2
    name:
    type: x300
Once a device is found, inspect its full hardware configuration:
uhd_usrp_probe
uhd_usrp_probe reports the motherboard type, FPGA image loaded, clock rates, available daughterboards, subdevice specifications, supported sample rates, frequency ranges, and gain ranges. Review this output before configuring your application to understand the actual hardware capabilities.
If uhd_find_devices returns no devices, confirm that the FPGA images were downloaded (uhd_images_downloader), check firewall rules and network configuration for Ethernet devices, and verify USB permissions for B-Series devices (add a udev rule or run with sudo to test).
4

Receive your first samples

With the device discovered, you can stream receive samples to a file using the high-level MultiUSRP API. Choose the Python or C++ tab below.
The UHD Python API exposes uhd.usrp.MultiUSRP, which provides a convenience method recv_num_samps() that handles streamer creation, stream commands, and teardown in a single call. The example below is adapted directly from the host/examples/python/rx_to_file.py source.
#!/usr/bin/env python3
# Receive samples from a USRP and write them to a binary file.
# Adapted from host/examples/python/rx_to_file.py

import numpy as np
import uhd

# --- Parameters ---
args       = "addr=192.168.10.2"   # Device address; empty string = first found
freq       = 2.45e9                # Center frequency in Hz
rate       = 1e6                   # Sample rate in samples/sec
gain       = 10                    # RX gain in dB
duration   = 5.0                   # Capture duration in seconds
channels   = [0]                   # Channel list
output_file = "samples.dat"

# --- Create device ---
usrp = uhd.usrp.MultiUSRP(args)

# --- Receive samples ---
num_samps = int(np.ceil(duration * rate))
samps = usrp.recv_num_samps(num_samps, freq, rate, channels, gain)

# --- Save to file ---
with open(output_file, "wb") as f:
    samps.tofile(f)

print(f"Received {samps.shape[1]} samples, saved to {output_file}")
For more control—such as streaming continuously until a stop condition—use the lower-level streamer API directly. The following pattern is taken from host/docs/driver_usage/stream.dox:
import uhd
import numpy as np

usrp = uhd.usrp.MultiUSRP("addr=192.168.10.2")

# Configure the streamer: fc32 on the host, sc16 over the wire
stream_args = uhd.usrp.StreamArgs("fc32", "sc16")
rx_streamer = usrp.get_rx_stream(stream_args)

rx_metadata = uhd.types.RXMetadata()
recv_buffer = np.zeros(rx_streamer.get_max_num_samps(), dtype=np.complex64)

# Issue a continuous stream command
stream_cmd = uhd.types.StreamCMD(uhd.types.StreamMode.start_cont)
stream_cmd.stream_now = True
rx_streamer.issue_stream_cmd(stream_cmd)

collected = []
for _ in range(100):                           # Collect 100 buffers
    samps = rx_streamer.recv(recv_buffer, rx_metadata)
    collected.append(recv_buffer[:samps].copy())

# Stop the stream
stream_cmd = uhd.types.StreamCMD(uhd.types.StreamMode.stop_cont)
rx_streamer.issue_stream_cmd(stream_cmd)

samples = np.concatenate(collected)
print(f"Total samples received: {len(samples)}")
Install the Python dependencies with:
pip install numpy
# UHD Python bindings are installed with the uhd-host package
The recv_num_samps() convenience method (Python) and the recv() loop pattern (C++) both produce interleaved complex float32 (fc32) samples by default. Each sample is a pair of 32-bit IEEE 754 floats representing the in-phase (I) and quadrature (Q) components.

Verifying Your Capture

After running either example, confirm the output file contains valid IQ data:
import numpy as np

samples = np.fromfile("samples.dat", dtype=np.complex64)
print(f"Samples loaded : {len(samples)}")
print(f"Mean power (dB): {10 * np.log10(np.mean(np.abs(samples)**2)):.1f}")
A non-zero mean power value confirms that the USRP was receiving and streaming RF energy. If the power is near -inf, check that the antenna is connected, the frequency is within the daughterboard’s range, and the gain is set appropriately.

Useful CLI Tools

UHD ships several command-line utilities that are valuable during development:
CommandPurpose
uhd_find_devicesDiscovers all UHD-compatible devices on the host
uhd_usrp_probePrints detailed hardware info: FPGA version, subdevices, supported ranges
uhd_images_downloaderDownloads FPGA bitfiles matching the installed UHD version
rx_samples_to_fileCapture RX samples to disk (see --help for all options)
tx_waveformsTransmit a configurable waveform (CONST, SINE, SQUARE, RAMP)
Run any tool with --help to see the full option list and usage examples.

Next Steps

Coding to the API

Deep-dive into the Multi-USRP, RFNoC, and C API interfaces with annotated examples and best-practice guidance.

Streaming Guide

Understand stream args, over-the-wire data types, overflow/underrun handling, and remote streaming.

Installation Guide

Full installation instructions for Linux, macOS, and Windows, including pre-built packages and build-from-source steps.

Knowledge Base

Application notes, tutorials, and the technical FAQ maintained by Ettus Research.

Build docs developers (and LLMs) love