Add support for multiple RTL-SDR devices (select device index in settings)

This commit is contained in:
Michal Krenek (Mikos) 2016-05-19 22:28:44 +02:00
parent 4e7818536c
commit 6cf2694708
5 changed files with 77 additions and 27 deletions

View File

@ -32,6 +32,7 @@ class QSpectrumAnalyzerSettings(QtGui.QDialog, Ui_QSpectrumAnalyzerSettings):
settings = QtCore.QSettings() settings = QtCore.QSettings()
self.executableEdit.setText(settings.value("rtl_power_executable", "rtl_power")) self.executableEdit.setText(settings.value("rtl_power_executable", "rtl_power"))
self.waterfallHistorySizeSpinBox.setValue(settings.value("waterfall_history_size", 100, int)) self.waterfallHistorySizeSpinBox.setValue(settings.value("waterfall_history_size", 100, int))
self.deviceIndexSpinBox.setValue(settings.value("device_index", 0, int))
self.sampleRateSpinBox.setValue(settings.value("sample_rate", 2560000, int)) self.sampleRateSpinBox.setValue(settings.value("sample_rate", 2560000, int))
backend = settings.value("backend", "rtl_power") backend = settings.value("backend", "rtl_power")
@ -58,6 +59,7 @@ class QSpectrumAnalyzerSettings(QtGui.QDialog, Ui_QSpectrumAnalyzerSettings):
settings = QtCore.QSettings() settings = QtCore.QSettings()
settings.setValue("rtl_power_executable", self.executableEdit.text()) settings.setValue("rtl_power_executable", self.executableEdit.text())
settings.setValue("waterfall_history_size", self.waterfallHistorySizeSpinBox.value()) settings.setValue("waterfall_history_size", self.waterfallHistorySizeSpinBox.value())
settings.setValue("device_index", self.deviceIndexSpinBox.value())
settings.setValue("sample_rate", self.sampleRateSpinBox.value()) settings.setValue("sample_rate", self.sampleRateSpinBox.value())
settings.setValue("backend", self.backendComboBox.currentText()) settings.setValue("backend", self.backendComboBox.currentText())
QtGui.QDialog.accept(self) QtGui.QDialog.accept(self)
@ -345,6 +347,7 @@ class QSpectrumAnalyzerMainWindow(QtGui.QMainWindow, Ui_QSpectrumAnalyzerMainWin
ppm=int(self.ppmSpinBox.value()), ppm=int(self.ppmSpinBox.value()),
crop=int(self.cropSpinBox.value()) / 100.0, crop=int(self.cropSpinBox.value()) / 100.0,
single_shot=single_shot, single_shot=single_shot,
device_index=settings.value("device_index", 0, int),
sample_rate=settings.value("sample_rate", 2560000, int)) sample_rate=settings.value("sample_rate", 2560000, int))
self.rtl_power_thread.start() self.rtl_power_thread.start()

View File

