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

基于Numpy实现RTL-SDR纯Python控制台频谱监测程序开发问询

基于Python+Numpy实现RTL-SDR控制台频谱监测

问题核心

需要从RTL-SDR的IQ样本计算80个线性频段(3.125kHz分辨率)的相对功率,仅依赖Python和Numpy用于控制台可视化,此前FFT尝试未正确捕捉目标信号。

解决方案实现

核心通过加窗FFT计算功率谱,再将频域数据分块平均得到目标频段的功率值。以下是完整代码及说明:

import numpy as np
from rtlsdr import RtlSdr

def get_spectrum(samples, sample_rate, freq_resolution):
    # 1. 加汉宁窗抑制频谱泄露
    window = np.hanning(len(samples))
    windowed_samples = samples * window

    # 2. 计算FFT得到频域数据
    fft_result = np.fft.fft(windowed_samples)

    # 3. 计算相对功率谱(幅度平方,无需绝对单位)
    power_spectrum = np.abs(fft_result) ** 2

    # 4. 调整频谱顺序,对应中心频率-125kHz到+125kHz的范围
    shifted_spectrum = np.fft.fftshift(power_spectrum)

    # 5. 将频谱分块为目标频段数,计算每块平均功率
    num_bins = int(sample_rate / freq_resolution)
    chunk_size = len(shifted_spectrum) // num_bins
    # 截断到能被分块整除的长度
    trimmed_spectrum = shifted_spectrum[:chunk_size * num_bins]
    # 分块并取均值
    binned_spectrum = trimmed_spectrum.reshape(num_bins, chunk_size).mean(axis=1)

    return binned_spectrum

sdr = RtlSdr()
sdr.sample_rate = 250_000
sdr.center_freq = 446_000_000
sdr.gain = 40
duration = 0.100  # 采样时长100ms
sdr.read_samples(2048)  # 丢弃初始无效样本

while True:
    samples = sdr.read_samples(int(duration * sdr.sample_rate))
    spectrum = get_spectrum(
        samples=samples,
        sample_rate=sdr.sample_rate,
        freq_resolution=sdr.sample_rate / 80  # 80个频段对应3.125kHz分辨率
    )
    # 归一化到0-9用于控制台可视化
    min_val = np.min(spectrum)
    max_val = np.max(spectrum)
    # 处理极端情况(避免除以0)
    if max_val - min_val < 1e-6:
        scaled_data = np.zeros_like(spectrum)
    else:
        scaled_data = 9 * ((spectrum - min_val) / (max_val - min_val))
    # 打印频谱(数字高度代表功率)
    print(''.join(str(int(v)) for v in scaled_data))

关键步骤说明

  1. 加窗处理:汉宁窗(np.hanning)是解决此前无信号反应的核心——未加窗会导致严重频谱泄露,目标信号能量被分散到多个FFT bin中,无法形成明显峰值。
  2. FFT与功率谱:复数IQ样本的FFT幅度平方直接对应相对功率,完全满足可视化对比需求。
  3. 频谱顺序调整:np.fft.fftshift将FFT默认的0~Fs频率范围转换为-Fs/2~Fs/2,完美匹配RTL-SDR中心频率左右的带宽(445.875MHz~446.125MHz)。
  4. 分块平均:将25000个FFT点平均分为80块,每块对应3.125kHz频段,既平滑噪声又得到目标分辨率的频谱数据。

额外优化建议

  • 可累计多次采样的频谱数据取平均,进一步降低噪声,让可视化更稳定。
  • 替换实时min/max归一化为滑动窗口统计(如最近10次的极值),避免频谱显示频繁跳变。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 03:14:51