diff --git a/gr_grc/rtl-sdr_source_to_file_meta_sink.grc b/gr_grc/rtl-sdr_source_to_file_meta_sink.grc index d37f81bfd215d7b7af58f0966167dd713fd0b13a..0e7b31195c00098a985383708ad6612a6bc59c27 100644 --- a/gr_grc/rtl-sdr_source_to_file_meta_sink.grc +++ b/gr_grc/rtl-sdr_source_to_file_meta_sink.grc @@ -81,7 +81,7 @@ </param> <param> <key>_coordinate</key> - <value>(320, 13)</value> + <value>(288, 13)</value> </param> <param> <key>_rotation</key> @@ -123,6 +123,33 @@ <value>2e6</value> </param> </block> + <block> + <key>variable</key> + <param> + <key>comment</key> + <value></value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>_coordinate</key> + <value>(376, 13)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + <param> + <key>id</key> + <value>time</value> + </param> + <param> + <key>value</key> + <value>60</value> + </param> + </block> <block> <key>blocks_file_meta_sink</key> <param> @@ -155,7 +182,7 @@ </param> <param> <key>_coordinate</key> - <value>(328, 154)</value> + <value>(672, 154)</value> </param> <param> <key>_rotation</key> @@ -190,6 +217,312 @@ <value>1</value> </param> </block> + <block> + <key>blocks_head</key> + <param> + <key>alias</key> + <value></value> + </param> + <param> + <key>comment</key> + <value></value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>_coordinate</key> + <value>(384, 196)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + <param> + <key>id</key> + <value>blocks_head_0</value> + </param> + <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> + <key>minoutbuf</key> + <value>0</value> + </param> + <param> + <key>num_items</key> + <value>int(samp_rate)*time</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + </block> + <block> + <key>osmosdr_source</key> + <param> + <key>alias</key> + <value></value> + </param> + <param> + <key>ant0</key> + <value></value> + </param> + <param> + <key>bb_gain0</key> + <value>20</value> + </param> + <param> + <key>bw0</key> + <value>0</value> + </param> + <param> + <key>dc_offset_mode0</key> + <value>0</value> + </param> + <param> + <key>corr0</key> + <value>0</value> + </param> + <param> + <key>freq0</key> + <value>freq</value> + </param> + <param> + <key>gain_mode0</key> + <value>False</value> + </param> + <param> + <key>if_gain0</key> + <value>20</value> + </param> + <param> + <key>iq_balance_mode0</key> + <value>0</value> + </param> + <param> + <key>gain0</key> + <value>0</value> + </param> + <param> + <key>ant1</key> + <value></value> + </param> + <param> + <key>bb_gain1</key> + <value>20</value> + </param> + <param> + <key>bw1</key> + <value>0</value> + </param> + <param> + <key>dc_offset_mode1</key> + <value>0</value> + </param> + <param> + <key>corr1</key> + <value>0</value> + </param> + <param> + <key>freq1</key> + <value>100e6</value> + </param> + <param> + <key>gain_mode1</key> + <value>False</value> + </param> + <param> + <key>if_gain1</key> + <value>20</value> + </param> + <param> + <key>iq_balance_mode1</key> + <value>0</value> + </param> + <param> + <key>gain1</key> + <value>10</value> + </param> + <param> + <key>ant2</key> + <value></value> + </param> + <param> + <key>bb_gain2</key> + <value>20</value> + </param> + <param> + <key>bw2</key> + <value>0</value> + </param> + <param> + <key>dc_offset_mode2</key> + <value>0</value> + </param> + <param> + <key>corr2</key> + <value>0</value> + </param> + <param> + <key>freq2</key> + <value>100e6</value> + </param> + <param> + <key>gain_mode2</key> + <value>False</value> + </param> + <param> + <key>if_gain2</key> + <value>20</value> + </param> + <param> + <key>iq_balance_mode2</key> + <value>0</value> + </param> + <param> + <key>gain2</key> + <value>10</value> + </param> + <param> + <key>ant3</key> + <value></value> + </param> + <param> + <key>bb_gain3</key> + <value>20</value> + </param> + <param> + <key>bw3</key> + <value>0</value> + </param> + <param> + <key>dc_offset_mode3</key> + <value>0</value> + </param> + <param> + <key>corr3</key> + <value>0</value> + </param> + <param> + <key>freq3</key> + <value>100e6</value> + </param> + <param> + <key>gain_mode3</key> + <value>False</value> + </param> + <param> + <key>if_gain3</key> + <value>20</value> + </param> + <param> + <key>iq_balance_mode3</key> + <value>0</value> + </param> + <param> + <key>gain3</key> + <value>10</value> + </param> + <param> + <key>ant4</key> + <value></value> + </param> + <param> + <key>bb_gain4</key> + <value>20</value> + </param> + <param> + <key>bw4</key> + <value>0</value> + </param> + <param> + <key>dc_offset_mode4</key> + <value>0</value> + </param> + <param> + <key>corr4</key> + <value>0</value> + </param> + <param> + <key>freq4</key> + <value>100e6</value> + </param> + <param> + <key>gain_mode4</key> + <value>False</value> + </param> + <param> + <key>if_gain4</key> + <value>20</value> + </param> + <param> + <key>iq_balance_mode4</key> + <value>0</value> + </param> + <param> + <key>gain4</key> + <value>10</value> + </param> + <param> + <key>comment</key> + <value></value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>args</key> + <value></value> + </param> + <param> + <key>_enabled</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(72, 308)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + <param> + <key>id</key> + <value>osmosdr_source_0</value> + </param> + <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> + <key>minoutbuf</key> + <value>0</value> + </param> + <param> + <key>nchan</key> + <value>1</value> + </param> + <param> + <key>type</key> + <value>fc32</value> + </param> + <param> + <key>sample_rate</key> + <value>samp_rate</value> + </param> + </block> <block> <key>rtlsdr_source</key> <param> @@ -410,7 +743,7 @@ </param> <param> <key>_enabled</key> - <value>True</value> + <value>0</value> </param> <param> <key>_coordinate</key> @@ -446,9 +779,21 @@ </param> </block> <connection> - <source_block_id>rtlsdr_source_0</source_block_id> + <source_block_id>blocks_head_0</source_block_id> <sink_block_id>blocks_file_meta_sink_0</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> + <connection> + <source_block_id>osmosdr_source_0</source_block_id> + <sink_block_id>blocks_head_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>rtlsdr_source_0</source_block_id> + <sink_block_id>blocks_head_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> </flow_graph> diff --git a/gr_grc/rtl-sdr_source_to_file_meta_sink.py b/gr_grc/rtl-sdr_source_to_file_meta_sink.py index 66d770cd89a4c99c6bf66e4dba687ea47e1a518b..a933a3070876330d70224e3e131d2ff24fe3963c 100755 --- a/gr_grc/rtl-sdr_source_to_file_meta_sink.py +++ b/gr_grc/rtl-sdr_source_to_file_meta_sink.py @@ -2,9 +2,10 @@ ################################################## # GNU Radio Python Flow Graph # Title: Top Block -# Generated: Sat Dec 19 12:53:49 2015 +# Generated: Tue Dec 22 16:32:04 2015 ################################################## +from gnuradio import blocks from gnuradio import eng_notation from gnuradio import gr from gnuradio import gr, blocks @@ -22,6 +23,7 @@ class top_block(gr.top_block): ################################################## # Variables ################################################## + self.time = time = 60 self.samp_rate = samp_rate = 2e6 self.freq = freq = 868e6 @@ -41,20 +43,30 @@ class top_block(gr.top_block): self.rtlsdr_source_0.set_antenna("", 0) self.rtlsdr_source_0.set_bandwidth(0, 0) + self.blocks_head_0 = blocks.head(gr.sizeof_gr_complex*1, int(samp_rate)*time) self.blocks_file_meta_sink_0 = blocks.file_meta_sink(gr.sizeof_gr_complex*1, "bla", samp_rate, 1, blocks.GR_FILE_FLOAT, True, 1000000, "", False) self.blocks_file_meta_sink_0.set_unbuffered(False) ################################################## # Connections ################################################## - self.connect((self.rtlsdr_source_0, 0), (self.blocks_file_meta_sink_0, 0)) + self.connect((self.blocks_head_0, 0), (self.blocks_file_meta_sink_0, 0)) + self.connect((self.rtlsdr_source_0, 0), (self.blocks_head_0, 0)) + def get_time(self): + return self.time + + def set_time(self, time): + self.time = time + self.blocks_head_0.set_length(int(self.samp_rate)*self.time) + def get_samp_rate(self): return self.samp_rate def set_samp_rate(self, samp_rate): self.samp_rate = samp_rate + self.blocks_head_0.set_length(int(self.samp_rate)*self.time) self.rtlsdr_source_0.set_sample_rate(self.samp_rate) def get_freq(self): diff --git a/lib/gr/__init__.py b/lib/gr/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/lib/gr/file_sink.py b/lib/gr/file_sink.py index e7089ae293cda62d3d64fcd55beb491dbb0e0ada..b1fe6cab4c62fde441d032cc71e549f39a510616 100644 --- a/lib/gr/file_sink.py +++ b/lib/gr/file_sink.py @@ -10,16 +10,30 @@ from gnuradio import gr, blocks from gnuradio.eng_option import eng_option from gnuradio.filter import firdes -class FileSink(self): +from lib.disk import Disk + +class FileSink(gr.top_block): """ FileSink class to create I/Q sample binary dump files. """ - def __init__(self, dump_file, samp_rate, capture_time, device): + def __init__(self, + dump_file, + freq, + samp_rate, + capture_time, + device, + parent=None + ): + gr.top_block.__init__(self, "file_sink_block") + self.file_path = dump_file - self.sample_rate = samp_rate + self.samp_rate = samp_rate self.freq = freq self.capture_time = capture_time - self.capture_device = device + self.capture_device = \ + osmosdr.source(args="numchan=" + str(1) + " " + "" ) + + self._build_blocks() def needed_disc_space(self): """ @@ -31,19 +45,10 @@ class FileSink(self): """ Capture samples to dump file. """ - pass - - def _dump_file_writable(self): - """ - Check permissions for specified file dump path. - """ - if os.path.exists(self.pathfile): - return os.access(self.file_path, os.W_OK) - elif os.access(os.path.dirname(self.file_path), os.W_OK) and \ - os.access(self.file_path, os.W_OK): - return True - else: - return False + tb = top_block() + tb.start() + tb.stop() + tb.wait() def get_file_path(self): return self.file_path @@ -56,3 +61,39 @@ class FileSink(self): def get_capture_device(self): return self.get_capture_device + + def _dump_file_writable(self): + """ + Check permissions for specified file dump path. + """ + Disk.path_writeble(self.file_path) + + def _build_blocks(self): + # blocks + # configure capture device + self.device_source = self.capture_device + self.device_source.set_sample_rate(self.samp_rate) + self.device_source.set_center_freq(self.freq, 0) + self.device_source.set_freq_corr(0, 0) + self.device_source.set_dc_offset_mode(0, 0) + self.device_source.set_iq_balance_mode(0, 0) + self.device_source.set_gain_mode(False, 0) + self.device_source.set_gain(0, 0) + self.device_source.set_if_gain(20, 0) + self.device_source.set_bb_gain(20, 0) + self.device_source.set_antenna("", 0) + self.device_source.set_bandwidth(0, 0) + # configure additional blocks + self.blocks_head_0 = blocks.head(gr.sizeof_gr_complex*1, \ + int(self.samp_rate)*self.capture_time) + self.blocks_file_meta_sink_0 = blocks.file_meta_sink( + gr.sizeof_gr_complex*1, \ + self.file_path, \ + self.samp_rate, \ + 1, \ + blocks.GR_FILE_FLOAT, \ + True, 1000000, "", False) + self.blocks_file_meta_sink_0.set_unbuffered(False) + # connect blocks + self.connect((self.blocks_head_0, 0), (self.blocks_file_meta_sink_0, 0)) + self.connect((self.device_source, 0), (self.blocks_head_0, 0)) diff --git a/lib/gui/gui.py b/lib/gui/gui.py index db2bfb510bebde61026a8c6450ede7e7302568ca..7c54b4f5f6beca50c5e3fcf2399e90a0d025fd53 100644 --- a/lib/gui/gui.py +++ b/lib/gui/gui.py @@ -12,6 +12,8 @@ from lib.hardware import Hardware from lib.su import Su from lib.disk import Disk +from lib.gr.file_sink import FileSink + class SuGui(QtWidgets.QMainWindow): """ GUI class used to realise the main window. @@ -41,7 +43,7 @@ class SuGui(QtWidgets.QMainWindow): self.lineEdit_dump_file.editingFinished. \ connect(self.check_dump_file_path) # radio buttons - self.radio_buttons = { + self.radio_buttons_samp_rate_and_time = { # samp_rate self.rb_1mhz: 1e6, self.rb_2mhz: 2e6, @@ -53,8 +55,12 @@ class SuGui(QtWidgets.QMainWindow): self.rb_1h: 3600, self.rb_24h: 86400 } + self.radio_buttons_freq = { + self.rb_433: 433e6, + self.rb_868: 868e6 + } # add released actions to radio buttons - for button in self.radio_buttons.keys(): + for button in self.radio_buttons_samp_rate_and_time.keys(): button.released.connect(self._update_status_label) # labels @@ -66,9 +72,16 @@ class SuGui(QtWidgets.QMainWindow): Start button action in main window. """ if self._check_dependencies_before_start_capture(): - print self._extract_selected_hardware_device() - print self.lineEdit_dump_file.text() - self._get_checked_radio_buttons() + options = self._extract_options() + file_sink = FileSink( + options['dump_file_path'], + options['freq'], + options['samp_rate'], + options['capture_time'], + options['device'] + ) + + def stop_button(self): """ @@ -177,6 +190,9 @@ class SuGui(QtWidgets.QMainWindow): return True def _update_status_label(self): + """ + Update status label. + """ needed_disk_space = Disk.sizeof_fmt(self._calculate_needed_disk_space()) self.label_status. \ setText("Needed disk space:\n" \ @@ -190,23 +206,50 @@ class SuGui(QtWidgets.QMainWindow): Returned integer value. """ - time, samp_rate = self._get_checked_radio_buttons().values() + time, samp_rate = self._get_checked_time_and_samp_rate_radio_buttons().values() return int((time*samp_rate) * 8) - def _get_checked_radio_buttons(self): + def _get_checked_time_and_samp_rate_radio_buttons(self): """ Return a list of all checked radio buttons. """ checked_buttons = {} - for radio_button, value in self.radio_buttons.iteritems(): + for radio_button, value in \ + self.radio_buttons_samp_rate_and_time.iteritems(): if radio_button.isChecked(): checked_buttons[radio_button] = value return checked_buttons + def _get_checked_freq_button(self): + """ + Get checked freq button. + """ + for radio_button, value in self.radio_buttons_freq.iteritems(): + if radio_button.isChecked(): + return {radio_button: value} + def _set_default_dump_file_path(self): if "SU_DUMP_FILE_PATH" in os.environ: self.lineEdit_dump_file.setText(os.environ['SU_DUMP_FILE_PATH']) else: self.lineEdit_dump_file.setText(self._get_default_dump_file_path()) + + def _extract_options(self): + """ + Extract selected options from gui. + """ + freq_button = self._get_checked_freq_button() + time_and_samp_rate_buttons = self._get_checked_time_and_samp_rate_radio_buttons() + # radio buttons + options = {} + options['capture_time'], options['samp_rate'] = \ + time_and_samp_rate_buttons.values() + options['freq'] = freq_button.values()[0] + # line inputs + options['dump_file_path'] = self.lineEdit_dump_file.text() + # dropdown boxes + options['device'] = self._extract_selected_hardware_device() + + return options