@ -22,7 +22,7 @@ class RtlPowerBaseThread(QtCore.QThread):
self.wait() self.wait()
def setup(self, start_freq, stop_freq, bin_size, interval=10.0, gain=-1, def setup(self, start_freq, stop_freq, bin_size, interval=10.0, gain=-1,
ppm=0, crop=0, single_shot=False, sample_rate=2560000): ppm=0, crop=0, single_shot=False, device_index=0, sample_rate=2560000):
"""Setup rtl_power params""" """Setup rtl_power params"""
raise NotImplementedError raise NotImplementedError
@ -63,13 +63,14 @@ class RtlPowerBaseThread(QtCore.QThread):
class RtlPowerThread(RtlPowerBaseThread): class RtlPowerThread(RtlPowerBaseThread):
"""Thread which runs rtl_power process""" """Thread which runs rtl_power process"""
def setup(self, start_freq, stop_freq, bin_size, interval=10.0, gain=-1, def setup(self, start_freq, stop_freq, bin_size, interval=10.0, gain=-1,
ppm=0, crop=0, single_shot=False, sample_rate=2560000): ppm=0, crop=0, single_shot=False, device_index=0, sample_rate=2560000):
"""Setup rtl_power params""" """Setup rtl_power params"""
self.params = { self.params = {
"start_freq": start_freq, "start_freq": start_freq,
"stop_freq": stop_freq, "stop_freq": stop_freq,
"bin_size": bin_size, "bin_size": bin_size,
"interval": interval, "interval": interval,
"device_index": device_index,
"hops": 0, "hops": 0,
"gain": gain, "gain": gain,
"ppm": ppm, "ppm": ppm,
@ -93,6 +94,7 @@ class RtlPowerThread(RtlPowerBaseThread):
self.params["stop_freq"], self.params["stop_freq"],
self.params["bin_size"]), self.params["bin_size"]),
"-i", "{}".format(self.params["interval"]), "-i", "{}".format(self.params["interval"]),
"-d", "{}".format(self.params["device_index"]),
"-p", "{}".format(self.params["ppm"]), "-p", "{}".format(self.params["ppm"]),
"-c", "{}".format(self.params["crop"]) "-c", "{}".format(self.params["crop"])
] ]
@ -143,7 +145,7 @@ class RtlPowerThread(RtlPowerBaseThread):
class RtlPowerFftwThread(RtlPowerBaseThread): class RtlPowerFftwThread(RtlPowerBaseThread):
"""Thread which runs rtl_power_fftw process""" """Thread which runs rtl_power_fftw process"""
def setup(self, start_freq, stop_freq, bin_size, interval=10.0, gain=-1, def setup(self, start_freq, stop_freq, bin_size, interval=10.0, gain=-1,
ppm=0, crop=0, single_shot=False, sample_rate=2560000): ppm=0, crop=0, single_shot=False, device_index=0, sample_rate=2560000):
"""Setup rtl_power_fftw params""" """Setup rtl_power_fftw params"""
crop = crop * 100 crop = crop * 100
overlap = crop * 2 overlap = crop * 2
@ -158,6 +160,7 @@ class RtlPowerFftwThread(RtlPowerBaseThread):
"start_freq": start_freq, "start_freq": start_freq,
"stop_freq": stop_freq, "stop_freq": stop_freq,
"freq_range": freq_range, "freq_range": freq_range,
"device_index": device_index,
"sample_rate": sample_rate, "sample_rate": sample_rate,
"bin_size": bin_size, "bin_size": bin_size,
"bins": bins, "bins": bins,
@ -199,6 +202,7 @@ class RtlPowerFftwThread(RtlPowerBaseThread):
self.params["stop_freq"]), self.params["stop_freq"]),
"-b", "{}".format(self.params["bins"]), "-b", "{}".format(self.params["bins"]),
"-t", "{}".format(self.params["time"]), "-t", "{}".format(self.params["time"]),
"-d", "{}".format(self.params["device_index"]),
"-r", "{}".format(self.params["sample_rate"]), "-r", "{}".format(self.params["sample_rate"]),
"-p", "{}".format(self.params["ppm"]), "-p", "{}".format(self.params["ppm"]),
] ]

View File

