Initial hackrf_sweep skeleton
This commit is contained in:
parent
6cf2694708
commit
a3ce184f5e
@ -5,7 +5,7 @@ import sys, signal, time
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from qspectrumanalyzer.version import __version__
|
||||
from qspectrumanalyzer.backend import RtlPowerThread, RtlPowerFftwThread
|
||||
from qspectrumanalyzer.backend import RtlPowerThread, RtlPowerFftwThread, HackRFSweepThread
|
||||
from qspectrumanalyzer.data import DataStorage
|
||||
from qspectrumanalyzer.plot import SpectrumPlotWidget, WaterfallPlotWidget
|
||||
from qspectrumanalyzer.utils import color_to_str, str_to_color
|
||||
@ -186,6 +186,9 @@ class QSpectrumAnalyzerMainWindow(QtGui.QMainWindow, Ui_QSpectrumAnalyzerMainWin
|
||||
backend = settings.value("backend", "rtl_power")
|
||||
if backend == "rtl_power_fftw":
|
||||
self.rtl_power_thread = RtlPowerFftwThread(self.data_storage)
|
||||
elif backend == "hackrf_sweep":
|
||||
self.rtl_power_thread = HackRFSweepThread(self.data_storage)
|
||||
print(self.rtl_power_thread)
|
||||
else:
|
||||
self.rtl_power_thread = RtlPowerThread(self.data_storage)
|
||||
|
||||
|
@ -267,3 +267,85 @@ class RtlPowerFftwThread(RtlPowerBaseThread):
|
||||
pass
|
||||
|
||||
self.prev_line = line
|
||||
|
||||
class HackRFSweepThread(RtlPowerBaseThread):
|
||||
"""Thread which runs hackrf_sweep process"""
|
||||
def setup(self, start_freq, stop_freq, bin_size, interval=10.0, gain=-1,
|
||||
ppm=0, crop=0, single_shot=False, device_index=0, sample_rate=2560000):
|
||||
"""Setup hackrf_sweep params"""
|
||||
crop = crop * 100
|
||||
overlap = crop * 2
|
||||
freq_range = stop_freq * 1e6 - start_freq * 1e6
|
||||
min_overhang = sample_rate * overlap * 0.01
|
||||
hops = math.ceil((freq_range - min_overhang) / (sample_rate - min_overhang))
|
||||
overhang = (hops * sample_rate - freq_range) / (hops - 1) if hops > 1 else 0
|
||||
bins = math.ceil(sample_rate / (bin_size * 1e3))
|
||||
crop_freq = sample_rate * crop * 0.01
|
||||
|
||||
self.params = {
|
||||
"start_freq": start_freq,
|
||||
"stop_freq": stop_freq,
|
||||
"freq_range": freq_range,
|
||||
"device_index": device_index,
|
||||
"sample_rate": sample_rate,
|
||||
"bin_size": bin_size,
|
||||
"bins": bins,
|
||||
"interval": interval,
|
||||
"hops": hops,
|
||||
"time": interval / hops,
|
||||
"gain": gain * 10,
|
||||
"ppm": ppm,
|
||||
"crop": crop,
|
||||
"overlap": overlap,
|
||||
"min_overhang": min_overhang,
|
||||
"overhang": overhang,
|
||||
"single_shot": single_shot
|
||||
}
|
||||
self.freqs = [self.get_hop_freq(hop) for hop in range(hops)]
|
||||
self.freqs_crop = [(f[0] + crop_freq, f[1] - crop_freq) for f in self.freqs]
|
||||
self.databuffer = {"timestamp": [], "x": [], "y": []}
|
||||
self.databuffer_hop = {"timestamp": [], "x": [], "y": []}
|
||||
self.hop = 0
|
||||
self.prev_line = ""
|
||||
|
||||
print("hackrf_sweep params:")
|
||||
pprint.pprint(self.params)
|
||||
print()
|
||||
|
||||
def get_hop_freq(self, hop):
|
||||
"""Get start and stop frequency for particular hop"""
|
||||
start_freq = self.params["start_freq"] * 1e6 + (self.params["sample_rate"] - self.params["overhang"]) * hop
|
||||
stop_freq = start_freq + self.params["sample_rate"] - (self.params["sample_rate"] / self.params["bins"])
|
||||
return (start_freq, stop_freq)
|
||||
|
||||
def process_start(self):
|
||||
"""Start hackrf_sweep process"""
|
||||
if not self.process and self.params:
|
||||
settings = QtCore.QSettings()
|
||||
cmdline = [
|
||||
settings.value("rtl_power_executable", "hackrf_sweep"),
|
||||
]
|
||||
|
||||
self.process = subprocess.Popen(cmdline, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL,
|
||||
universal_newlines=False)
|
||||
|
||||
def parse_output(self, buf):
|
||||
"""Parse one buf of output from hackrf_sweep"""
|
||||
data = np.fromstring(buf, dtype='<f4')
|
||||
print("Got buffer for {}MHz".format(data[0]))
|
||||
|
||||
|
||||
def run(self):
|
||||
"""hackrf_sweep thread main loop"""
|
||||
self.process_start()
|
||||
self.alive = True
|
||||
self.rtlPowerStarted.emit()
|
||||
|
||||
while self.alive:
|
||||
buf = self.process.stdout.read(4*(1+32))
|
||||
if buf:
|
||||
self.parse_output(buf)
|
||||
|
||||
self.process_stop()
|
||||
self.alive = False
|
||||
self.rtlPowerStopped.emit()
|
||||
|
@ -252,37 +252,37 @@
|
||||
<context>
|
||||
<name>QSpectrumAnalyzerSettings</name>
|
||||
<message>
|
||||
<location filename="ui_qspectrumanalyzer_settings.py" line="112"/>
|
||||
<location filename="ui_qspectrumanalyzer_settings.py" line="114"/>
|
||||
<source>rtl_power</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="ui_qspectrumanalyzer_settings.py" line="113"/>
|
||||
<location filename="ui_qspectrumanalyzer_settings.py" line="115"/>
|
||||
<source>...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="ui_qspectrumanalyzer_settings.py" line="110"/>
|
||||
<location filename="ui_qspectrumanalyzer_settings.py" line="111"/>
|
||||
<source>rtl_power_fftw</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="ui_qspectrumanalyzer_settings.py" line="108"/>
|
||||
<location filename="ui_qspectrumanalyzer_settings.py" line="109"/>
|
||||
<source>&Backend:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="ui_qspectrumanalyzer_settings.py" line="111"/>
|
||||
<location filename="ui_qspectrumanalyzer_settings.py" line="113"/>
|
||||
<source>E&xecutable:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="ui_qspectrumanalyzer_settings.py" line="114"/>
|
||||
<location filename="ui_qspectrumanalyzer_settings.py" line="116"/>
|
||||
<source>&Waterfall history size:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="ui_qspectrumanalyzer_settings.py" line="116"/>
|
||||
<location filename="ui_qspectrumanalyzer_settings.py" line="118"/>
|
||||
<source>Sa&mple rate:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -292,15 +292,20 @@
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="ui_qspectrumanalyzer_settings.py" line="107"/>
|
||||
<location filename="ui_qspectrumanalyzer_settings.py" line="108"/>
|
||||
<source>Settings - QSpectrumAnalyzer</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="ui_qspectrumanalyzer_settings.py" line="115"/>
|
||||
<location filename="ui_qspectrumanalyzer_settings.py" line="117"/>
|
||||
<source>&Device index:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="ui_qspectrumanalyzer_settings.py" line="112"/>
|
||||
<source>hackrf_sweep</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QSpectrumAnalyzerSmooth</name>
|
||||
|
@ -38,6 +38,11 @@
|
||||
<string>rtl_power_fftw</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>hackrf_sweep</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
|
@ -37,6 +37,7 @@ class Ui_QSpectrumAnalyzerSettings(object):
|
||||
self.backendComboBox.setObjectName(_fromUtf8("backendComboBox"))
|
||||
self.backendComboBox.addItem(_fromUtf8(""))
|
||||
self.backendComboBox.addItem(_fromUtf8(""))
|
||||
self.backendComboBox.addItem(_fromUtf8(""))
|
||||
self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.backendComboBox)
|
||||
self.label = QtGui.QLabel(QSpectrumAnalyzerSettings)
|
||||
self.label.setObjectName(_fromUtf8("label"))
|
||||
@ -108,6 +109,7 @@ class Ui_QSpectrumAnalyzerSettings(object):
|
||||
self.label_3.setText(_translate("QSpectrumAnalyzerSettings", "&Backend:", None))
|
||||
self.backendComboBox.setItemText(0, _translate("QSpectrumAnalyzerSettings", "rtl_power", None))
|
||||
self.backendComboBox.setItemText(1, _translate("QSpectrumAnalyzerSettings", "rtl_power_fftw", None))
|
||||
self.backendComboBox.setItemText(2, _translate("QSpectrumAnalyzerSettings", "hackrf_sweep", None))
|
||||
self.label.setText(_translate("QSpectrumAnalyzerSettings", "E&xecutable:", None))
|
||||
self.executableEdit.setText(_translate("QSpectrumAnalyzerSettings", "rtl_power", None))
|
||||
self.executableButton.setText(_translate("QSpectrumAnalyzerSettings", "...", None))
|
||||
|
Loading…
Reference in New Issue
Block a user