diff --git a/gr_grc/jamming_868.grc b/gr_grc/jamming_868.grc index 2f91a213d2677bc0fe7af0d82da50c93c69f1516..2a50a4b051a34bb9e089ffa8a4594f4474ef328c 100644 --- a/gr_grc/jamming_868.grc +++ b/gr_grc/jamming_868.grc @@ -1,5 +1,5 @@ <?xml version='1.0' encoding='utf-8'?> -<?grc format='1' created='3.7.9'?> +<?grc format='1' created='3.7.10'?> <flow_graph> <timestamp>Sat Feb 13 17:51:14 2016</timestamp> <block> @@ -30,7 +30,7 @@ </param> <param> <key>_coordinate</key> - <value>(16, 22)</value> + <value>(16, 21)</value> </param> <param> <key>_rotation</key> @@ -93,34 +93,7 @@ </param> <param> <key>_coordinate</key> - <value>(392, 23)</value> - </param> - <param> - <key>_rotation</key> - <value>0</value> - </param> - <param> - <key>id</key> - <value>cutoff_freq</value> - </param> - <param> - <key>value</key> - <value>transition_width/2</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>(280, 23)</value> + <value>(264, 21)</value> </param> <param> <key>_rotation</key> @@ -132,7 +105,7 @@ </param> <param> <key>value</key> - <value>868.3e6</value> + <value>868e6</value> </param> </block> <block> @@ -147,7 +120,7 @@ </param> <param> <key>_coordinate</key> - <value>(192, 23)</value> + <value>(176, 21)</value> </param> <param> <key>_rotation</key> @@ -159,101 +132,11 @@ </param> <param> <key>value</key> - <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>(536, 23)</value> - </param> - <param> - <key>_rotation</key> - <value>0</value> - </param> - <param> - <key>id</key> - <value>transition_width</value> - </param> - <param> - <key>value</key> - <value>6e5</value> - </param> - </block> - <block> - <key>analog_fastnoise_source_x</key> - <param> - <key>amp</key> - <value>1</value> - </param> - <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>(32, 317)</value> - </param> - <param> - <key>_rotation</key> - <value>0</value> - </param> - <param> - <key>id</key> - <value>analog_fastnoise_source_x_0</value> - </param> - <param> - <key>maxoutbuf</key> - <value>0</value> - </param> - <param> - <key>minoutbuf</key> - <value>0</value> - </param> - <param> - <key>noise_type</key> - <value>analog.GR_GAUSSIAN</value> - </param> - <param> - <key>type</key> - <value>complex</value> - </param> - <param> - <key>seed</key> - <value>0</value> - </param> - <param> - <key>samples</key> - <value>8192</value> + <value>2e7</value> </param> </block> <block> - <key>analog_sig_source_x</key> - <param> - <key>amp</key> - <value>1</value> - </param> + <key>blocks_file_source</key> <param> <key>alias</key> <value></value> @@ -271,12 +154,12 @@ <value>True</value> </param> <param> - <key>freq</key> - <value>1e3</value> + <key>file</key> + <value>/home/meise/projects/ba_sdr/src/su/gr_grc/scripts/jamming_signal_868.3.iq</value> </param> <param> <key>_coordinate</key> - <value>(40, 140)</value> + <value>(16, 85)</value> </param> <param> <key>_rotation</key> @@ -284,7 +167,7 @@ </param> <param> <key>id</key> - <value>analog_sig_source_x_0</value> + <value>blocks_file_source_0</value> </param> <param> <key>maxoutbuf</key> @@ -294,68 +177,13 @@ <key>minoutbuf</key> <value>0</value> </param> - <param> - <key>offset</key> - <value>0</value> - </param> - <param> - <key>type</key> - <value>complex</value> - </param> - <param> - <key>samp_rate</key> - <value>samp_rate</value> - </param> - <param> - <key>waveform</key> - <value>analog.GR_SIN_WAVE</value> - </param> - </block> - <block> - <key>blocks_add_xx</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>1</value> - </param> - <param> - <key>_coordinate</key> - <value>(248, 234)</value> - </param> - <param> - <key>_rotation</key> - <value>0</value> - </param> - <param> - <key>id</key> - <value>blocks_add_xx_0</value> - </param> <param> <key>type</key> <value>complex</value> </param> <param> - <key>maxoutbuf</key> - <value>0</value> - </param> - <param> - <key>minoutbuf</key> - <value>0</value> - </param> - <param> - <key>num_inputs</key> - <value>2</value> + <key>repeat</key> + <value>True</value> </param> <param> <key>vlen</key> @@ -382,7 +210,7 @@ </param> <param> <key>_coordinate</key> - <value>(376, 368)</value> + <value>(232, 212)</value> </param> <param> <key>_rotation</key> @@ -390,7 +218,7 @@ </param> <param> <key>id</key> - <value>blocks_throttle_0</value> + <value>blocks_throttle_1</value> </param> <param> <key>ignoretag</key> @@ -417,140 +245,6 @@ <value>1</value> </param> </block> - <block> - <key>channels_fading_model</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>(432, 229)</value> - </param> - <param> - <key>_rotation</key> - <value>0</value> - </param> - <param> - <key>id</key> - <value>channels_fading_model_0</value> - </param> - <param> - <key>LOS</key> - <value>False</value> - </param> - <param> - <key>maxoutbuf</key> - <value>0</value> - </param> - <param> - <key>minoutbuf</key> - <value>0</value> - </param> - <param> - <key>fDTs</key> - <value>10.0/samp_rate</value> - </param> - <param> - <key>N</key> - <value>8</value> - </param> - <param> - <key>K</key> - <value>4.0</value> - </param> - <param> - <key>seed</key> - <value>0</value> - </param> - </block> - <block> - <key>low_pass_filter</key> - <param> - <key>beta</key> - <value>6.76</value> - </param> - <param> - <key>alias</key> - <value></value> - </param> - <param> - <key>comment</key> - <value></value> - </param> - <param> - <key>affinity</key> - <value></value> - </param> - <param> - <key>cutoff_freq</key> - <value>cutoff_freq</value> - </param> - <param> - <key>decim</key> - <value>1</value> - </param> - <param> - <key>_enabled</key> - <value>0</value> - </param> - <param> - <key>type</key> - <value>fir_filter_ccf</value> - </param> - <param> - <key>_coordinate</key> - <value>(880, 2)</value> - </param> - <param> - <key>_rotation</key> - <value>0</value> - </param> - <param> - <key>gain</key> - <value>1</value> - </param> - <param> - <key>id</key> - <value>low_pass_filter_0</value> - </param> - <param> - <key>interp</key> - <value>1</value> - </param> - <param> - <key>maxoutbuf</key> - <value>0</value> - </param> - <param> - <key>minoutbuf</key> - <value>0</value> - </param> - <param> - <key>samp_rate</key> - <value>samp_rate</value> - </param> - <param> - <key>width</key> - <value>transition_width</value> - </param> - <param> - <key>win</key> - <value>firdes.WIN_HAMMING</value> - </param> - </block> <block> <key>osmosdr_sink</key> <param> @@ -579,7 +273,7 @@ </param> <param> <key>if_gain0</key> - <value>0</value> + <value>47</value> </param> <param> <key>gain0</key> @@ -711,11 +405,11 @@ </param> <param> <key>_enabled</key> - <value>0</value> + <value>1</value> </param> <param> <key>_coordinate</key> - <value>(680, 106)</value> + <value>(416, 82)</value> </param> <param> <key>_rotation</key> @@ -778,7 +472,7 @@ </param> <param> <key>_coordinate</key> - <value>(680, 279)</value> + <value>(416, 213)</value> </param> <param> <key>_rotation</key> @@ -790,7 +484,7 @@ </param> <param> <key>id</key> - <value>wxgui_fftsink2_0</value> + <value>wxgui_fftsink2_1</value> </param> <param> <key>notebook</key> @@ -798,7 +492,7 @@ </param> <param> <key>peak_hold</key> - <value>False</value> + <value>True</value> </param> <param> <key>ref_level</key> @@ -841,138 +535,21 @@ <value>10</value> </param> </block> - <block> - <key>wxgui_scopesink2</key> - <param> - <key>ac_couple</key> - <value>False</value> - </param> - <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>1</value> - </param> - <param> - <key>_coordinate</key> - <value>(680, 501)</value> - </param> - <param> - <key>_rotation</key> - <value>0</value> - </param> - <param> - <key>grid_pos</key> - <value></value> - </param> - <param> - <key>id</key> - <value>wxgui_scopesink2_0</value> - </param> - <param> - <key>notebook</key> - <value></value> - </param> - <param> - <key>num_inputs</key> - <value>1</value> - </param> - <param> - <key>samp_rate</key> - <value>samp_rate</value> - </param> - <param> - <key>t_scale</key> - <value>0</value> - </param> - <param> - <key>title</key> - <value>Scope Plot</value> - </param> - <param> - <key>trig_mode</key> - <value>wxgui.TRIG_MODE_AUTO</value> - </param> - <param> - <key>type</key> - <value>complex</value> - </param> - <param> - <key>v_offset</key> - <value>0</value> - </param> - <param> - <key>v_scale</key> - <value>0</value> - </param> - <param> - <key>win_size</key> - <value></value> - </param> - <param> - <key>xy_mode</key> - <value>False</value> - </param> - <param> - <key>y_axis_label</key> - <value>Counts</value> - </param> - </block> - <connection> - <source_block_id>analog_fastnoise_source_x_0</source_block_id> - <sink_block_id>blocks_add_xx_0</sink_block_id> - <source_key>0</source_key> - <sink_key>1</sink_key> - </connection> - <connection> - <source_block_id>analog_sig_source_x_0</source_block_id> - <sink_block_id>blocks_add_xx_0</sink_block_id> - <source_key>0</source_key> - <sink_key>0</sink_key> - </connection> - <connection> - <source_block_id>blocks_add_xx_0</source_block_id> - <sink_block_id>channels_fading_model_0</sink_block_id> - <source_key>0</source_key> - <sink_key>0</sink_key> - </connection> - <connection> - <source_block_id>blocks_throttle_0</source_block_id> - <sink_block_id>wxgui_fftsink2_0</sink_block_id> - <source_key>0</source_key> - <sink_key>0</sink_key> - </connection> <connection> - <source_block_id>blocks_throttle_0</source_block_id> - <sink_block_id>wxgui_scopesink2_0</sink_block_id> + <source_block_id>blocks_file_source_0</source_block_id> + <sink_block_id>blocks_throttle_1</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> <connection> - <source_block_id>channels_fading_model_0</source_block_id> - <sink_block_id>blocks_throttle_0</sink_block_id> - <source_key>0</source_key> - <sink_key>0</sink_key> - </connection> - <connection> - <source_block_id>low_pass_filter_0</source_block_id> - <sink_block_id>blocks_throttle_0</sink_block_id> + <source_block_id>blocks_file_source_0</source_block_id> + <sink_block_id>osmosdr_sink_0</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> <connection> - <source_block_id>low_pass_filter_0</source_block_id> - <sink_block_id>osmosdr_sink_0</sink_block_id> + <source_block_id>blocks_throttle_1</source_block_id> + <sink_block_id>wxgui_fftsink2_1</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> diff --git a/gr_grc/rtl-sdr_source_to_file_sink.grc b/gr_grc/rtl-sdr_source_to_file_sink.grc index bcb989c19dc177d3646bff72b9adce37c6c9b46c..22c8d4463ceb3fb5475c9a907000c0506f68aa1a 100644 --- a/gr_grc/rtl-sdr_source_to_file_sink.grc +++ b/gr_grc/rtl-sdr_source_to_file_sink.grc @@ -66,7 +66,7 @@ </param> <param> <key>run_options</key> - <value>prompt</value> + <value>run</value> </param> <param> <key>run</key> @@ -182,7 +182,7 @@ </param> <param> <key>_enabled</key> - <value>True</value> + <value>1</value> </param> <param> <key>file</key> @@ -190,7 +190,7 @@ </param> <param> <key>_coordinate</key> - <value>(400, 126)</value> + <value>(344, 198)</value> </param> <param> <key>_rotation</key> @@ -229,11 +229,11 @@ </param> <param> <key>_enabled</key> - <value>True</value> + <value>1</value> </param> <param> <key>_coordinate</key> - <value>(232, 140)</value> + <value>(248, 84)</value> </param> <param> <key>_rotation</key> @@ -480,7 +480,7 @@ </param> <param> <key>args</key> - <value></value> + <value>osmosdr=0</value> </param> <param> <key>_enabled</key> diff --git a/gr_grc/rtl-sdr_source_to_file_sink.py b/gr_grc/rtl-sdr_source_to_file_sink.py deleted file mode 100755 index a933a3070876330d70224e3e131d2ff24fe3963c..0000000000000000000000000000000000000000 --- a/gr_grc/rtl-sdr_source_to_file_sink.py +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env python2 -################################################## -# GNU Radio Python Flow Graph -# Title: Top Block -# 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 -from gnuradio.eng_option import eng_option -from gnuradio.filter import firdes -from optparse import OptionParser -import osmosdr - - -class top_block(gr.top_block): - - def __init__(self): - gr.top_block.__init__(self, "Top Block") - - ################################################## - # Variables - ################################################## - self.time = time = 60 - self.samp_rate = samp_rate = 2e6 - self.freq = freq = 868e6 - - ################################################## - # Blocks - ################################################## - self.rtlsdr_source_0 = osmosdr.source( args="numchan=" + str(1) + " " + "" ) - self.rtlsdr_source_0.set_sample_rate(samp_rate) - self.rtlsdr_source_0.set_center_freq(freq, 0) - self.rtlsdr_source_0.set_freq_corr(0, 0) - self.rtlsdr_source_0.set_dc_offset_mode(0, 0) - self.rtlsdr_source_0.set_iq_balance_mode(0, 0) - self.rtlsdr_source_0.set_gain_mode(False, 0) - self.rtlsdr_source_0.set_gain(0, 0) - self.rtlsdr_source_0.set_if_gain(20, 0) - self.rtlsdr_source_0.set_bb_gain(20, 0) - 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.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): - return self.freq - - def set_freq(self, freq): - self.freq = freq - self.rtlsdr_source_0.set_center_freq(self.freq, 0) - - -if __name__ == '__main__': - parser = OptionParser(option_class=eng_option, usage="%prog: [options]") - (options, args) = parser.parse_args() - tb = top_block() - tb.start() - try: - raw_input('Press Enter to quit: ') - except EOFError: - pass - tb.stop() - tb.wait() diff --git a/gr_grc/rtlsdr_signal_detection_868_1_and_0_1_persent_df.grc b/gr_grc/rtlsdr_signal_detection_868_1_and_0_1_persent_df.grc index 57f9f6068775acc7e279733d81f006209c15a16d..65da99de62221f164dc627100f6200236712a52f 100644 --- a/gr_grc/rtlsdr_signal_detection_868_1_and_0_1_persent_df.grc +++ b/gr_grc/rtlsdr_signal_detection_868_1_and_0_1_persent_df.grc @@ -1,5 +1,5 @@ <?xml version='1.0' encoding='utf-8'?> -<?grc format='1' created='3.7.9'?> +<?grc format='1' created='3.7.10'?> <flow_graph> <timestamp>Fri Feb 12 13:36:09 2016</timestamp> <block> @@ -30,7 +30,7 @@ </param> <param> <key>_coordinate</key> - <value>(936, 633)</value> + <value>(8, 5)</value> </param> <param> <key>_rotation</key> @@ -93,7 +93,34 @@ </param> <param> <key>_coordinate</key> - <value>(136, 81)</value> + <value>(248, 5)</value> + </param> + <param> + <key>_rotation</key> + <value>180</value> + </param> + <param> + <key>id</key> + <value>capture_time</value> + </param> + <param> + <key>value</key> + <value>60*60</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>(368, 13)</value> </param> <param> <key>_rotation</key> @@ -105,7 +132,7 @@ </param> <param> <key>value</key> - <value>transition_width_0_1/2</value> + <value>3e5</value> </param> </block> <block> @@ -120,7 +147,7 @@ </param> <param> <key>_coordinate</key> - <value>(152, 361)</value> + <value>(792, 53)</value> </param> <param> <key>_rotation</key> @@ -132,7 +159,7 @@ </param> <param> <key>value</key> - <value>transition_width_1/2</value> + <value>3.5e5</value> </param> </block> <block> @@ -147,11 +174,11 @@ </param> <param> <key>_coordinate</key> - <value>(8, 337)</value> + <value>(984, 205)</value> </param> <param> <key>_rotation</key> - <value>0</value> + <value>180</value> </param> <param> <key>id</key> @@ -174,7 +201,7 @@ </param> <param> <key>_coordinate</key> - <value>(8, 81)</value> + <value>(992, 125)</value> </param> <param> <key>_rotation</key> @@ -201,7 +228,7 @@ </param> <param> <key>_coordinate</key> - <value>(736, 89)</value> + <value>(848, 173)</value> </param> <param> <key>_rotation</key> @@ -228,7 +255,7 @@ </param> <param> <key>_coordinate</key> - <value>(240, 81)</value> + <value>(488, 13)</value> </param> <param> <key>_rotation</key> @@ -240,7 +267,7 @@ </param> <param> <key>value</key> - <value>2.5e5</value> + <value>cutoff_freq_0_1/2</value> </param> </block> <block> @@ -255,7 +282,7 @@ </param> <param> <key>_coordinate</key> - <value>(248, 361)</value> + <value>(968, 53)</value> </param> <param> <key>_rotation</key> @@ -267,7 +294,7 @@ </param> <param> <key>value</key> - <value>3.5e5</value> + <value>cutoff_freq_1/2</value> </param> </block> <block> @@ -290,7 +317,7 @@ </param> <param> <key>_coordinate</key> - <value>(576, 338)</value> + <value>(112, 401)</value> </param> <param> <key>_rotation</key> @@ -333,11 +360,11 @@ </param> <param> <key>_coordinate</key> - <value>(576, 186)</value> + <value>(360, 401)</value> </param> <param> <key>_rotation</key> - <value>0</value> + <value>180</value> </param> <param> <key>id</key> @@ -357,7 +384,11 @@ </param> </block> <block> - <key>blocks_threshold_ff</key> + <key>blocks_file_sink</key> + <param> + <key>append</key> + <value>False</value> + </param> <param> <key>alias</key> <value></value> @@ -372,31 +403,66 @@ </param> <param> <key>_enabled</key> - <value>1</value> + <value>True</value> + </param> + <param> + <key>file</key> + <value>data.iq</value> </param> <param> <key>_coordinate</key> - <value>(736, 312)</value> + <value>(416, 158)</value> </param> <param> <key>_rotation</key> <value>0</value> </param> <param> - <key>high</key> - <value>0.000686</value> + <key>id</key> + <value>blocks_file_sink_0</value> </param> <param> - <key>id</key> - <value>blocks_threshold_ff_0</value> + <key>type</key> + <value>complex</value> </param> <param> - <key>init</key> + <key>unbuffered</key> + <value>False</value> + </param> + <param> + <key>vlen</key> + <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>(224, 196)</value> + </param> + <param> + <key>_rotation</key> <value>0</value> </param> <param> - <key>low</key> - <value>0.000686</value> + <key>id</key> + <value>blocks_head_0</value> </param> <param> <key>maxoutbuf</key> @@ -406,9 +472,21 @@ <key>minoutbuf</key> <value>0</value> </param> + <param> + <key>num_items</key> + <value>int(capture_time*samp_rate)</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> </block> <block> - <key>blocks_threshold_ff</key> + <key>blocks_message_sink</key> <param> <key>alias</key> <value></value> @@ -421,33 +499,29 @@ <key>affinity</key> <value></value> </param> + <param> + <key>dont_block</key> + <value>True</value> + </param> <param> <key>_enabled</key> - <value>1</value> + <value>True</value> </param> <param> <key>_coordinate</key> - <value>(736, 160)</value> + <value>(48, 516)</value> </param> <param> <key>_rotation</key> <value>0</value> </param> - <param> - <key>high</key> - <value>threshold</value> - </param> <param> <key>id</key> - <value>blocks_threshold_ff_0_0</value> - </param> - <param> - <key>init</key> - <value>0</value> + <value>blocks_message_sink_0</value> </param> <param> - <key>low</key> - <value>threshold</value> + <key>type</key> + <value>float</value> </param> <param> <key>maxoutbuf</key> @@ -457,17 +531,17 @@ <key>minoutbuf</key> <value>0</value> </param> + <param> + <key>vlen</key> + <value>1</value> + </param> </block> <block> - <key>freq_xlating_fir_filter_xxx</key> + <key>blocks_message_sink</key> <param> <key>alias</key> <value></value> </param> - <param> - <key>center_freq</key> - <value>7e5+2.5e5</value> - </param> <param> <key>comment</key> <value></value> @@ -477,24 +551,28 @@ <value></value> </param> <param> - <key>decim</key> - <value>1</value> + <key>dont_block</key> + <value>True</value> </param> <param> <key>_enabled</key> - <value>1</value> + <value>True</value> </param> <param> <key>_coordinate</key> - <value>(200, 152)</value> + <value>(424, 516)</value> </param> <param> <key>_rotation</key> - <value>0</value> + <value>180</value> </param> <param> <key>id</key> - <value>freq_xlating_fir_filter_0_1</value> + <value>blocks_message_sink_1</value> + </param> + <param> + <key>type</key> + <value>float</value> </param> <param> <key>maxoutbuf</key> @@ -505,28 +583,16 @@ <value>0</value> </param> <param> - <key>samp_rate</key> - <value>samp_rate</value> - </param> - <param> - <key>taps</key> + <key>vlen</key> <value>1</value> </param> - <param> - <key>type</key> - <value>ccc</value> - </param> </block> <block> - <key>freq_xlating_fir_filter_xxx</key> + <key>blocks_threshold_ff</key> <param> <key>alias</key> <value></value> </param> - <param> - <key>center_freq</key> - <value>3e5</value> - </param> <param> <key>comment</key> <value></value> @@ -535,25 +601,33 @@ <key>affinity</key> <value></value> </param> - <param> - <key>decim</key> - <value>1</value> - </param> <param> <key>_enabled</key> <value>1</value> </param> <param> <key>_coordinate</key> - <value>(200, 256)</value> + <value>(56, 438)</value> </param> <param> <key>_rotation</key> - <value>0</value> + <value>180</value> + </param> + <param> + <key>high</key> + <value>0.000686</value> </param> <param> <key>id</key> - <value>freq_xlating_fir_filter_1</value> + <value>blocks_threshold_ff_0</value> + </param> + <param> + <key>init</key> + <value>0</value> + </param> + <param> + <key>low</key> + <value>0.000686</value> </param> <param> <key>maxoutbuf</key> @@ -563,29 +637,68 @@ <key>minoutbuf</key> <value>0</value> </param> + </block> + <block> + <key>blocks_threshold_ff</key> <param> - <key>samp_rate</key> - <value>samp_rate</value> + <key>alias</key> + <value></value> </param> <param> - <key>taps</key> + <key>comment</key> + <value></value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>_enabled</key> <value>1</value> </param> <param> - <key>type</key> - <value>ccc</value> + <key>_coordinate</key> + <value>(360, 438)</value> </param> - </block> - <block> - <key>low_pass_filter</key> <param> - <key>beta</key> - <value>6.76</value> + <key>_rotation</key> + <value>0</value> </param> + <param> + <key>high</key> + <value>threshold</value> + </param> + <param> + <key>id</key> + <value>blocks_threshold_ff_0_0</value> + </param> + <param> + <key>init</key> + <value>0</value> + </param> + <param> + <key>low</key> + <value>threshold</value> + </param> + <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> + <key>minoutbuf</key> + <value>0</value> + </param> + </block> + <block> + <key>freq_xlating_fir_filter_xxx</key> <param> <key>alias</key> <value></value> </param> + <param> + <key>center_freq</key> + <value>7e5+2.5e5</value> + </param> <param> <key>comment</key> <value></value> @@ -594,10 +707,6 @@ <key>affinity</key> <value></value> </param> - <param> - <key>cutoff_freq</key> - <value>cutoff_freq_0_1</value> - </param> <param> <key>decim</key> <value>1</value> @@ -606,29 +715,17 @@ <key>_enabled</key> <value>1</value> </param> - <param> - <key>type</key> - <value>fir_filter_ccf</value> - </param> <param> <key>_coordinate</key> - <value>(408, 126)</value> + <value>(416, 311)</value> </param> <param> <key>_rotation</key> <value>0</value> </param> - <param> - <key>gain</key> - <value>1</value> - </param> <param> <key>id</key> - <value>low_pass_filter_0_1</value> - </param> - <param> - <key>interp</key> - <value>1</value> + <value>freq_xlating_fir_filter_0_1</value> </param> <param> <key>maxoutbuf</key> @@ -643,24 +740,24 @@ <value>samp_rate</value> </param> <param> - <key>width</key> - <value>transition_width_0_1</value> + <key>taps</key> + <value>firdes.low_pass(1, samp_rate, transition_width_0_1, cutoff_freq_0_1, firdes.WIN_HAMMING, 6.76)</value> </param> <param> - <key>win</key> - <value>firdes.WIN_HAMMING</value> + <key>type</key> + <value>ccc</value> </param> </block> <block> - <key>low_pass_filter</key> - <param> - <key>beta</key> - <value>6.76</value> - </param> + <key>freq_xlating_fir_filter_xxx</key> <param> <key>alias</key> <value></value> </param> + <param> + <key>center_freq</key> + <value>3e5</value> + </param> <param> <key>comment</key> <value></value> @@ -669,10 +766,6 @@ <key>affinity</key> <value></value> </param> - <param> - <key>cutoff_freq</key> - <value>cutoff_freq_1</value> - </param> <param> <key>decim</key> <value>1</value> @@ -681,29 +774,17 @@ <key>_enabled</key> <value>1</value> </param> - <param> - <key>type</key> - <value>fir_filter_ccf</value> - </param> <param> <key>_coordinate</key> - <value>(408, 278)</value> + <value>(32, 311)</value> </param> <param> <key>_rotation</key> - <value>0</value> - </param> - <param> - <key>gain</key> - <value>1</value> + <value>180</value> </param> <param> <key>id</key> - <value>low_pass_filter_1</value> - </param> - <param> - <key>interp</key> - <value>1</value> + <value>freq_xlating_fir_filter_1</value> </param> <param> <key>maxoutbuf</key> @@ -718,12 +799,12 @@ <value>samp_rate</value> </param> <param> - <key>width</key> - <value>transition_width_1</value> + <key>taps</key> + <value>firdes.low_pass(1, samp_rate, transition_width_1, cutoff_freq_1, firdes.WIN_HAMMING, 6.76)</value> </param> <param> - <key>win</key> - <value>firdes.WIN_HAMMING</value> + <key>type</key> + <value>ccc</value> </param> </block> <block> @@ -770,7 +851,7 @@ </param> <param> <key>gain0</key> - <value>10</value> + <value>20</value> </param> <param> <key>ant1</key> @@ -982,177 +1063,89 @@ </param> </block> <block> - <key>wxgui_scopesink2</key> - <param> - <key>ac_couple</key> - <value>False</value> - </param> - <param> - <key>alias</key> - <value></value> - </param> + <key>pad_sink</key> <param> <key>comment</key> <value></value> </param> - <param> - <key>affinity</key> - <value></value> - </param> <param> <key>_enabled</key> - <value>1</value> + <value>True</value> </param> <param> <key>_coordinate</key> - <value>(864, 135)</value> + <value>(200, 516)</value> </param> <param> <key>_rotation</key> <value>0</value> </param> - <param> - <key>grid_pos</key> - <value></value> - </param> <param> <key>id</key> - <value>wxgui_scopesink2_0</value> - </param> - <param> - <key>notebook</key> - <value></value> - </param> - <param> - <key>num_inputs</key> - <value>1</value> - </param> - <param> - <key>samp_rate</key> - <value>samp_rate</value> - </param> - <param> - <key>t_scale</key> - <value>1e-4</value> - </param> - <param> - <key>title</key> - <value>Scope Plot</value> - </param> - <param> - <key>trig_mode</key> - <value>wxgui.TRIG_MODE_AUTO</value> + <value>pad_sink_0</value> </param> <param> <key>type</key> - <value>float</value> + <value></value> </param> <param> - <key>v_offset</key> - <value>0</value> + <key>label</key> + <value>out</value> </param> <param> - <key>v_scale</key> + <key>num_streams</key> <value>1</value> </param> <param> - <key>win_size</key> - <value></value> - </param> - <param> - <key>xy_mode</key> + <key>optional</key> <value>False</value> </param> <param> - <key>y_axis_label</key> - <value>Counts</value> + <key>vlen</key> + <value>1</value> </param> </block> <block> - <key>wxgui_scopesink2</key> - <param> - <key>ac_couple</key> - <value>False</value> - </param> - <param> - <key>alias</key> - <value></value> - </param> + <key>pad_sink</key> <param> <key>comment</key> <value></value> </param> - <param> - <key>affinity</key> - <value></value> - </param> <param> <key>_enabled</key> - <value>1</value> + <value>True</value> </param> <param> <key>_coordinate</key> - <value>(864, 287)</value> + <value>(312, 516)</value> </param> <param> <key>_rotation</key> - <value>0</value> - </param> - <param> - <key>grid_pos</key> - <value></value> + <value>180</value> </param> <param> <key>id</key> - <value>wxgui_scopesink2_0_0</value> - </param> - <param> - <key>notebook</key> - <value></value> - </param> - <param> - <key>num_inputs</key> - <value>1</value> - </param> - <param> - <key>samp_rate</key> - <value>samp_rate</value> - </param> - <param> - <key>t_scale</key> - <value>1e-4</value> - </param> - <param> - <key>title</key> - <value>Scope Plot</value> - </param> - <param> - <key>trig_mode</key> - <value>wxgui.TRIG_MODE_AUTO</value> + <value>pad_sink_0_0</value> </param> <param> <key>type</key> - <value>float</value> + <value></value> </param> <param> - <key>v_offset</key> - <value>0</value> + <key>label</key> + <value>out</value> </param> <param> - <key>v_scale</key> + <key>num_streams</key> <value>1</value> </param> <param> - <key>win_size</key> - <value></value> - </param> - <param> - <key>xy_mode</key> + <key>optional</key> <value>False</value> </param> <param> - <key>y_axis_label</key> - <value>Counts</value> + <key>vlen</key> + <value>1</value> </param> </block> <connection> @@ -1168,50 +1161,62 @@ <sink_key>0</sink_key> </connection> <connection> - <source_block_id>blocks_threshold_ff_0</source_block_id> - <sink_block_id>wxgui_scopesink2_0_0</sink_block_id> + <source_block_id>blocks_head_0</source_block_id> + <sink_block_id>blocks_file_sink_0</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> <connection> - <source_block_id>blocks_threshold_ff_0_0</source_block_id> - <sink_block_id>wxgui_scopesink2_0</sink_block_id> + <source_block_id>blocks_head_0</source_block_id> + <sink_block_id>freq_xlating_fir_filter_0_1</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> <connection> - <source_block_id>freq_xlating_fir_filter_0_1</source_block_id> - <sink_block_id>low_pass_filter_0_1</sink_block_id> + <source_block_id>blocks_head_0</source_block_id> + <sink_block_id>freq_xlating_fir_filter_1</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> <connection> - <source_block_id>freq_xlating_fir_filter_1</source_block_id> - <sink_block_id>low_pass_filter_1</sink_block_id> + <source_block_id>blocks_message_sink_0</source_block_id> + <sink_block_id>pad_sink_0</sink_block_id> + <source_key>msg</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>blocks_message_sink_1</source_block_id> + <sink_block_id>pad_sink_0_0</sink_block_id> + <source_key>msg</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>blocks_threshold_ff_0</source_block_id> + <sink_block_id>blocks_message_sink_0</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> <connection> - <source_block_id>low_pass_filter_0_1</source_block_id> - <sink_block_id>blocks_complex_to_mag_squared_1_0</sink_block_id> + <source_block_id>blocks_threshold_ff_0_0</source_block_id> + <sink_block_id>blocks_message_sink_1</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> <connection> - <source_block_id>low_pass_filter_1</source_block_id> - <sink_block_id>blocks_complex_to_mag_squared_1</sink_block_id> + <source_block_id>freq_xlating_fir_filter_0_1</source_block_id> + <sink_block_id>blocks_complex_to_mag_squared_1_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>freq_xlating_fir_filter_0_1</sink_block_id> + <source_block_id>freq_xlating_fir_filter_1</source_block_id> + <sink_block_id>blocks_complex_to_mag_squared_1</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>freq_xlating_fir_filter_1</sink_block_id> + <sink_block_id>blocks_head_0</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> diff --git a/gr_grc/scripts/dump_to_signal_blocks.py b/gr_grc/scripts/dump_to_signal_blocks.py deleted file mode 100644 index 2252908efdd520f36ca6dce65474dde9cd9db58f..0000000000000000000000000000000000000000 --- a/gr_grc/scripts/dump_to_signal_blocks.py +++ /dev/null @@ -1,159 +0,0 @@ -#!/usr/bin/env python2 -# -*- coding: utf-8 -*- - -import sys - -import numpy as np - -from gnuradio import blocks -from gnuradio import gr - -class top_block(gr.top_block): - - def __init__(self, samp_rate=2e6, file_path=sys.argv[1]): - gr.top_block.__init__(self, "Top Block") - - ################################################## - # Variables - ################################################## - self.samp_rate = samp_rate - - # Queue - self.msgq_out = blocks_message_sink_0_msgq_out = gr.msg_queue(0) - - ################################################## - # Blocks - ################################################## - self.blocks_throttle_0 = blocks.throttle(gr.sizeof_gr_complex*1, \ - 10*samp_rate, \ - True) - #self.threshold = 0.0006 - # 0.0000317 - # 0.00031 - self.threshold = 3.17382e-05*2 - - self.blocks_threshold_ff_0 = blocks.threshold_ff(self.threshold, self.threshold) - self.blocks_message_sink_0 = blocks.message_sink(gr.sizeof_float*1, \ - blocks_message_sink_0_msgq_out, \ - False) - self.blocks_file_source_0 = blocks.file_source(gr.sizeof_gr_complex*1, \ - str(file_path), \ - False) - self.blocks_complex_to_mag_squared_0 = blocks.complex_to_mag_squared(1) - - ################################################## - # Connections - ################################################## - # file_source → throttle → complex_to_max_squared → threshold → message_sink - self.connect((self.blocks_complex_to_mag_squared_0, 0), (self.blocks_threshold_ff_0, 0)) - self.connect((self.blocks_file_source_0, 0), (self.blocks_throttle_0, 0)) - self.connect((self.blocks_threshold_ff_0, 0), (self.blocks_message_sink_0, 0)) - self.connect((self.blocks_throttle_0, 0), (self.blocks_complex_to_mag_squared_0, 0)) - - def get_samp_rate(self): - return self.samp_rate - - def set_samp_rate(self, samp_rate): - self.samp_rate = samp_rate - self.blocks_throttle_0.set_sample_rate(self.samp_rate) - - -def main(top_block_cls=top_block, options=None): - """ - What does this function do? - - 1. Run flowgraph and do energy based signal detection write results into - message queue. - 2. Read iq dump file and count samples. - 3. Start reading data from flowgraph message queue. - 4. Counting some data: - a) 1s and 0s - b) number of all samples - 5. If there are ones, save section into a array with hashes and merge depending - sections. - 6. Print results. - """ - # Section 1 - tb = top_block_cls() - tb.start() - - # Section 2 - data = np.memmap(open(sys.argv[1]), mode="r", dtype=np.complex64) - samples_in_file = len(data) - print("sum of all samples: %s\n" % samples_in_file) - - count_zero = 0 - count_one = 0 - samples_sum = 0 - - arrays_with_ones = [] - - # Section 3 - # just loop until all samples are processed - while True: - # pull from message queue - msg = tb.msgq_out.delete_head() - msg_string = msg.to_string() - - # convert string with floats into an numpy array - samples = np.fromstring(msg_string, dtype='float32') - # Section 4: do some counting - ones = np.count_nonzero(samples) - count_one += ones - count_zero += np.count_nonzero(samples != 1.0) - - # Section 5 - if ones > 0 and np.count_nonzero(samples) > 150: - # skip first message queue sample - if len(arrays_with_ones) == 0: - hash = {} - hash['count_before_array'] = samples_sum - hash['samples'] = samples - - arrays_with_ones.append(hash) - else: - last_recorded_samples = arrays_with_ones[-1] - if (last_recorded_samples['count_before_array'] + \ - len(last_recorded_samples['samples'])) == samples_sum: - - print("ones in block: %s samples: %s" % (np.count_nonzero(samples), len(samples))) - for sample in samples: - arrays_with_ones[-1]['samples'] = np.append \ - (arrays_with_ones[-1]['samples'], sample) - - else: - hash = {} - hash['count_before_array'] = int(samples_sum) - hash['samples'] = samples - arrays_with_ones.append(hash) - - - samples_sum += len(samples) - if samples_sum == samples_in_file: - break - - # Section 6 - print("%s of %s sample" % (samples_sum, samples_in_file)) - print("zero: %s" % count_zero) - print("one: %s" % count_one) - print("ones in time (1/2e6)*%s = %ss = %sms\n" % (count_one, 1/2e6*count_one, 1/2e6*count_one*1000)) - print("print sections with ones:") - - for hash in arrays_with_ones: - string = "" - print("Count: %s" % hash['count_before_array']) - for items in hash['samples']: - string += str(int(items)) - - print("%s\n" % string) - - print("\nSignal sections:\n") - for i, hash in enumerate(arrays_with_ones): - samples_count = len(hash['samples']) - section_length_in_ms = 1/2e6*samples_count*1000 - print("start: %s end: %s time: %sms" % (hash['count_before_array'], \ - samples_count+hash['count_before_array'], \ - section_length_in_ms)) - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/gr_grc/scripts/measure_sample_and_time.py b/gr_grc/scripts/measure_sample_and_time.py deleted file mode 100644 index a115b92e63c4c49da3de78c900a805fe6630626b..0000000000000000000000000000000000000000 --- a/gr_grc/scripts/measure_sample_and_time.py +++ /dev/null @@ -1,118 +0,0 @@ -#!/usr/bin/env python2 -# -*- coding: utf-8 -*- -################################################## -# GNU Radio Python Flow Graph -# Title: Top Block -# Generated: Mon Jan 18 14:03:47 2016 -################################################## - -import time - -from gnuradio import blocks -from gnuradio import eng_notation -from gnuradio import gr -from gnuradio.eng_option import eng_option -from gnuradio.filter import firdes -from optparse import OptionParser -import osmosdr - -import numpy as np - -class top_block(gr.top_block): - - def __init__(self): - gr.top_block.__init__(self, "Top Block") - - ################################################## - # Variables - ################################################## - self.time = time = 60 - self.samp_rate = samp_rate = 2e6 - self.freq = freq = 868e6 - - ################################################## - # Blocks - ################################################## - self.osmosdr_source_0 = osmosdr.source( args="numchan=" + str(1) + " " + "" ) - self.osmosdr_source_0.set_sample_rate(samp_rate) - self.osmosdr_source_0.set_center_freq(freq, 0) - self.osmosdr_source_0.set_freq_corr(0, 0) - self.osmosdr_source_0.set_dc_offset_mode(0, 0) - self.osmosdr_source_0.set_iq_balance_mode(0, 0) - self.osmosdr_source_0.set_gain_mode(False, 0) - self.osmosdr_source_0.set_gain(0, 0) - self.osmosdr_source_0.set_if_gain(20, 0) - self.osmosdr_source_0.set_bb_gain(20, 0) - self.osmosdr_source_0.set_antenna("", 0) - self.osmosdr_source_0.set_bandwidth(0, 0) - - self.blocks_head_0 = blocks.head(gr.sizeof_gr_complex*1, int(samp_rate)*time) - self.blocks_file_sink_0 = blocks.file_sink(gr.sizeof_gr_complex*1, "/home/meise/tmp/sample.iq", False) - self.blocks_file_sink_0.set_unbuffered(False) - - ################################################## - # Connections - ################################################## - self.connect((self.blocks_head_0, 0), (self.blocks_file_sink_0, 0)) - self.connect((self.osmosdr_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.osmosdr_source_0.set_sample_rate(self.samp_rate) - - def get_freq(self): - return self.freq - - def set_freq(self, freq): - self.freq = freq - self.osmosdr_source_0.set_center_freq(self.freq, 0) - - -def count_samples(): - file_path = "/home/meise/tmp/sample.iq" - - # convert file into pynum array and use a memory map - f = np.memmap(open(file_path), mode="r", dtype=np.complex64) - - return len(f) - -def main(top_block_cls=top_block, options=None): - tb = top_block_cls() - tb.start() - tb.wait() - - -if __name__ == '__main__': - measurements = [] - - for i in range(0, 10): - m = {} - m['start_time'] = time.clock() - main() - m['end_time'] = time.clock() - - m['running_time'] = m['end_time']-m['start_time'] - m['samples_count'] = count_samples() - m['count'] = i+1 - m['expacted_time'] = 60 - - measurements.append(m) - - for m in measurements: - print("%s;%s;%s;%s;%s;%s" % (m['count'], \ - m['running_time'], \ - m['samples_count'], \ - m['start_time'], \ - m['end_time'], - m['expacted_time'])) diff --git a/gr_grc/scripts/show_enocean_telegram_from_file.py b/gr_grc/scripts/show_enocean_telegram_from_file.py deleted file mode 100644 index 44b7e1228ca95ddcb8d01991750b54070aa3c14a..0000000000000000000000000000000000000000 --- a/gr_grc/scripts/show_enocean_telegram_from_file.py +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env python2.7 -# -*- encoding: utf-8 -*- - -import numpy as np -import sys -import re - -data = np.memmap(open(sys.argv[1]), mode="r", dtype=np.float32) - -string = "" -messages = [] -for i, val in enumerate(data): - string += str(int(val)) - - if i%1000 == 0: - if re.search(r"[1]{6,7}[0]{1,2}", string): - messages.append(string) - elif re.search(r"[1]{5,6}[0]{6,7}", string): - messages.append(string) - - string = "" - -for i in messages: - print(i) diff --git a/gr_grc/scripts/spectrogram.py b/gr_grc/scripts/spectrogram.py deleted file mode 100644 index 3f69c53ff59387c255ae9b5b464854c011092366..0000000000000000000000000000000000000000 --- a/gr_grc/scripts/spectrogram.py +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env python2.7 -# -*- encoding: utf-8 -*- - -import math -import numpy as np -from pylab import plot,show,subplot,specgram - -from scipy.fftpack import fft, ifft - -file_path = "/home/meise/tmp/iq_dumps/enocean/868_2m_enocean.iq" - -# convert file into pynum array and use a memory map -data = np.memmap(open(file_path), mode="r", dtype=np.complex64) - -print(data.__class__) -print("samples: %s" % len(data)) - -specgram(abs(data), NFFT=262144, noverlap=0, mode='default') # small window - -show() diff --git a/gr_grc/scripts/spectrogram_demo_gr.py b/gr_grc/scripts/spectrogram_demo_gr.py deleted file mode 100644 index 3dab0535ab2ba4309500e59108b89ccf5bb73777..0000000000000000000000000000000000000000 --- a/gr_grc/scripts/spectrogram_demo_gr.py +++ /dev/null @@ -1,291 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2007,2008,2010,2011 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -try: - import scipy - from scipy import fftpack -except ImportError: - print "Please install SciPy to run this script (http://www.scipy.org/)" - raise SystemExit, 1 - -try: - from pylab import * -except ImportError: - print "Please install Matplotlib to run this script (http://matplotlib.sourceforge.net/)" - raise SystemExit, 1 - -from optparse import OptionParser -from scipy import log10 -from gnuradio.eng_option import eng_option - -class gr_plot_psd: - def __init__(self, datatype, filename, options): - self.hfile = open(filename, "r") - self.block_length = options.block - self.start = options.start - self.sample_rate = options.sample_rate - self.psdfftsize = options.psd_size - self.specfftsize = options.spec_size - - self.dospec = options.enable_spec # if we want to plot the spectrogram - - self.datatype = getattr(scipy, datatype) #scipy.complex64 - self.sizeof_data = self.datatype().nbytes # number of bytes per sample in file - - self.axis_font_size = 16 - self.label_font_size = 18 - self.title_font_size = 20 - self.text_size = 22 - - # Setup PLOT - self.fig = figure(1, figsize=(16, 12), facecolor='w') - rcParams['xtick.labelsize'] = self.axis_font_size - rcParams['ytick.labelsize'] = self.axis_font_size - - self.text_file = figtext(0.10, 0.95, ("File: %s" % filename), - weight="heavy", size=self.text_size) - self.text_file_pos = figtext(0.10, 0.92, "File Position: ", - weight="heavy", size=self.text_size) - self.text_block = figtext(0.35, 0.92, ("Block Size: %d" % self.block_length), - weight="heavy", size=self.text_size) - self.text_sr = figtext(0.60, 0.915, ("Sample Rate: %.2f" % self.sample_rate), - weight="heavy", size=self.text_size) - self.make_plots() - - self.button_left_axes = self.fig.add_axes([0.45, 0.01, 0.05, 0.05], frameon=True) - self.button_left = Button(self.button_left_axes, "<") - self.button_left_callback = self.button_left.on_clicked(self.button_left_click) - - self.button_right_axes = self.fig.add_axes([0.50, 0.01, 0.05, 0.05], frameon=True) - self.button_right = Button(self.button_right_axes, ">") - self.button_right_callback = self.button_right.on_clicked(self.button_right_click) - - self.xlim = scipy.array(self.sp_iq.get_xlim()) - - self.manager = get_current_fig_manager() - connect('draw_event', self.zoom) - connect('key_press_event', self.click) - show() - - def get_data(self): - self.position = self.hfile.tell()/self.sizeof_data - self.text_file_pos.set_text("File Position: %d" % self.position) - try: - self.iq = scipy.fromfile(self.hfile, dtype=self.datatype, count=self.block_length) - except MemoryError: - print "End of File" - return False - else: - # retesting length here as newer version of scipy does not throw a MemoryError, just - # returns a zero-length array - if(len(self.iq) > 0): - tstep = 1.0 / self.sample_rate - #self.time = scipy.array([tstep*(self.position + i) for i in xrange(len(self.iq))]) - self.time = scipy.array([tstep*(i) for i in xrange(len(self.iq))]) - - self.iq_psd, self.freq = self.dopsd(self.iq) - return True - else: - print "End of File" - return False - - def dopsd(self, iq): - ''' Need to do this here and plot later so we can do the fftshift ''' - overlap = self.psdfftsize/4 - winfunc = scipy.blackman - psd,freq = mlab.psd(iq, self.psdfftsize, self.sample_rate, - window = lambda d: d*winfunc(self.psdfftsize), - noverlap = overlap) - psd = 10.0*log10(abs(psd)) - return (psd, freq) - - def make_plots(self): - # if specified on the command-line, set file pointer - self.hfile.seek(self.sizeof_data*self.start, 1) - - iqdims = [[0.075, 0.2, 0.4, 0.6], [0.075, 0.55, 0.4, 0.3]] - psddims = [[0.575, 0.2, 0.4, 0.6], [0.575, 0.55, 0.4, 0.3]] - specdims = [0.2, 0.125, 0.6, 0.3] - - # Subplot for real and imaginary parts of signal - self.sp_iq = self.fig.add_subplot(2,2,1, position=iqdims[self.dospec]) - self.sp_iq.set_title(("I&Q"), fontsize=self.title_font_size, fontweight="bold") - self.sp_iq.set_xlabel("Time (s)", fontsize=self.label_font_size, fontweight="bold") - self.sp_iq.set_ylabel("Amplitude (V)", fontsize=self.label_font_size, fontweight="bold") - - # Subplot for PSD plot - self.sp_psd = self.fig.add_subplot(2,2,2, position=psddims[self.dospec]) - self.sp_psd.set_title(("PSD"), fontsize=self.title_font_size, fontweight="bold") - self.sp_psd.set_xlabel("Frequency (Hz)", fontsize=self.label_font_size, fontweight="bold") - self.sp_psd.set_ylabel("Power Spectrum (dBm)", fontsize=self.label_font_size, fontweight="bold") - - r = self.get_data() - - self.plot_iq = self.sp_iq.plot([], 'bo-') # make plot for reals - self.plot_iq += self.sp_iq.plot([], 'ro-') # make plot for imags - self.draw_time(self.time, self.iq) # draw the plot - - self.plot_psd = self.sp_psd.plot([], 'b') # make plot for PSD - self.draw_psd(self.freq, self.iq_psd) # draw the plot - - - if self.dospec: - # Subplot for spectrogram plot - self.sp_spec = self.fig.add_subplot(2,2,3, position=specdims) - self.sp_spec.set_title(("Spectrogram"), fontsize=self.title_font_size, fontweight="bold") - self.sp_spec.set_xlabel("Time (s)", fontsize=self.label_font_size, fontweight="bold") - self.sp_spec.set_ylabel("Frequency (Hz)", fontsize=self.label_font_size, fontweight="bold") - - self.draw_spec(self.time, self.iq) - - draw() - - def draw_time(self, t, iq): - reals = iq.real - imags = iq.imag - self.plot_iq[0].set_data([t, reals]) - self.plot_iq[1].set_data([t, imags]) - self.sp_iq.set_xlim(t.min(), t.max()) - self.sp_iq.set_ylim([1.5*min([reals.min(), imags.min()]), - 1.5*max([reals.max(), imags.max()])]) - - def draw_psd(self, f, p): - self.plot_psd[0].set_data([f, p]) - self.sp_psd.set_ylim([p.min()-10, p.max()+10]) - self.sp_psd.set_xlim([f.min(), f.max()]) - - def draw_spec(self, t, s): - overlap = self.specfftsize/4 - winfunc = scipy.blackman - self.sp_spec.clear() - self.sp_spec.specgram(s, self.specfftsize, self.sample_rate, - window = lambda d: d*winfunc(self.specfftsize), - noverlap = overlap, xextent=[t.min(), t.max()]) - - def update_plots(self): - self.draw_time(self.time, self.iq) - self.draw_psd(self.freq, self.iq_psd) - - if self.dospec: - self.draw_spec(self.time, self.iq) - - self.xlim = scipy.array(self.sp_iq.get_xlim()) # so zoom doesn't get called - - draw() - - def zoom(self, event): - newxlim = scipy.array(self.sp_iq.get_xlim()) - curxlim = scipy.array(self.xlim) - if(newxlim[0] != curxlim[0] or newxlim[1] != curxlim[1]): - #xmin = max(0, int(ceil(self.sample_rate*(newxlim[0] - self.position)))) - #xmax = min(int(ceil(self.sample_rate*(newxlim[1] - self.position))), len(self.iq)) - xmin = max(0, int(ceil(self.sample_rate*(newxlim[0])))) - xmax = min(int(ceil(self.sample_rate*(newxlim[1]))), len(self.iq)) - - iq = scipy.array(self.iq[xmin : xmax]) - time = scipy.array(self.time[xmin : xmax]) - - iq_psd, freq = self.dopsd(iq) - - self.draw_psd(freq, iq_psd) - self.xlim = scipy.array(self.sp_iq.get_xlim()) - - draw() - - def click(self, event): - forward_valid_keys = [" ", "down", "right"] - backward_valid_keys = ["up", "left"] - - if(find(event.key, forward_valid_keys)): - self.step_forward() - - elif(find(event.key, backward_valid_keys)): - self.step_backward() - - def button_left_click(self, event): - self.step_backward() - - def button_right_click(self, event): - self.step_forward() - - def step_forward(self): - r = self.get_data() - if(r): - self.update_plots() - - def step_backward(self): - # Step back in file position - if(self.hfile.tell() >= 2*self.sizeof_data*self.block_length ): - self.hfile.seek(-2*self.sizeof_data*self.block_length, 1) - else: - self.hfile.seek(-self.hfile.tell(),1) - r = self.get_data() - if(r): - self.update_plots() - -def find(item_in, list_search): - try: - return list_search.index(item_in) != None - except ValueError: - return False - -def setup_options(): - usage="%prog: [options] input_filename" - description = "Takes a GNU Radio binary file (with specified data type using --data-type) and displays the I&Q data versus time as well as the power spectral density (PSD) plot. The y-axis values are plotted assuming volts as the amplitude of the I&Q streams and converted into dBm in the frequency domain (the 1/N power adjustment out of the FFT is performed internally). The script plots a certain block of data at a time, specified on the command line as -B or --block. The start position in the file can be set by specifying -s or --start and defaults to 0 (the start of the file). By default, the system assumes a sample rate of 1, so in time, each sample is plotted versus the sample number. To set a true time and frequency axis, set the sample rate (-R or --sample-rate) to the sample rate used when capturing the samples. Finally, the size of the FFT to use for the PSD and spectrogram plots can be set independently with --psd-size and --spec-size, respectively. The spectrogram plot does not display by default and is turned on with -S or --enable-spec." - - parser = OptionParser(option_class=eng_option, conflict_handler="resolve", - usage=usage, description=description) - parser.add_option("-d", "--data-type", type="string", default="complex64", - help="Specify the data type (complex64, float32, (u)int32, (u)int16, (u)int8) [default=%default]") - parser.add_option("-B", "--block", type="int", default=8192, - help="Specify the block size [default=%default]") - parser.add_option("-s", "--start", type="int", default=0, - help="Specify where to start in the file [default=%default]") - parser.add_option("-R", "--sample-rate", type="eng_float", default=1.0, - help="Set the sampler rate of the data [default=%default]") - parser.add_option("", "--psd-size", type="int", default=1024, - help="Set the size of the PSD FFT [default=%default]") - parser.add_option("", "--spec-size", type="int", default=256, - help="Set the size of the spectrogram FFT [default=%default]") - parser.add_option("-S", "--enable-spec", action="store_true", default=False, - help="Turn on plotting the spectrogram [default=%default]") - - return parser - -def main(): - parser = setup_options() - (options, args) = parser.parse_args () - if len(args) != 1: - parser.print_help() - raise SystemExit, 1 - filename = args[0] - - dc = gr_plot_psd(options.data_type, filename, options) - -if __name__ == "__main__": - try: - main() - except KeyboardInterrupt: - pass - - - diff --git a/lib/capture_file.py b/lib/capture_file.py new file mode 100644 index 0000000000000000000000000000000000000000..9ede12268325a2c02e2c875b70a85f8c0ee54cbb --- /dev/null +++ b/lib/capture_file.py @@ -0,0 +1,40 @@ +# -*- encoding: utf-8 -*- + +import hashlib +import yaml + + +class CaptureFile(object): + def __init__(self, path, time, freq, samp_rate, tag): + self.captue_file = path + self.time = time + self.tag = tag + self.freq = freq + self.samp_rate = samp_rate + + self.md5 = None + self.signal_blocks = [] + self.samp_rate = None + + def md5(self): + return self.md5sum() + + def md5sum(self): + """ + Return md5 hash of capture file. + """ + if self.md5 == None: + file_hash = hashlib.md5() + with open(self.captue_file, "rb") as file: + for chunk in iter(lambda: file.read(4096), b""): + file_hash.update(chunk) + + self.md5 = file_hash.hexdigest() + + return self.md5 + + def toYaml(self, yaml_path): + print(yaml_path) + print(self.__dict__) + with open(yaml_path, 'w') as outfile: + outfile.write(yaml.dump(self.__dict__, default_flow_style=False)) diff --git a/lib/detector.py b/lib/detector.py new file mode 100644 index 0000000000000000000000000000000000000000..69027fc5704831844eab94b4cc7b6d0d1503fc9e --- /dev/null +++ b/lib/detector.py @@ -0,0 +1,13 @@ +# -*- encoding: utf-8 -*- + +class Detector(object): + + @staticmethod + def detect_modulation(msg): + """ + Return guessed modulation in message. + """ + if msg.find("1"*700) == -1: + return "ASK" + else: + return "FSK" diff --git a/lib/gr/file_sink.py b/lib/gr/file_sink.py index 0d6729d686e0b5a208d3e6f5df14aaf69a18f862..2823bef65d59b4895a19984b05ec302c6c7b3054 100644 --- a/lib/gr/file_sink.py +++ b/lib/gr/file_sink.py @@ -2,18 +2,25 @@ import os import logging +import time +import numpy as np +import yaml from gnuradio import blocks from gnuradio import eng_notation from gnuradio import gr from gnuradio.eng_option import eng_option from gnuradio.filter import firdes +from gnuradio import filter from optparse import OptionParser import osmosdr from PyQt5.QtCore import QThread, pyqtSignal, QObject from lib.disk import Disk +from lib.transmission import Transmission +from lib.capture_file import CaptureFile +from lib.detector import Detector class FileSink(gr.top_block): """ @@ -24,6 +31,8 @@ class FileSink(gr.top_block): freq, capture_time, dump_file, + threshold, + tag, device=None ): gr.top_block.__init__(self, "file_sink_block") @@ -31,9 +40,23 @@ class FileSink(gr.top_block): self.samp_rate = samp_rate self.freq = freq self.capture_time = capture_time - self.file_path = dump_file - self.device = osmosdr.source( args="numchan=" + str(1) + " " + "osmosdr=0" ) - + self.file_path = str(dump_file) + self.threshold_ff_min = float(threshold) + self.threshold_ff_max = float(threshold) + self.device = self.osmosdr_source_0 = osmosdr.source( args="numchan=" + str(1) + " " + "" ) + self.tag = tag + self.center_freq_0 = 3e5 + self.center_freq_1 = 9.5e5 + # low pass filter 1% - 868.0 - 868.6 + self.cutoff_freq_0 = cutoff_freq_0 = 3.5e5 + self.transition_width_0 = transition_width_0 = cutoff_freq_0/2 + # low pass filter 0.1% - 868.7 - 869.2 + self.cutoff_freq_1 = cutoff_freq_1 = 2.5e5 + self.transition_width_1 = transition_width_1 = cutoff_freq_1/2 + # msg queue for 1% section + self.msgq_out_0 = self.blocks_message_sink_0_msgq_out = gr.msg_queue(0) + # msg queue for 0.1% + self.msgq_out_1 = self.blocks_message_sink_1_msgq_out = gr.msg_queue(0) def needed_disc_space(self): """ @@ -45,7 +68,6 @@ class FileSink(gr.top_block): """ Capture alias """ - # self.capture() print("capture started") def capture(self): @@ -55,6 +77,7 @@ class FileSink(gr.top_block): self._build_blocks() logging.info("Start '%s' capture." % self.file_path) self.start() + self._start_live_processing() self.wait() logging.info("Capture '%s' done." % self.file_path) @@ -67,36 +90,170 @@ class FileSink(gr.top_block): def get_capture_device(self): return self.device + def _start_live_processing(self): + cf = CaptureFile("data.iq", int(time.time()), self.freq, self.samp_rate, self.tag) + samples_len_0, samples_len_1 = 0, 0 # current samples count in buffer + results_0 , results_1 = {}, {} + + results_0['samples_count'], results_1['samples_count'] = 0, 0 # all processed samples + results_0['messages'], results_1['messages'] = [], [] + results_0['time_added'], results_1['time_added']= 0, 0 + results_0['block_samples_start'], results_1['block_samples_start']= 0, 0 + results_0['transmission_counter'], results_1['transmission_counter'] = 0, 0 + results_0['cf'], results_1['cf'] = cf, cf + + while True: + # read data from msg queue and convert it to a numpy array + # counting ones in np array is faster then counting them in a sting + msg_0 = self.msgq_out_0.delete_head() + samples_0 = np.fromstring(msg_0.to_string(), dtype='float32') + samples_len_0 = len(samples_0) + + msg_1 = self.msgq_out_1.delete_head() + samples_1 = np.fromstring(msg_1.to_string(), dtype='float32') + samples_len_1 = len(samples_1) + + results_0 = self._process_samples(samples_0, results_0) + results_1 = self._process_samples(samples_1, results_1) + + results_0['samples_count'] += samples_len_0 + results_1['samples_count'] += samples_len_1 + + def _process_samples(self, samples, results): + # skip samples with only zeros + if np.count_nonzero(samples) != 0 or results['time_added'] != 0: + # convert array to string + string = "" + for i in samples: + string += str(int(i)) + + if len(results['messages']) == 0: + results['block_samples_start'] = results['samples_count'] + + results['messages'].append(string) + + if results['time_added'] == 0: + results['time_added'] = time.time() + + # output transmission block after 500ms + if results['time_added'] != 0 and (time.time()-results['time_added']) > 1: + # join message blocks + msg = "".join(results['messages']) + # do some calculations + + first_one = msg.find("1") + last_one = msg.rfind("1") + transmission_time = round(1/self.samp_rate*(int(msg.count("1"))*1000), 2) # in ms + real_transmission_time = round(1/self.samp_rate*(int(last_one-first_one)*1000), 2) # in ms + + results['transmission_counter'] += 1 + + tm = Transmission(results['transmission_counter']) + tm.start = results['block_samples_start'] + tm.samples = len(msg) + tm.plot = None + tm.freq = self.freq + tm.first_one = first_one + tm.last_one = last_one + tm.transmission_time = transmission_time + tm.real_transmission_time = real_transmission_time + tm.modulation = Detector.detect_modulation(msg) + + # append transmission and write data + results['cf'].signal_blocks.append(tm) + results['cf'].toYaml(os.path.dirname(self.file_path) + "/data.yml") + # print transmission + print(msg) + tm.print_transmission() + # clear variables for new transmission + results['messages'] = [] + results['block_samples_start'] = 0 + results['time_added'] = 0 + + return results + def _dump_file_writable(self): """ Check permissions for specified file dump path. """ Disk.path_writeble(self.file_path) + def _print_transmission_data(self, tm, msg="Not defined"): + print(msg) + tm.print_transmission() + def _build_blocks(self): """ Create gr blocks. """ # blocks - self.osmosdr_source_0 = self.device + # osmocom source self.osmosdr_source_0.set_sample_rate(self.samp_rate) self.osmosdr_source_0.set_center_freq(self.freq, 0) self.osmosdr_source_0.set_freq_corr(0, 0) self.osmosdr_source_0.set_dc_offset_mode(0, 0) self.osmosdr_source_0.set_iq_balance_mode(0, 0) self.osmosdr_source_0.set_gain_mode(False, 0) - self.osmosdr_source_0.set_gain(0, 0) + self.osmosdr_source_0.set_gain(20, 0) self.osmosdr_source_0.set_if_gain(20, 0) self.osmosdr_source_0.set_bb_gain(20, 0) self.osmosdr_source_0.set_antenna("", 0) self.osmosdr_source_0.set_bandwidth(0, 0) - self.blocks_head_0 = blocks.head(gr.sizeof_gr_complex*1, int(self.samp_rate)*self.capture_time) + # file sink self.blocks_file_sink_0 = blocks.file_sink(gr.sizeof_gr_complex*1, str(self.file_path), False) self.blocks_file_sink_0.set_unbuffered(False) + # FIR-Filter for 1% + self.freq_xlating_fir_filter_xxx_0 = filter.freq_xlating_fir_filter_ccc(1, (firdes.low_pass(1, self.samp_rate, self.transition_width_0, self.cutoff_freq_0, firdes.WIN_HAMMING, 6.76)), 3e5, self.samp_rate) + + # message sink for 1% + self.blocks_message_sink_0 = blocks.message_sink(gr.sizeof_float*1, self.blocks_message_sink_0_msgq_out, False) + + # FIR-Filter for 0.1% + self.freq_xlating_fir_filter_xxx_1 = filter.freq_xlating_fir_filter_ccc(1, (firdes.low_pass(1, self.samp_rate, self.transition_width_1, self.cutoff_freq_1, firdes.WIN_HAMMING, 6.76)), self.center_freq_1, self.samp_rate) + + + # message sink for 0.1% + self.blocks_message_sink_1 = blocks.message_sink(gr.sizeof_float*1, self.blocks_message_sink_1_msgq_out, False) + + # threshold block and energy based detecttion + self.blocks_threshold_ff_0 = blocks.threshold_ff(self.threshold_ff_min, self.threshold_ff_max, 0) + self.blocks_complex_to_mag_squared_0 = blocks.complex_to_mag_squared(1) + self.blocks_complex_to_mag_squared_1 = blocks.complex_to_mag_squared(1) + self.blocks_threshold_ff_1 = blocks.threshold_ff(self.threshold_ff_min, self.threshold_ff_max, 0) + self.blocks_complex_to_mag_squared_1 = blocks.complex_to_mag_squared(1) + + self.blocks_head_0 = blocks.head(gr.sizeof_gr_complex*1, int(self.capture_time*self.samp_rate)) + + self.blocks_file_sink_0 = blocks.file_sink(gr.sizeof_gr_complex*1, self.file_path, False) + ################################################## # Connections ################################################## - self.connect((self.blocks_head_0, 0), (self.blocks_file_sink_0, 0)) - self.connect((self.osmosdr_source_0, 0), (self.blocks_head_0, 0)) + # hardware source → head + self.connect((self.osmosdr_source_0, 0), + (self.blocks_head_0, 0)) + # head → fir + self.connect((self.blocks_head_0, 0), + (self.freq_xlating_fir_filter_xxx_0, 0)) + self.connect((self.blocks_head_0, 0), + (self.freq_xlating_fir_filter_xxx_1, 0)) + # head → file sink + self.connect((self.blocks_head_0, 0), + (self.blocks_file_sink_0, 0)) + # fir → complex to mag + self.connect((self.freq_xlating_fir_filter_xxx_0, 0), + (self.blocks_complex_to_mag_squared_0, 0)) + self.connect((self.freq_xlating_fir_filter_xxx_1, 0), + (self.blocks_complex_to_mag_squared_1, 0)) + # complex to mag → threshold + self.connect((self.blocks_complex_to_mag_squared_0, 0), + (self.blocks_threshold_ff_0, 0)) + self.connect((self.blocks_complex_to_mag_squared_1, 0), + (self.blocks_threshold_ff_1, 0)) + # threshold → message sink + self.connect((self.blocks_threshold_ff_0, 0), + (self.blocks_message_sink_0, 0)) + self.connect((self.blocks_threshold_ff_1, 0), + (self.blocks_message_sink_1, 0)) diff --git a/lib/gr/noise_detect.py b/lib/gr/noise_floor_detect.py similarity index 94% rename from lib/gr/noise_detect.py rename to lib/gr/noise_floor_detect.py index b835b15ee403f5214c685f746f496cd8119f83c4..2cffc414836c84fa04ac6028f0d365ece2d9a25f 100644 --- a/lib/gr/noise_detect.py +++ b/lib/gr/noise_floor_detect.py @@ -11,7 +11,9 @@ import osmosdr class NoiseFloorDetect(gr.top_block): - + """ + Detect and plot noise floor for given period of time. + """ def __init__(self, samp_rate, freq, @@ -28,9 +30,6 @@ class NoiseFloorDetect(gr.top_block): self._build_blocks() def detect(self): - """ - - """ self.start() samples_count = 0 @@ -67,13 +66,15 @@ class NoiseFloorDetect(gr.top_block): self.samp_rate = samp_rate self.blocks_throttle_0.set_sample_rate(self.samp_rate) - def _plot_data(self, samples, samp_rate=2e6): + def _plot_data(self, samples, samp_rate=None): + if samp_rate == None: + samp_rate = self.samp_rate result = {} # 1. split samples into 1s sections and extract max value # 2. threshold is calculated as median + min value max_sections = [] - for i in range(0, int(len(samples)/2e6)-1): + for i in range(0, int(len(samples)/samp_rate)-1): amax = np.amax(samples[i*int(samp_rate):(i+1)*int(samp_rate)]) max_sections.append(amax) @@ -149,4 +150,4 @@ class NoiseFloorDetect(gr.top_block): self.connect((self.blocks_head_0, 0), (self.blocks_complex_to_mag_squared_0, 0)) self.connect((self.blocks_complex_to_mag_squared_0, 0), - (self.blocks_message_sink_0, 0)) \ No newline at end of file + (self.blocks_message_sink_0, 0)) diff --git a/lib/gr/render_specgram.py b/lib/gr/render_specgram.py deleted file mode 100644 index 423048be9bceb91d3e1fb52ce79a3628ebf98bb5..0000000000000000000000000000000000000000 --- a/lib/gr/render_specgram.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- - -import os - -import scipy -import matplotlib.pyplot as plt -import numpy as np - -from lib.disk import Disk - -class RenderSpecgram(object): - - def __init__(self, source, destination): - self.source = source - self.destination = destination diff --git a/lib/gui/gui.py b/lib/gui/gui.py index 524447b4214fa189422aa3336c83685861860458..e0d0bcbc5fd1db8e945053a0a4bf6888f63a61b7 100644 --- a/lib/gui/gui.py +++ b/lib/gui/gui.py @@ -12,7 +12,7 @@ from lib.su import Su from lib.disk import Disk from lib.gr.file_sink import FileSink -from lib.gr.noise_detect import NoiseFloorDetect +from lib.gr.noise_floor_detect import NoiseFloorDetect from lib.gui.update_progress_bar import UpdateProgressBar from lib.gui.capture import Capture @@ -106,7 +106,9 @@ class SuGui(QtWidgets.QMainWindow): file_sink = FileSink(options['samp_rate'], options['freq'], options['capture_time'], - capture_path + "/data.iq") + capture_path + "/data.iq", + options['threshold'], + options['tag']) self.button_stop.setEnabled(True) self.button_start.setEnabled(False) @@ -288,14 +290,7 @@ class SuGui(QtWidgets.QMainWindow): self._set_setEnabled(True) def _check_samp_rate(self): - if self.rb_868.isChecked(): - self.rb_1mhz.setEnabled(True) - - if self.rb_1mhz.isChecked(): - self.rb_1mhz.setChecked(False) - self.rb_2mhz.setChecked(True) - else: - self.rb_1mhz.setEnabled(True) + pass def _configure_enocean(self): self.rb_868.setChecked(True) @@ -380,6 +375,11 @@ class SuGui(QtWidgets.QMainWindow): "Select RF hardware.") self.refresh_hw_button() return False + elif len(self.lineEdit_nf.text()) == 0: + QtWidgets.QMessageBox.about(self, "Threshold missing…", + "Please add threshold.") + self.lineEdit_nf.setText("0.00686") + return False else: return True @@ -455,5 +455,6 @@ class SuGui(QtWidgets.QMainWindow): # dropdown boxes options['device'] = self._extract_selected_hardware_device() options['tag'] = self.lineEdit_tag.text() + options['threshold'] = self.lineEdit_nf.text() return options diff --git a/lib/transmission.py b/lib/transmission.py new file mode 100644 index 0000000000000000000000000000000000000000..9122ea442e48cb6d62957675ad476171324e4df1 --- /dev/null +++ b/lib/transmission.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- + +class Transmission(object): + + def __init__(self, id): + self.id = id + self.start = None + self.samples = None + self.plot = None + self.freq = None + self.first_one = None + self.last_one = None + self.transmission_time = None + self.real_transmission_time = None + self.modulation = None + + def print_transmission(self): + print("Transmission time: \t\t" + str(self.transmission_time) + "ms") + print("Real transmission time: \t" + str(self.real_transmission_time) + "ms") + print("Modulation: " + self.modulation + "\n") + print("Transmission block starts at sample: \t" + str(self.start)) + print("Transmission starts at sample: \t\t" + str(self.start + self.first_one)) + print("Sample count: \t\t\t\t" + str(self.samples)) + print("\n\n") diff --git a/scripts/data.yml b/scripts/data.yml new file mode 100644 index 0000000000000000000000000000000000000000..3b82dcc117345a7819097bd4f2a3f7bc2b768a74 --- /dev/null +++ b/scripts/data.yml @@ -0,0 +1,115 @@ +capture_file: data.iq +freq: 868270000 +samp_rate: 5000000.0 +sha256: null +signal_blocks: +- first_one: 4026 + freq: 868000000.0 + id: 1 + last_one: 28160 + plot: null + real_transmission_time: 4.83 + samples: 28590 + start: 13385866 + transmission_time: 1.91 +- first_one: 1859 + freq: 868000000.0 + id: 2 + last_one: 30453 + plot: null + real_transmission_time: 5.72 + samples: 32725 + start: 24515899 + transmission_time: 1.77 +- first_one: 3419 + freq: 868000000.0 + id: 3 + last_one: 23949 + plot: null + real_transmission_time: 4.11 + samples: 24453 + start: 38915799 + transmission_time: 1.97 +- first_one: 743 + freq: 868000000.0 + id: 4 + last_one: 24596 + plot: null + real_transmission_time: 4.77 + samples: 28587 + start: 50630406 + transmission_time: 1.78 +- first_one: 4001 + freq: 868000000.0 + id: 5 + last_one: 28432 + plot: null + real_transmission_time: 4.89 + samples: 28549 + start: 63316210 + transmission_time: 1.57 +- first_one: 2055 + freq: 868000000.0 + id: 6 + last_one: 22795 + plot: null + real_transmission_time: 4.15 + samples: 24453 + start: 78468872 + transmission_time: 1.89 +- first_one: 169 + freq: 868000000.0 + id: 7 + last_one: 20996 + plot: null + real_transmission_time: 4.17 + samples: 24453 + start: 93710928 + transmission_time: 1.8 +- first_one: 2735 + freq: 868000000.0 + id: 8 + last_one: 27870 + plot: null + real_transmission_time: 5.03 + samples: 28508 + start: 106024631 + transmission_time: 1.92 +- first_one: 2440 + freq: 868000000.0 + id: 9 + last_one: 22756 + plot: null + real_transmission_time: 4.06 + samples: 24535 + start: 119389249 + transmission_time: 1.74 +- first_one: 273 + freq: 868000000.0 + id: 10 + last_one: 24458 + plot: null + real_transmission_time: 4.84 + samples: 24576 + start: 127700627 + transmission_time: 1.82 +- first_one: 2124 + freq: 868000000.0 + id: 11 + last_one: 22307 + plot: null + real_transmission_time: 4.04 + samples: 24453 + start: 156758961 + transmission_time: 1.82 +- first_one: 1646 + freq: 868000000.0 + id: 12 + last_one: 21750 + plot: null + real_transmission_time: 4.02 + samples: 24576 + start: 162497183 + transmission_time: 1.89 +tag: my transmission dump +time: 1455742852 diff --git a/gr_grc/scripts/detect_noise_flore.py b/scripts/detect_noise_flore.py old mode 100644 new mode 100755 similarity index 80% rename from gr_grc/scripts/detect_noise_flore.py rename to scripts/detect_noise_flore.py index 8986851e1a797bfe161dc660ef0462244b1bc7af..87407f5ee410711d8fc3855464192537ac5ae4bd --- a/gr_grc/scripts/detect_noise_flore.py +++ b/scripts/detect_noise_flore.py @@ -4,10 +4,12 @@ import sys import numpy as np +import matplotlib.pyplot as plt from gnuradio import blocks from gnuradio import gr + class top_block(gr.top_block): def __init__(self, samp_rate=2e6, file_path=sys.argv[1], measure_time=sys.argv[2]): @@ -64,9 +66,7 @@ def main(top_block_cls=top_block, options=None): tb.start() samples_count = 0 - samples_average = np.empty(0, dtype='float32') - samples_median = np.empty(0, dtype='float32') - samples_std = np.empty(0, dtype='float32') + sample_blocks = [] minimum = 999999999.9 maximum = 0.0 @@ -79,9 +79,7 @@ def main(top_block_cls=top_block, options=None): # convert string with floats into an numpy array samples = np.fromstring(msg_string, dtype='float32') - samples_average = np.append(samples_average, np.average(samples)) - samples_median = np.append(samples_median, np.median(samples)) - samples_std = np.append(samples_std, np.std(samples)) + sample_blocks.append(samples) mi = np.amin(samples) ma = np.amax(samples) @@ -95,13 +93,29 @@ def main(top_block_cls=top_block, options=None): if samples_count >= int(sys.argv[2])*2e6: break - print("\nProcessed %s samples!\n" % (3*int(2e6))) + + new_samples_all = np.concatenate(sample_blocks) + print("\nProcessed %s samples!\n" % (int(sys.argv[2])*int(2e6))) print("min: %s " % minimum) print("max: %s \n" % maximum) - print("average: %s" % np.average(samples_average)) - print("median: %s" % np.median(samples_median)) - print("standard diviation: %s" % np.std(samples_std)) + print("average: %s" % np.average(new_samples_all)) + print("median: %s" % np.median(new_samples_all)) + print("standard diviation: %s" % np.std(new_samples_all)) + + max_2s = np.amax(new_samples_all[:2*2e6]) + + plt.plot(new_samples_all) + plt.plot([0,len(new_samples_all)-1], [max_2s*1.5, max_2s*1.5], \ + label="threshold " + str(round(max_2s, 6)), \ + linewidth=1.5, linestyle="-", color="red") + + plt.legend(loc='upper right') + + plt.xlabel("Samples") + plt.ylabel("Magnitude") + plt.savefig('show.png') + if __name__ == '__main__': main() \ No newline at end of file diff --git a/scripts/dump_to_signal_blocks.py b/scripts/dump_to_signal_blocks.py new file mode 100755 index 0000000000000000000000000000000000000000..54f60c9ae5b11e71c9d9a5776d6f81ab3cc569ec --- /dev/null +++ b/scripts/dump_to_signal_blocks.py @@ -0,0 +1,268 @@ +#!/usr/bin/env python2 +# -*- coding: utf-8 -*- + +import sys +import re + +import numpy as np + +from gnuradio import blocks +from gnuradio import gr + +class top_block(gr.top_block): + + def __init__(self, samp_rate=2.4e6, file_path=sys.argv[1]): + gr.top_block.__init__(self, "Top Block") + + ################################################## + # Variables + ################################################## + self.samp_rate = samp_rate + + # Queue + self.msgq_out = blocks_message_sink_0_msgq_out = gr.msg_queue(0) + + ################################################## + # Blocks + ################################################## + self.blocks_throttle_0 = blocks.throttle(gr.sizeof_gr_complex*1, \ + 10*samp_rate, \ + True) + self.threshold = float(sys.argv[2]) + + self.blocks_threshold_ff_0 = blocks.threshold_ff(self.threshold, self.threshold) + self.blocks_message_sink_0 = blocks.message_sink(gr.sizeof_float*1, \ + blocks_message_sink_0_msgq_out, \ + False) + self.blocks_file_source_0 = blocks.file_source(gr.sizeof_gr_complex*1, \ + str(file_path), \ + False) + self.blocks_complex_to_mag_squared_0 = blocks.complex_to_mag_squared(1) + + ################################################## + # Connections + ################################################## + # file_source → throttle → complex_to_max_squared → threshold → message_sink + self.connect((self.blocks_complex_to_mag_squared_0, 0), (self.blocks_threshold_ff_0, 0)) + self.connect((self.blocks_file_source_0, 0), (self.blocks_throttle_0, 0)) + self.connect((self.blocks_threshold_ff_0, 0), (self.blocks_message_sink_0, 0)) + self.connect((self.blocks_throttle_0, 0), (self.blocks_complex_to_mag_squared_0, 0)) + + def get_samp_rate(self): + return self.samp_rate + + def set_samp_rate(self, samp_rate): + self.samp_rate = samp_rate + self.blocks_throttle_0.set_sample_rate(self.samp_rate) + +def longes_row_of_ones(array): + row = 0 + last = 0 + longes_row = 0 + + for i in array: + if i == 1: + row += 1 + if row > longes_row: + longes_row = row + else: + row = 0 + + last = i + + return longes_row + +def preamble_detect(array): + """ + Block is a list with signal in it. + """ + block = "" + for i in array: + block += str(int(i)) + + transmission = {} + + start_match = re.search(r"([1]{15,25}[0]{15,25}){2}", block) + end_match = re.search(r"([1]{15,25}[0]{80,85})", block) + + telegram = "" + + if start_match: + for index, val in enumerate(block): + if index > start_match.start()-1 and index <= end_match.start(): + telegram += val + elif index > end_match.start() and index < end_match.end(): + if val == "1": + telegram += val + + + transmission['telegram'] = telegram + transmission['telegram_start'] = start_match.start() + else: + return None + + return transmission + +def preamble_detect_hm(array): + block = "" + for i in array: + block += str(int(i)) + + start_match = re.search(r"([0]{1}[1]{50})", block) + end_match = re.search(r"([1]{50}[0]{1})", block) + + transmission = {} + + if start_match is not None and end_match is not None: + telegram = "" + counter = 0 + array = [] + + start_telegram = start_match.start()+50 + + for index, val in enumerate(block): + if index > start_match.start()-1 and index < end_match.start()+1: + if val == "1": + telegram += val + elif index > end_match.start() and index < end_match.end(): + if val == "1": + telegram += val + + transmission['telegram'] = telegram + transmission['telegram_start'] = start_match.start()+1 # cause of the starting 0 pattern + transmission['type'] = "hm" + else: + return None + + return transmission + +def main(top_block_cls=top_block, options=None): + """ + What does this function do? + + 1. Run flowgraph and do energy based signal detection write results into + message queue. + 2. Read iq dump file and count samples. + 3. Start reading data from flowgraph message queue. + 4. Counting some data: + a) 1s and 0s + b) number of all samples + 5. If there are ones, save section into a array with hashes and merge depending + sections. + 6. Print results. + """ + # Section 1 + tb = top_block_cls() + tb.start() + + # Section 2 + data = np.memmap(open(sys.argv[1]), mode="r", dtype=np.complex64) + samples_in_file = len(data) + print("sum of all samples: %s\n" % samples_in_file) + + count_zero = 0 + count_one = 0 + samples_sum = 0 + + arrays_with_ones = [] + + # Section 3 + # just loop until all samples are processed + while True: + # pull from message queue + msg = tb.msgq_out.delete_head() + msg_string = msg.to_string() + + # convert string with floats into an numpy array + samples = np.fromstring(msg_string, dtype='float32') + # Section 4: do some counting + ones = np.count_nonzero(samples) + count_one += ones + count_zero += np.count_nonzero(samples != 1.0) + + + # Section 5 + non_zeros = np.count_nonzero(samples) + + # print(non_zeros) + # print("array with ones count: %s" % len(arrays_with_ones)) + if ones > 0 and non_zeros > 200: + # create first message queue hash + if len(arrays_with_ones) == 0: + hash = {} + hash['count_before_array'] = samples_sum + hash['samples'] = samples + hash['longes_row_of_ones'] = longes_row_of_ones(samples) + + arrays_with_ones.append(hash) + else: + # check if a message was splitted in queue + last_recorded_samples = arrays_with_ones[-1] + samples_len_last_recorded_samples = len(last_recorded_samples['samples']) + + # print("last_recorded_samples len: %s" % samples_len_last_recorded_samples) + if (last_recorded_samples['count_before_array'] + \ + samples_len_last_recorded_samples) == samples_sum: + tmp_array = [] + + for sample in samples: + tmp_array.append(sample) + + arrays_with_ones[-1]['samples'] = np.append(arrays_with_ones[-1]['samples'], tmp_array) + else: + hash = {} + hash['count_before_array'] = int(samples_sum) + hash['samples'] = samples + hash['longes_row_of_ones'] = longes_row_of_ones(samples) + arrays_with_ones.append(hash) + + + samples_sum += len(samples) + if samples_sum == samples_in_file: + break + + # Section 6 + print("%s of %s sample" % (samples_sum, samples_in_file)) + print("zero: %s" % count_zero) + print("one: %s" % count_one) + print("ones in time (1/2.4e6)*%s = %ss = %sms\n" % (count_one, 1/2.4e6*count_one, 1/2.4e6*count_one*1000)) + +# print("print sections with ones:") +# for hash in arrays_with_ones: +# string = "" +# print("Count: %s" % hash['count_before_array']) +# for items in hash['samples']: +# string += str(int(items)) +# +# print("%s\n" % string) +# +# print("\nSignal sections:\n") +# for i, hash in enumerate(arrays_with_ones): +# longes_row = longes_row_of_ones(hash['samples']) +# samples_count = len(hash['samples']) +# section_length_in_ms = 1/2.4e6*samples_count*1000 +# +# print("start: %s end: %s time: %sms, longes row of ones: %s" % (hash['count_before_array'], \ +# samples_count+hash['count_before_array'], \ +# section_length_in_ms, longes_row)) + + for i, block in enumerate(arrays_with_ones): + telegram = preamble_detect_hm(block['samples']) + if telegram is None: + telegram = preamble_detect(block['samples']) + + if telegram is not None: + block['telegram'] = telegram + telegram_length = len(block['telegram']['telegram']) + print("signal: %s time: %sms type: %s" % (telegram_length, + round(telegram_length*(1/2.4e6)*1000,2), + block['telegram']['type'])) + + + +if __name__ == '__main__': + if len(sys.argv) == 1 and len(sys.argv) > 3: + print("Usage: " + sys.argv[0] + " dump_file threshold\n") + sys.exit(1) + else: + main() diff --git a/scripts/jamming_signal_868.3.iq b/scripts/jamming_signal_868.3.iq new file mode 100644 index 0000000000000000000000000000000000000000..ecedb1d7528d2ddcb9bb71348a01a6136ef2163d Binary files /dev/null and b/scripts/jamming_signal_868.3.iq differ diff --git a/gr_grc/scripts/knx_replay_szenario.py b/scripts/knx_replay_szenario.py old mode 100755 new mode 100644 similarity index 100% rename from gr_grc/scripts/knx_replay_szenario.py rename to scripts/knx_replay_szenario.py diff --git a/gr_grc/scripts/plot_data.py b/scripts/plot_yaml_data.py similarity index 100% rename from gr_grc/scripts/plot_data.py rename to scripts/plot_yaml_data.py diff --git a/gr_grc/scripts/show_live_transmissions.py b/scripts/show_live_transmissions.py similarity index 93% rename from gr_grc/scripts/show_live_transmissions.py rename to scripts/show_live_transmissions.py index cfef9782cbfcd0227ba68585ee19d989b15a7dcd..6b735a5c533dbc45ca62d0e438cba1a7e96adbc2 100755 --- a/gr_grc/scripts/show_live_transmissions.py +++ b/scripts/show_live_transmissions.py @@ -31,7 +31,7 @@ class top_block(gr.top_block): ################################################## self.cutoff_freq = cutoff_freq = 3e5 self.transition_width = transition_width = cutoff_freq/2 - self.samp_rate = samp_rate = 2.7e6 + self.samp_rate = samp_rate = 2.4e6 self.freq = freq = 868e6 self.center_freq = 3e5 @@ -61,7 +61,10 @@ class top_block(gr.top_block): str(sys.argv[2]), False) self.blocks_file_sink_0.set_unbuffered(False) - self.freq_xlating_fir_filter_xxx_0 = filter.freq_xlating_fir_filter_ccc(1, (firdes.low_pass(1, samp_rate, transition_width, cutoff_freq, firdes.WIN_HAMMING, 6.76)), 3e5, samp_rate) + self.freq_xlating_fir_filter_xxx_0 = filter. \ + freq_xlating_fir_filter_ccc(1, + (firdes.low_pass(1, samp_rate, transition_width, cutoff_freq, firdes.WIN_HAMMING, 6.76)), + 3e5, samp_rate) self.blocks_threshold_ff_0 = blocks.threshold_ff(0.00686, 0.00686, 0) self.blocks_message_sink_0 = blocks.message_sink(gr.sizeof_float*1, blocks_message_sink_0_msgq_out, False) self.blocks_complex_to_mag_squared_0 = blocks.complex_to_mag_squared(1) @@ -143,7 +146,7 @@ def main(top_block_cls=top_block, options=None): samples_len = len(samples) # skip samples with only zeros - if np.count_nonzero(samples) != 0: + if np.count_nonzero(samples) != 0 or time_added != 0: # convert array to string string = "" for i in samples: @@ -153,15 +156,17 @@ def main(top_block_cls=top_block, options=None): block_samples_start = samples_count messages.append(string) - time_added = time.time() + + if time_added == 0: + time_added = time.time() # output transmission block after 500ms - if time_added != 0 and (time.time()-time_added) > 0.5 : + if time_added != 0 and (time.time()-time_added) > 1: # join message blocks msg = "".join(messages) # do some calculations transmission_time = round(1/tb.samp_rate*(int(msg.count("1"))*1000), 2) - first_one = msg.index("1") + first_one = msg.find("1") last_one = msg.rfind("1") real_transmission_time = round(1/tb.samp_rate*(int(last_one-first_one)*1000), 2) transmission_counter += 1 diff --git a/gr_grc/scripts/split_file.py b/scripts/split_file.py similarity index 100% rename from gr_grc/scripts/split_file.py rename to scripts/split_file.py diff --git a/gr_grc/scripts/yaml_to_table.py b/scripts/yaml_to_table.py old mode 100755 new mode 100644 similarity index 59% rename from gr_grc/scripts/yaml_to_table.py rename to scripts/yaml_to_table.py index 7e5964b4499d76e6f47d0b9f49e57b63f7ba99ef..5a20d7ac5597ad2c35721d7954d2fdde7324976e --- a/gr_grc/scripts/yaml_to_table.py +++ b/scripts/yaml_to_table.py @@ -29,16 +29,17 @@ with open(sys.argv[1], 'r') as stream: real_transmission_time = [] transmission_time = [] - for i, var in enumerate(data['signal_blocks']): # add values to array for later processing real_transmission_time.append(var['real_transmission_time']) transmission_time.append(var['transmission_time']) -print("%s & %s\,ms \\newline %s\,ms & %s\,ms \\newline %s\,ms & %s\,ms \\newline %s\,ms" % (data['tag'], - round(np.amin(real_transmission_time),2), - round(np.amin(transmission_time),2), - round(np.amax(real_transmission_time),2), - round(np.amax(transmission_time),2), - round(np.mean(real_transmission_time),2), - round(np.mean(transmission_time),2))) +print("%s & %s\,ms \\newline %s\,ms & " \ + "%s\,ms \\newline %s\,ms & " \ + "%s\,ms \\newline %s\,ms" % (data['tag'], + round(np.amin(real_transmission_time),2), + round(np.amin(transmission_time),2), + round(np.amax(real_transmission_time),2), + round(np.amax(transmission_time),2), + round(np.mean(real_transmission_time),2), + round(np.mean(transmission_time),2))) diff --git a/tests/lib/test_capture_file.py b/tests/lib/test_capture_file.py new file mode 100644 index 0000000000000000000000000000000000000000..fa301b5985d22a7deb14e17e0ade17d76f64a65c --- /dev/null +++ b/tests/lib/test_capture_file.py @@ -0,0 +1,25 @@ +# -*- encoding: utf-8 -*- + +import pytest +import os +import time + +from os.path import expanduser, exists + +from lib.capture_file import CaptureFile + +class TestCaptureFile: + + def test_constructor(self): + cf = CaptureFile("/etc/passwd", time.time(), 868e6, 2.4e6, + "my tag") + + assert cf.freq == 868e6 + assert cf.tag == "my tag" + + def test_md5sum(self): + cf = CaptureFile("/etc/passwd", time.time(), 868e6, 2.4e6, + "my tag") + md5sum = "7c95ccf7bb881767c7f92350afb09c40" + + assert cf.md5sum() == md5sum diff --git a/tests/lib/test_disk.py b/tests/lib/test_disk.py index e693cd79457f532705f4a688006f51435067de2b..123b3b3d8de2a4d526ca1eec3cff249b8540544c 100644 --- a/tests/lib/test_disk.py +++ b/tests/lib/test_disk.py @@ -49,7 +49,8 @@ class TestDisk: assert Disk.create_new_su_id(1337) == "01337" def test_create_capture_folder(self): - new_path = Disk.create_capture_folder("/home/meise/tmp/", "2.4e6", - "868e6", "HomeMatic test 1") + new_path = Disk.create_capture_folder("/home/meise/tmp/", 2.4e6, + 868e6, "HomeMatic test 1") - assert new_path == "/home/meise/tmp/00002-868e6-2.4e6-HomeMatic_test_1" + assert new_path == "/home/meise/tmp/00010-868000000MHz-2400000MHz-HomeMatic_test_1" + os.rmdir(new_path)