You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用USRP B210生成2.4GHz检测信号并生成目标频谱图?

USRP B210 2.4GHz信号频谱图生成问题求助

我是RF与信号处理领域的新手,手里有USRP B210设备,需要采集2.4GHz频段的信号并生成频谱图,用来训练AI模型识别WiFi、蓝牙、无人机这类信号。试过Ettus Research提供的基础代码,也自己改了加低通滤波的版本,但生成的频谱图和预期差很多,求解决办法。


Ettus Research 提供的基础代码

import uhd
import numpy as np

usrp = uhd.usrp.MultiUSRP()

num_samps = 10000 # number of samples received
center_freq = 100e6 # Hz
sample_rate = 1e6 # Hz
gain = 50 # dB

usrp.set_rx_rate(sample_rate, 0)
usrp.set_rx_freq(uhd.libpyuhd.types.tune_request(center_freq), 0)
usrp.set_rx_gain(gain, 0)

# Set up the stream and receive buffer
st_args = uhd.usrp.StreamArgs("fc32", "sc16")
st_args.channels = [0]
metadata = uhd.types.RXMetadata()
streamer = usrp.get_rx_stream(st_args)
recv_buffer = np.zeros((1, 1000), dtype=np.complex64)

# Start Stream
stream_cmd = uhd.types.StreamCMD(uhd.types.StreamMode.start_cont)
stream_cmd.stream_now = True
streamer.issue_stream_cmd(stream_cmd)

# Receive Samples
samples = np.zeros(num_samps, dtype=np.complex64)
for i in range(num_samps//1000):
    streamer.recv(recv_buffer, metadata)
    samples[i*1000:(i+1)*1000] = recv_buffer[0]

# Stop Stream
stream_cmd = uhd.types.StreamCMD(uhd.types.StreamMode.stop_cont)
streamer.issue_stream_cmd(stream_cmd)

print(len(samples))
print(samples[0:10])

本人修改后的代码(添加低通滤波)

import uhd
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import butter, lfilter

def butter_lowpass_filter(data, cutoff_freq, sample_rate, order=5):
    nyquist = 0.5 * sample_rate
    normal_cutoff = cutoff_freq / nyquist
    b, a = butter(order, normal_cutoff, btype='low', analog=False)
    y = lfilter(b, a, data)
    return y

usrp = uhd.usrp.MultiUSRP()

num_samps = 1000000
center_freq = 2.4e9
sample_rate = 1e7
gain = 2
duration = 0.25
order = 10
cutoff_frequency = 2.5e6
denoised_samples = butter_lowpass_filter(samples, cutoff_frequency, sample_rate, order)


usrp.set_rx_rate(sample_rate, 0)
usrp.set_rx_freq(uhd.libpyuhd.types.tune_request(center_freq), 0)
usrp.set_rx_gain(gain, 0)

st_args = uhd.usrp.StreamArgs("fc32", "sc16")
st_args.channels = [0]
metadata = uhd.types.RXMetadata()
streamer = usrp.get_rx_stream(st_args)
recv_buffer = np.zeros((1, 1000), dtype=np.complex64)

stream_cmd = uhd.types.StreamCMD(uhd.types.StreamMode.start_cont)
stream_cmd.stream_now = True
streamer.issue_stream_cmd(stream_cmd)

samples = np.zeros(num_samps, dtype=np.complex64)
for i in range(num_samps // 1000):
    streamer.recv(recv_buffer, metadata)
    samples[i * 1000:(i + 1) * 1000] = recv_buffer[0]

stream_cmd = uhd.types.StreamCMD(uhd.types.StreamMode.stop_cont)
streamer.issue_stream_cmd(stream_cmd)

denoised_samples = butter_lowpass_filter(samples, cutoff_frequency, sample_rate)

print(len(denoised_samples))
print(denoised_samples[0:10])

plt.specgram(denoised_samples, NFFT=int(duration * sample_rate), Fs=sample_rate, noverlap=int(duration * sample_rate * 0.9), cmap='viridis')
plt.xlabel('Time (s)')
plt.ylabel('Frequency (Hz)')
plt.title('Spectrogram aver filter pass-bas 2')
cbar = plt.colorbar()
cbar.set_label('Intensity (dB)')


plt.show()

频谱图对比

当前生成的频谱图

当前生成的频谱图

预期目标频谱图

预期目标频谱图


问题分析与解决建议

1. 代码中的明显错误

  • 开头提前调用了butter_lowpass_filter(samples, ...),但此时samples还未定义,直接删除这行无效代码。
  • 增益设置过低:USRP B210增益范围为0-76dB,你设的2dB会导致信号过弱,噪声完全掩盖有用信号。建议从30dB开始逐步调高,同时观察采样值幅度是否接近±1(避免削波)。

2. 频谱图参数调整

  • NFFT大小:当前用0.25*1e7=2500000作为NFFT,时间分辨率极低,看不到信号的时间变化。换成2048/4096这类2的幂数,平衡时间与频率分辨率。
  • 强度刻度:plt.specgram默认用线性刻度,添加scale='dB'参数才能和预期的dB刻度频谱图一致。
  • 频率轴优化:把ylabel改为“相对于2.4GHz的频率偏移(Hz)”,并通过plt.ylim(-sample_rate/2, sample_rate/2)确保显示全带宽,更直观。
  • 重叠率:0.9的重叠率没问题,但配合过大的NFFT会导致时间轴稀疏,调整NFFT后再微调。

3. 滤波方案优化

  • 你用的2.5MHz低通滤波会把WiFi(20MHz带宽)这类有用信号滤掉,完全没必要。如果要降噪,改用带通滤波,通带设为2.4GHz±10MHz;或者先去掉滤波,看原始信号的频谱情况。

4. 采样稳定性检查

  • 添加代码检查采样时的错误状态,避免丢包影响数据:
if metadata.error_code != uhd.types.RXMetadataErrorCode.none:
    print(f"采样错误: {metadata.strerror()}")
  • 确保USRP使用内部时钟稳定(默认设置即可,有外部参考源可优先使用)。

调整后的频谱图生成示例

# 直接使用原始采样,去掉不必要的滤波
plt.specgram(samples, NFFT=4096, Fs=sample_rate, noverlap=3072, scale='dB', cmap='viridis')
plt.xlabel('时间(s)')
plt.ylabel('相对于2.4GHz的频率偏移(Hz)')
plt.title('2.4GHz频段频谱图')
cbar = plt.colorbar()
cbar.set_label('强度(dB)')
plt.ylim(-sample_rate/2, sample_rate/2)
plt.show()

内容的提问来源于stack exchange,提问作者PSY

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 22:34:59