@ -81,7 +81,7 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="__main__.py" line="462"/> <location filename="__main__.py" line="465"/>
<source>QSpectrumAnalyzer {}</source> <source>QSpectrumAnalyzer {}</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -176,12 +176,12 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="__main__.py" line="296"/> <location filename="__main__.py" line="298"/>
<source>N/A</source> <source>N/A</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="__main__.py" line="462"/> <location filename="__main__.py" line="465"/>
<source>About - QSpectrumAnalyzer</source> <source>About - QSpectrumAnalyzer</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -206,7 +206,7 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="__main__.py" line="296"/> <location filename="__main__.py" line="298"/>
<source>Frequency hops: {} | Sweep time: {:.2f} s | FPS: {:.2f}</source> <source>Frequency hops: {} | Sweep time: {:.2f} s | FPS: {:.2f}</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -252,50 +252,55 @@
<context> <context>
<name>QSpectrumAnalyzerSettings</name> <name>QSpectrumAnalyzerSettings</name>
<message> <message>
<location filename="ui_qspectrumanalyzer_settings.py" line="100"/> <location filename="ui_qspectrumanalyzer_settings.py" line="112"/>
<source>rtl_power</source> <source>rtl_power</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_settings.py" line="101"/> <location filename="ui_qspectrumanalyzer_settings.py" line="113"/>
<source>...</source> <source>...</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_settings.py" line="98"/> <location filename="ui_qspectrumanalyzer_settings.py" line="110"/>
<source>rtl_power_fftw</source> <source>rtl_power_fftw</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_settings.py" line="96"/> <location filename="ui_qspectrumanalyzer_settings.py" line="108"/>
<source>&amp;Backend:</source> <source>&amp;Backend:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_settings.py" line="99"/> <location filename="ui_qspectrumanalyzer_settings.py" line="111"/>
<source>E&amp;xecutable:</source> <source>E&amp;xecutable:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_settings.py" line="102"/> <location filename="ui_qspectrumanalyzer_settings.py" line="114"/>
<source>&amp;Waterfall history size:</source> <source>&amp;Waterfall history size:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_settings.py" line="103"/> <location filename="ui_qspectrumanalyzer_settings.py" line="116"/>
<source>Sa&amp;mple rate:</source> <source>Sa&amp;mple rate:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="__main__.py" line="47"/> <location filename="__main__.py" line="48"/>
<source>Select executable - QSpectrumAnalyzer</source> <source>Select executable - QSpectrumAnalyzer</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_settings.py" line="95"/> <location filename="ui_qspectrumanalyzer_settings.py" line="107"/>
<source>Settings - QSpectrumAnalyzer</source> <source>Settings - QSpectrumAnalyzer</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<location filename="ui_qspectrumanalyzer_settings.py" line="115"/>
<source>&amp;Device index:</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>QSpectrumAnalyzerSmooth</name> <name>QSpectrumAnalyzerSmooth</name>

View File

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>400</width> <width>325</width>
<height>210</height> <height>259</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -92,6 +92,29 @@
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="3" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>&amp;Device index:</string>
</property>
<property name="buddy">
<cstring>deviceIndexSpinBox</cstring>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="deviceIndexSpinBox">
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>99</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_4"> <widget class="QLabel" name="label_4">
<property name="text"> <property name="text">
<string>Sa&amp;mple rate:</string> <string>Sa&amp;mple rate:</string>
@ -101,7 +124,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="4" column="1">
<widget class="QSpinBox" name="sampleRateSpinBox"> <widget class="QSpinBox" name="sampleRateSpinBox">
<property name="minimum"> <property name="minimum">
<number>0</number> <number>0</number>
@ -149,7 +172,9 @@
<tabstop>executableEdit</tabstop> <tabstop>executableEdit</tabstop>
<tabstop>executableButton</tabstop> <tabstop>executableButton</tabstop>
<tabstop>waterfallHistorySizeSpinBox</tabstop> <tabstop>waterfallHistorySizeSpinBox</tabstop>
<tabstop>deviceIndexSpinBox</tabstop>
<tabstop>sampleRateSpinBox</tabstop> <tabstop>sampleRateSpinBox</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops> </tabstops>
<resources/> <resources/>
<connections> <connections>
@ -160,8 +185,8 @@
<slot>accept()</slot> <slot>accept()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>230</x> <x>236</x>
<y>203</y> <y>252</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>157</x> <x>157</x>
@ -176,8 +201,8 @@
<slot>reject()</slot> <slot>reject()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>298</x> <x>304</x>
<y>203</y> <y>252</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>286</x> <x>286</x>

