如何解决如何使用 rtlsdr 作为源对特定频率进行带通滤波器?
我对 Python 和 rtlsdr 的世界仍然很陌生,但我正在使用 RaspBerry Pi 开展一个项目,以便在听到无线电信号时触发警告灯。
在较高的层面上,我的项目使用外部天线用于 2 米无线电频段,该天线连接到插入 RaspBerry Pi 的 rtl-sdr 加密狗。我有一个标准继电器连接到 GPIO 引脚,当它“听到”信号时会打开灯。
我真的不在乎 99% 的输入信号。我只想知道什么时候有 147.3MHz 的载波,让 GPIO 开灯。而已。不多也不少。这当然可以简单地完成吗?我已经阅读了 scipy.signal.butter 带通滤波器,但我无法让它在这个频率下工作。
我的代码在下面,我欢迎任何改进建议,但理想情况下,我正在寻找一种方法来让程序识别 147.3MHz 中心频率处的峰值,然后调用我的“warning_lights.py”脚本。
import RPi.GPIO as GPIO
from rtlsdr import *
from scipy import signal
import peakdetect
import datetime
import sys
import subprocess
def restart():
import subprocess
import time
time.sleep(120)
command = "/usr/bin/sudo /sbin/shutdown -r Now"
process = subprocess.Popen(command.split(),stdout=subprocess.PIPE)
output = process.communicate()[0]
print (output)
# configure SDR device and settings
sdr = RtlSdr()
sdr.sample_rate = 2.4e6 # Hz
sdr.center_freq = 147.3e6 # Hz
sdr.gain = 'auto' # Possible values are 0.0 0.9 1.4 2.7 3.7 7.7 8.7 12.5 14.4 15.7 16.6 19.7 20.7 22.9 25.4 28.0 29.7 32.8 33.8 36.4 37.2 38.6 40.2 42.1 43.4 43.9 44.5 48.0 49.6
num_samples = 1024*1024
procs = []
while True:
try:
samples = sdr.read_samples(num_samples)
power,psd_freq = psd(samples,nfft=1024,Fs=sdr.sample_rate/1e6,Fc=sdr.center_freq/1e6)
power_db = 10*np.log10(power)
maxima,minima = peakdetect.peakdetect(power_db,psd_freq,delta=1)
for mx in maxima:
if mx[0] == 147.3: #checking that peak was on 147.3 MHz
if mx[1] > (-15): #checking dBm of signal
try:
while proc.poll() is None:
proc.terminate()
except:
print("Warning lights not on. Turning them on.")
finally:
print(mx[1])
proc = subprocess.Popen([sys.executable,'/home/pi/scripts/warning_lights.py'])
procs.append(proc)
except:
restart()
解决方法
当您调到 147.3MHz 时,您从 SDR 中得到的不是输入端出现的实际无线电信号。 SDR 将射频信号的频率降低到更容易处理和数字化的较低频率。结果,以 147.3MHz 为中心的原始信号部分向下移动到 0Hz,进入所谓的“基带”。特定带宽(在您的情况下为 2.4MHz)之外的所有内容都会被过滤掉。因此,例如,如果在 148.3MHz 处有一个纯正弦信号,这将在您的 SDR 输出中显示为 1MHz 正弦信号。考虑一个频谱图来形象化这个非常有帮助: Wikipedia article on baseband。
因此,如果有一个以 147.3MHz 为中心的无线电信号,您将不会在 SDR 的输出中看到 147.3MHz,而是在 0Hz(由于 SDR 电路的频率不是完全准确)。正如您提到的,这应该很容易使用 scipy 进行过滤。
还有另一个问题可能是个问题。大多数 SDR 在它们被调谐到的频率上产生一个小的频率峰值(称为“DC 尖峰”)。在我的 RTL-SDR 中,我发现增益很低时就是这种情况。解决此问题的方法是调谐到您感兴趣的信号带宽之外的频率(例如 147.5MHz 可以工作),然后在您的处理过程中补偿这种变化。
因此,应该起作用的是:
# configure SDR device and settings
sdr = RtlSdr()
offset_freq = 200e3 # Hz
sdr.sample_rate = 2.4e6 # Hz
sdr.center_freq = 147.3e6 - offset_freq # Hz
sdr.gain = 'auto' # Possible values are 0.0 0.9 1.4 2.7 3.7 7.7 8.7 12.5 14.4 15.7 16.6 19.7 20.7 22.9 25.4 28.0 29.7 32.8 33.8 36.4 37.2 38.6 40.2 42.1 43.4 43.9 44.5 48.0 49.6
num_samples = 1024*1024
procs = []
while True:
try:
samples = sdr.read_samples(num_samples)
power,psd_freq = psd(samples,NFFT=1024,Fs=sdr.sample_rate/1e6,Fc=sdr.center_freq/1e6)
power_db = 10*np.log10(power)
maxima,minima = peakdetect.peakdetect(power_db,psd_freq,delta=1)
for mx in maxima:
if mx[0] == offset_freq: #checking that peak was on 147.3 MHz
if mx[1] > (-15): #checking dBm of signal
try:
while proc.poll() is None:
proc.terminate()
except:
print("Warning lights not on. Turning them on.")
finally:
print(mx[1])
proc = subprocess.Popen([sys.executable,'/home/pi/scripts/warning_lights.py'])
procs.append(proc)
except:
restart()
这在图像中没有说明,但您也可以从低于载波的任何频率获得信号中的负频率。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。