首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何获得复数RTL-SDR信号峰的坐标?

如何获得复数RTL-SDR信号峰的坐标?
EN

Stack Overflow用户
提问于 2018-03-19 16:21:12
回答 4查看 1.4K关注 0票数 0

我可以通过使用以下命令从RTL-SDR捕获信号:

代码语言:javascript
复制
from rtlsdr import *

i = 0
signals = []
sdr = RtlSdr()

sdr.sample_rate = 2.8e6     
sdr.center_freq = 434.42e6
sdr.gain = 25

while True:
    samples = sdr.read_samples(1024*1024)
    decibel = 10*log10(var(samples))
    if decibel >= -10:
        signals.append(samples)
        i += 1
    if i == 2:
        break

如果我使用Matplotlib和Seaborn绘制信号,它们看起来像这样:

现在,我需要的是获得高于某个功率电平的所有峰值的坐标,例如-20。

我发现了一个非常有希望的各种Python options的列表。然而,所有这些示例都使用了一个简单的Numpy数组,不同的算法可以很容易地使用它。

这是最好的尝试(因为我的猜测是我从RTL-SDR得到一个复杂的信号,并且必须将其“转换”为具有实值的数组?):

代码语言:javascript
复制
import numpy as np
import peakutils.peak

real_sig = np.real(signals[0])
indexes = peakutils.peak.indexes(real_sig, thres=-20.0/max(real_sig), min_dist=1)
print("Peaks are: %s" % (indexes))

将这几行添加到上面的脚本中,我确实得到了一些输出,但是,首先,对于功率级别-20以上的五个峰值,有太多的值。其次,这些值在给定的上下文中没有多大意义。

那么,我需要做哪些更改才能得到像"Peak 1 is at 433.22 MHz“这样有意义的结果呢?

理想情况下,我应该得到像Peak 1: X = 433.22, Y = -18.0这样的坐标,但我想一旦我知道如何获得正确的X值,我就可以自己解决这个问题。

EN

回答 4

Stack Overflow用户

发布于 2018-03-20 01:53:17

您缺少几个步骤。

您首先需要:从长度为N的RTL-SDR中选取一段复数IQ数据(您可能需要将原始IQ样本从无符号8位转换为有符号浮点),对其进行窗口(von Hann或Hamming等),通过长度为N的FFT将其转换到频域,将FFT结果转换为对数幅度,并按频率标记FFT对数幅度结果bit(例如数组元素),其大致为

代码语言:javascript
复制
frequency(i) = sdr.center_freq + i * sdr.sample_rate / N

对于仓位0到N/2

代码语言:javascript
复制
frequency(i) = sdr.center_freq - (N - i) * sdr.sample_rate / N

对于仓位N/2到N-1

然后,您可以沿着对数幅度数组搜索峰值,并将频率标签应用于找到的峰值。

新增:不能直接从RTL-SDR获取频域信息(如频率峰值)。你想要的高峰并不在那里。RTL-SDR输出原始复数/IQ时域样本,而不是频域数据。因此,首先您需要查找、研究并了解两者之间的区别。然后你可能会理解为什么FFT (或DFT,或Goertzels,或小波,等等)进行转换所需的。

票数 1
EN

Stack Overflow用户

发布于 2018-03-20 03:32:41

类似于:

得到y值相对幂的signals数组。

代码语言:javascript
复制
sort([x for x in signals > -20])
sort[:i]

对于第一个山峰。

对于频率范围:

代码语言:javascript
复制
frequency_peaks = [ frequencyspectrum[a] for a in signals[:i]]

但实际上,你应该使用Fourrier变换和装箱(@hotpaw2的答案):

numpy.fft可以做到这一点:

https://docs.scipy.org/doc/numpy-1.13.0/reference/routines.fft.html

另请参阅:

https://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem

背景理论。

票数 1
EN

Stack Overflow用户

发布于 2018-03-20 02:59:40

我现在已经尝试了以下代码(灵感来自hotpaw2的答案和我在谷歌上找到的东西):

代码语言:javascript
复制
from numpy.fft import fft, fftshift
window = np.hamming(sdr.sample_rate/1e6+1)

plt.figure()
A = fft(window, 2048) / 25.5 # what do these values mean?
mag = np.abs(fftshift(A))
freq = np.linspace(sdr.center_freq/1e6-(sdr.sample_rate/1e6)/2, sdr.center_freq/1e6+(sdr.sample_rate/1e6)/2, len(A))
response = 20 * np.log10(mag)
#response = np.clip(response, -100, 100)
plt.plot(freq, response)
plt.title("Frequency response of Hamming window")
plt.ylabel("Magnitude [dB]")
plt.xlabel("Normalized frequency [cycles per sample]")
plt.axis("tight")
plt.show()

来源:https://docs.scipy.org/doc/numpy-1.14.0/reference/generated/numpy.hamming.html

这将导致以下(绝对无用的)信号图:

我需要一个像我的原始帖子中的PSD一样的图,在其中我可以检测峰值。

有人能给我解释一下为什么我要做这些Hamming/FFT的事情吗?

我所需要的就是我的信号(由RTL-SDR接收到)的表示,peakutils.peak.indexes()方法接受并返回其中的正确峰值。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49358449

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档