View File

@ -25,7 +25,7 @@ except AttributeError:
class Ui_QSpectrumAnalyzerSettings(object): class Ui_QSpectrumAnalyzerSettings(object):
def setupUi(self, QSpectrumAnalyzerSettings): def setupUi(self, QSpectrumAnalyzerSettings):
QSpectrumAnalyzerSettings.setObjectName(_fromUtf8("QSpectrumAnalyzerSettings")) QSpectrumAnalyzerSettings.setObjectName(_fromUtf8("QSpectrumAnalyzerSettings"))
QSpectrumAnalyzerSettings.resize(400, 210) QSpectrumAnalyzerSettings.resize(325, 259)
self.verticalLayout = QtGui.QVBoxLayout(QSpectrumAnalyzerSettings) self.verticalLayout = QtGui.QVBoxLayout(QSpectrumAnalyzerSettings)
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
self.formLayout = QtGui.QFormLayout() self.formLayout = QtGui.QFormLayout()
@ -59,16 +59,25 @@ class Ui_QSpectrumAnalyzerSettings(object):
self.waterfallHistorySizeSpinBox.setProperty("value", 100) self.waterfallHistorySizeSpinBox.setProperty("value", 100)
self.waterfallHistorySizeSpinBox.setObjectName(_fromUtf8("waterfallHistorySizeSpinBox")) self.waterfallHistorySizeSpinBox.setObjectName(_fromUtf8("waterfallHistorySizeSpinBox"))
self.formLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.waterfallHistorySizeSpinBox) self.formLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.waterfallHistorySizeSpinBox)
self.label_5 = QtGui.QLabel(QSpectrumAnalyzerSettings)
self.label_5.setObjectName(_fromUtf8("label_5"))
self.formLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.label_5)
self.deviceIndexSpinBox = QtGui.QSpinBox(QSpectrumAnalyzerSettings)
self.deviceIndexSpinBox.setMinimum(0)
self.deviceIndexSpinBox.setMaximum(99)
self.deviceIndexSpinBox.setProperty("value", 0)
self.deviceIndexSpinBox.setObjectName(_fromUtf8("deviceIndexSpinBox"))
self.formLayout.setWidget(3, QtGui.QFormLayout.FieldRole, self.deviceIndexSpinBox)
self.label_4 = QtGui.QLabel(QSpectrumAnalyzerSettings) self.label_4 = QtGui.QLabel(QSpectrumAnalyzerSettings)
self.label_4.setObjectName(_fromUtf8("label_4")) self.label_4.setObjectName(_fromUtf8("label_4"))
self.formLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.label_4) self.formLayout.setWidget(4, QtGui.QFormLayout.LabelRole, self.label_4)
self.sampleRateSpinBox = QtGui.QSpinBox(QSpectrumAnalyzerSettings) self.sampleRateSpinBox = QtGui.QSpinBox(QSpectrumAnalyzerSettings)
self.sampleRateSpinBox.setMinimum(0) self.sampleRateSpinBox.setMinimum(0)
self.sampleRateSpinBox.setMaximum(25000000) self.sampleRateSpinBox.setMaximum(25000000)
self.sampleRateSpinBox.setSingleStep(10000) self.sampleRateSpinBox.setSingleStep(10000)
self.sampleRateSpinBox.setProperty("value", 2560000) self.sampleRateSpinBox.setProperty("value", 2560000)
self.sampleRateSpinBox.setObjectName(_fromUtf8("sampleRateSpinBox")) self.sampleRateSpinBox.setObjectName(_fromUtf8("sampleRateSpinBox"))
self.formLayout.setWidget(3, QtGui.QFormLayout.FieldRole, self.sampleRateSpinBox) self.formLayout.setWidget(4, QtGui.QFormLayout.FieldRole, self.sampleRateSpinBox)
self.verticalLayout.addLayout(self.formLayout) self.verticalLayout.addLayout(self.formLayout)
spacerItem = QtGui.QSpacerItem(20, 21, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) spacerItem = QtGui.QSpacerItem(20, 21, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.verticalLayout.addItem(spacerItem) self.verticalLayout.addItem(spacerItem)
@ -80,6 +89,7 @@ class Ui_QSpectrumAnalyzerSettings(object):
self.label_3.setBuddy(self.backendComboBox) self.label_3.setBuddy(self.backendComboBox)
self.label.setBuddy(self.executableEdit) self.label.setBuddy(self.executableEdit)
self.label_2.setBuddy(self.waterfallHistorySizeSpinBox) self.label_2.setBuddy(self.waterfallHistorySizeSpinBox)
self.label_5.setBuddy(self.deviceIndexSpinBox)
self.label_4.setBuddy(self.sampleRateSpinBox) self.label_4.setBuddy(self.sampleRateSpinBox)
self.retranslateUi(QSpectrumAnalyzerSettings) self.retranslateUi(QSpectrumAnalyzerSettings)
@ -89,7 +99,9 @@ class Ui_QSpectrumAnalyzerSettings(object):
QSpectrumAnalyzerSettings.setTabOrder(self.backendComboBox, self.executableEdit) QSpectrumAnalyzerSettings.setTabOrder(self.backendComboBox, self.executableEdit)
QSpectrumAnalyzerSettings.setTabOrder(self.executableEdit, self.executableButton) QSpectrumAnalyzerSettings.setTabOrder(self.executableEdit, self.executableButton)
QSpectrumAnalyzerSettings.setTabOrder(self.executableButton, self.waterfallHistorySizeSpinBox) QSpectrumAnalyzerSettings.setTabOrder(self.executableButton, self.waterfallHistorySizeSpinBox)
QSpectrumAnalyzerSettings.setTabOrder(self.waterfallHistorySizeSpinBox, self.sampleRateSpinBox) QSpectrumAnalyzerSettings.setTabOrder(self.waterfallHistorySizeSpinBox, self.deviceIndexSpinBox)
QSpectrumAnalyzerSettings.setTabOrder(self.deviceIndexSpinBox, self.sampleRateSpinBox)
QSpectrumAnalyzerSettings.setTabOrder(self.sampleRateSpinBox, self.buttonBox)
def retranslateUi(self, QSpectrumAnalyzerSettings): def retranslateUi(self, QSpectrumAnalyzerSettings):
QSpectrumAnalyzerSettings.setWindowTitle(_translate("QSpectrumAnalyzerSettings", "Settings - QSpectrumAnalyzer", None)) QSpectrumAnalyzerSettings.setWindowTitle(_translate("QSpectrumAnalyzerSettings", "Settings - QSpectrumAnalyzer", None))
@ -100,5 +112,6 @@ class Ui_QSpectrumAnalyzerSettings(object):
self.executableEdit.setText(_translate("QSpectrumAnalyzerSettings", "rtl_power", None)) self.executableEdit.setText(_translate("QSpectrumAnalyzerSettings", "rtl_power", None))
self.executableButton.setText(_translate("QSpectrumAnalyzerSettings", "...", None)) self.executableButton.setText(_translate("QSpectrumAnalyzerSettings", "...", None))
self.label_2.setText(_translate("QSpectrumAnalyzerSettings", "&Waterfall history size:", None)) self.label_2.setText(_translate("QSpectrumAnalyzerSettings", "&Waterfall history size:", None))
self.label_5.setText(_translate("QSpectrumAnalyzerSettings", "&Device index:", None))
self.label_4.setText(_translate("QSpectrumAnalyzerSettings", "Sa&mple rate:", None)) self.label_4.setText(_translate("QSpectrumAnalyzerSettings", "Sa&mple rate:", None))