USRP
USRP (Universal Software Radio Peripheral) — професійна SDR платформа від Ettus Research.
Огляд
Лінійка продуктів
| Серія |
Призначення |
Ціна |
| B-серія |
Настільні |
$700-2000 |
| N-серія |
Мережеві |
$3000-6000 |
| X-серія |
Високопродуктивні |
$6000-15000 |
| E-серія |
Embedded |
$3000-5000 |
USRP B200/B210
| Параметр |
B200 |
B210 |
| Частоти |
70 МГц - 6 ГГц |
70 МГц - 6 ГГц |
| Ширина |
56 МГц |
56 МГц |
| Канали |
1x1 |
2x2 MIMO |
| ADC/DAC |
12 біт |
12 біт |
| Інтерфейс |
USB 3.0 |
USB 3.0 |
| FPGA |
Spartan-6 |
Spartan-6 |
USRP N310
| Параметр |
Значення |
| Частоти |
10 МГц - 6 ГГц |
| Ширина |
100 МГц |
| Канали |
4x4 MIMO |
| Інтерфейс |
10GbE |
| Синхронізація |
GPS, PPS, 10 МГц |
Встановлення UHD
Linux
# Ubuntu/Debian
sudo apt install uhd-host libuhd-dev
# Завантажити FPGA images
sudo uhd_images_downloader
# Перевірка
uhd_find_devices
uhd_usrp_probe
Збірка з джерел
git clone https://github.com/EttusResearch/uhd.git
cd uhd/host
mkdir build && cd build
cmake ..
make -j$(nproc)
sudo make install
sudo ldconfig
Windows
1. Завантажити UHD інсталятор з Ettus
2. Встановити
3. Додати в PATH
4. uhd_images_downloader
Базове використання
Виявлення пристроїв
# Пошук
uhd_find_devices
# Детальна інформація
uhd_usrp_probe
# З параметрами
uhd_usrp_probe --args "type=b200"
Командна строка
# Прийом
uhd_rx_cfile -f 100e6 -r 1e6 -g 30 rx.bin
# Передача
uhd_tx_cfile -f 100e6 -r 1e6 -g 30 tx.bin
# Benchmark
uhd_benchmark_rate --rx_rate 10e6 --tx_rate 10e6
Параметри
--args Параметри пристрою
-f, --freq Центральна частота
-r, --rate Sample rate
-g, --gain Підсилення
-A, --ant Антена (TX/RX, RX2)
-c, --chan Канал (для MIMO)
GNU Radio
Встановлення
sudo apt install gnuradio
UHD блоки
| Блок |
Призначення |
| UHD: USRP Source |
Прийом |
| UHD: USRP Sink |
Передача |
Приклад flowgraph
#!/usr/bin/env python3
from gnuradio import gr, uhd, blocks, analog
class usrp_rx(gr.top_block):
def __init__(self):
gr.top_block.__init__(self)
# USRP джерело
self.usrp = uhd.usrp_source(
device_addr="",
stream_args=uhd.stream_args(
cpu_format="fc32",
channels=[0]
)
)
self.usrp.set_samp_rate(1e6)
self.usrp.set_center_freq(100e6)
self.usrp.set_gain(30)
# Запис у файл
self.sink = blocks.file_sink(gr.sizeof_gr_complex, "rx.bin")
self.connect(self.usrp, self.sink)
Python API
Прийом
import uhd
import numpy as np
# Створити USRP
usrp = uhd.usrp.MultiUSRP()
# Налаштування
usrp.set_rx_rate(1e6)
usrp.set_rx_freq(uhd.types.TuneRequest(100e6))
usrp.set_rx_gain(30)
# Streamer
st_args = uhd.usrp.StreamArgs("fc32", "sc16")
rx_streamer = usrp.get_rx_stream(st_args)
# Прийом
metadata = uhd.types.RXMetadata()
buffer = np.zeros(1000, dtype=np.complex64)
stream_cmd = uhd.types.StreamCMD(uhd.types.StreamMode.start_cont)
rx_streamer.issue_stream_cmd(stream_cmd)
num_samps = rx_streamer.recv(buffer, metadata)
print(f"Received {num_samps} samples")
Передача
import uhd
import numpy as np
usrp = uhd.usrp.MultiUSRP()
usrp.set_tx_rate(1e6)
usrp.set_tx_freq(uhd.types.TuneRequest(100e6))
usrp.set_tx_gain(30)
st_args = uhd.usrp.StreamArgs("fc32", "sc16")
tx_streamer = usrp.get_tx_stream(st_args)
# Генерація сигналу
samples = np.exp(1j * 2 * np.pi * np.arange(1000) / 100)
metadata = uhd.types.TXMetadata()
tx_streamer.send(samples.astype(np.complex64), metadata)
Синхронізація
Зовнішня опора
# 10 МГц + PPS
uhd_usrp_probe --args "clock_source=external,time_source=external"
GPS (N-серія)
# GPSDO
uhd_usrp_probe --args "clock_source=gpsdo,time_source=gpsdo"
MIMO синхронізація
# Синхронізація каналів
usrp.set_clock_source("internal")
usrp.set_time_now(uhd.types.TimeSpec(0.0))
# Для зовнішньої опори
usrp.set_clock_source("external")
usrp.set_time_source("external")
usrp.set_time_unknown_pps(uhd.types.TimeSpec(0.0))
Daughterboards
Типи
| Плата |
Частоти |
TX/RX |
| WBX |
50 МГц - 2.2 ГГц |
TRx |
| SBX |
400 МГц - 4.4 ГГц |
TRx |
| UBX |
10 МГц - 6 ГГц |
TRx |
| TwinRX |
10 МГц - 6 ГГц |
2x Rx |
| BasicTX/RX |
DC - 250 МГц |
Tx/Rx |
Вибір антени
# Перегляд доступних
print(usrp.get_rx_antennas())
# ['TX/RX', 'RX2', 'CAL']
# Встановлення
usrp.set_rx_antenna("RX2")
Практичні проекти
LTE eNodeB (srsRAN)
# Конфігурація
[rf]
device_name = uhd
device_args = type=b200,num_recv_frames=64,num_send_frames=64
# Запуск
sudo srsenb enb.conf
Radar
# FMCW radar приклад
class FMCWRadar:
def __init__(self):
self.usrp = uhd.usrp.MultiUSRP()
self.bw = 100e6
self.sweep_time = 1e-3
def generate_chirp(self):
t = np.linspace(0, self.sweep_time, int(self.bw * self.sweep_time))
return np.exp(1j * np.pi * self.bw/self.sweep_time * t**2)
Spectrum Sensing
def spectrum_scan(start_freq, end_freq, step):
usrp = uhd.usrp.MultiUSRP()
usrp.set_rx_rate(20e6)
results = []
for freq in np.arange(start_freq, end_freq, step):
usrp.set_rx_freq(uhd.types.TuneRequest(freq))
samples = receive_samples(usrp, 10000)
power = 10 * np.log10(np.mean(np.abs(samples)**2))
results.append((freq, power))
return results
Оптимізація
USB Buffer
# Збільшити буфер
uhd_usrp_probe --args "num_recv_frames=128"
Network (N-серія)
# MTU 9000 (jumbo frames)
sudo ip link set eth0 mtu 9000
# Аргументи
uhd_usrp_probe --args "addr=192.168.10.2,recv_frame_size=8000"
Sample rate
B200: до 56 MSPS
N310: до 100 MSPS
Стабільні значення:
- USB: 1, 2, 5, 10, 20, 25 MSPS
- Ethernet: кратні master clock
Troubleshooting
Пристрій не знайдено
# USB
lsusb | grep Ettus
sudo dmesg | tail
# Мережа
uhd_find_devices --args "addr=192.168.10.2"
Dropped samples
O: overflow (прийом)
U: underflow (передача)
Рішення:
1. Зменшити sample rate
2. Збільшити буфери
3. Перевірити USB/мережу
Late commands
L: пізні команди
Рішення:
1. Збільшити затримку
2. Синхронізувати час
3. Зменшити навантаження CPU