From 553898f61b8f2f62cec81a94ded8a1f2bc0f53ea Mon Sep 17 00:00:00 2001 From: Manolis Surligas Date: Sun, 9 Dec 2018 00:57:15 +0200 Subject: [PATCH 01/24] Improve CW decoding * Introduce the hysteresis option, in order the CW demodulator to adjust properly the plateau length based on the WPM and any filtering that can be used before * Instead for a frame per word, now the CW decoder waits for 10 long spaces before it commits a frame. With this way many words are placed on the same frame telemetry decoding is easier --- grc/satnogs_cw_to_symbol.xml | 95 +++--- include/satnogs/cw_to_symbol.h | 14 +- include/satnogs/morse.h | 7 +- lib/cw_to_symbol_impl.cc | 572 +++++++++++++++++---------------- lib/cw_to_symbol_impl.h | 3 +- lib/morse_decoder_impl.cc | 165 +++++----- lib/morse_decoder_impl.h | 29 +- 7 files changed, 466 insertions(+), 419 deletions(-) diff --git a/grc/satnogs_cw_to_symbol.xml b/grc/satnogs_cw_to_symbol.xml index 984c241..89ea992 100644 --- a/grc/satnogs_cw_to_symbol.xml +++ b/grc/satnogs_cw_to_symbol.xml @@ -1,51 +1,58 @@ - CW to Symbols - satnogs_cw_to_symbol - import satnogs - satnogs.cw_to_symbol($sampling_rate, $threshold, $conf_level, $wpm) - set_act_threshold($threshold) - - - Sampling Rate - sampling_rate - samp_rate - real - + CW to Symbols + satnogs_cw_to_symbol + import satnogs + satnogs.cw_to_symbol($sampling_rate, $threshold, $conf_level, $wpm, $hysteresis) + set_act_threshold($threshold) - - Activation Threshold - threshold - real - - - - Confidence Level - conf_level - 0.9 - real - + + Sampling Rate + sampling_rate + samp_rate + real + - - Words per Minute - wpm - 20 - int - + + Activation Threshold + threshold + real + - - act_threshold - message - 1 - - - - in - float - + + Confidence Level + conf_level + 0.9 + real + - - out - message - + + Words per Minute + wpm + 20 + int + + + + Hysteresis + hysteresis + 0 + int + + + + act_threshold + message + 1 + + + + in + float + + + + out + message + diff --git a/include/satnogs/cw_to_symbol.h b/include/satnogs/cw_to_symbol.h index acf5aef..6a05bbf 100644 --- a/include/satnogs/cw_to_symbol.h +++ b/include/satnogs/cw_to_symbol.h @@ -24,6 +24,9 @@ #include #include +#define MIN_WPM 5 +#define MAX_WPM 50 + namespace gr { namespace satnogs @@ -65,10 +68,19 @@ namespace gr * symbols * * @param wpm Morse code Words per Minute + * + * @param hysteresis this value represents the hysteresis of a possible + * filter used before the CW to Symbol block. For example if there is + * a moving average filter with x taps, the full power of the signal + * will be available after x samples. The total length of samples with + * maximum power will be 2*x less. Because the block searches for plateaus + * with proper durations, this filtering hysteresis should be known. + * If no such a filter is used, the hysteresis value should be set to zero. */ static cw_to_symbol::sptr make (double sampling_rate, float threshold, float conf_level = 0.9, - size_t wpm = 20); + size_t wpm = 20, + size_t hysteresis = 0); virtual void set_act_threshold (float thrld) = 0; diff --git a/include/satnogs/morse.h b/include/satnogs/morse.h index af643b5..b7e96cf 100644 --- a/include/satnogs/morse.h +++ b/include/satnogs/morse.h @@ -2,7 +2,7 @@ /* * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module * - * Copyright (C) 2016,2017 + * Copyright (C) 2016-2018 * Libre Space Foundation * * This program is free software: you can redistribute it and/or modify @@ -22,8 +22,6 @@ #ifndef INCLUDE_SATNOGS_MORSE_H_ #define INCLUDE_SATNOGS_MORSE_H_ -#define MIN_WPM 5 -#define MAX_WPM 30 /** * The different Morse symbols */ @@ -32,7 +30,8 @@ typedef enum { MORSE_DASH, //!< Morse dash (-) symbol MORSE_INTRA_SPACE, //!< Space between dot and dash symbols MORSE_S_SPACE, //!< Morse short space between characters - MORSE_L_SPACE //! #include #if BOOST_VERSION >= 106500 - #include +#include #else - #include +#include #endif #include namespace gr { - namespace satnogs - { +namespace satnogs +{ - cw_to_symbol::sptr - cw_to_symbol::make (double sampling_rate, float threshold, float conf_level, - size_t wpm) - { - return gnuradio::get_initial_sptr ( - new cw_to_symbol_impl (sampling_rate, threshold, conf_level, wpm)); - } +cw_to_symbol::sptr +cw_to_symbol::make (double sampling_rate, float threshold, float conf_level, + size_t wpm, size_t hysteresis) +{ + return gnuradio::get_initial_sptr ( + new cw_to_symbol_impl (sampling_rate, threshold, conf_level, wpm, + hysteresis)); +} - /* - * The private constructor - */ - cw_to_symbol_impl::cw_to_symbol_impl (double sampling_rate, float threshold, - float conf_level, size_t wpm) : - gr::sync_block ("cw_to_symbol", - gr::io_signature::make (1, 1, sizeof(float)), - gr::io_signature::make (0, 0, 0)), - d_sampling_rate (sampling_rate), - d_act_thrshld (threshold), - d_confidence_level (conf_level), - d_dot_samples ((1.2 / wpm) * sampling_rate), - d_window_size(0), - d_window_cnt(0), - d_dot_windows_num(0), - d_dec_state (NO_SYNC), - d_prev_space_symbol (true) - { - if (wpm < MIN_WPM) { - throw std::invalid_argument ( - "Decoder can not handle such low WPM setting"); - } +/* + * The private constructor + */ +cw_to_symbol_impl::cw_to_symbol_impl (double sampling_rate, float threshold, + float conf_level, size_t wpm, + size_t hysteresis) : + gr::sync_block ("cw_to_symbol", + gr::io_signature::make (1, 1, sizeof(float)), + gr::io_signature::make (0, 0, 0)), + d_sampling_rate (sampling_rate), + d_act_thrshld (threshold), + d_confidence_level (conf_level), + d_dot_samples ((1.2 / wpm) * sampling_rate), + d_window_size (0), + d_window_cnt (0), + d_idle_cnt (0), + d_dot_windows_num (0), + d_dec_state (NO_SYNC), + d_prev_space_symbol (true) +{ + if (wpm < MIN_WPM) { + throw std::invalid_argument ("Decoder can not handle such low WPM setting"); + } - if (wpm > MAX_WPM) { - throw std::invalid_argument ( - "Decoder can not handle such high WPM setting"); - } + if (wpm > MAX_WPM) { + throw std::invalid_argument ( + "Decoder can not handle such high WPM setting"); + } - if (conf_level > 1.0 || conf_level < 0.5) { - throw std::invalid_argument ( - "Confidence level should be in the range [0.5, 1.0]"); - } + if (conf_level > 1.0 || conf_level < 0.5) { + throw std::invalid_argument ( + "Confidence level should be in the range [0.5, 1.0]"); + } - message_port_register_in (pmt::mp ("act_threshold")); - message_port_register_out (pmt::mp ("out")); + if(hysteresis > d_dot_samples / 4) { + throw std::invalid_argument ("Too large hysteresis value"); + } - /* Register the message handlers */ - set_msg_handler ( - pmt::mp ("act_threshold"), - boost::bind (&cw_to_symbol_impl::set_act_threshold_msg_handler, this, - _1)); + message_port_register_in (pmt::mp ("act_threshold")); + message_port_register_out (pmt::mp ("out")); - /* - * Try to split the CW pulses in smaller windows for detecting faster - * a false alarm. As we use the window size for setting the history - * it should have a reasonably size. - */ - size_t i = 1; - d_window_size = d_dot_samples / i; - while(d_window_size > 64) { - i++; - d_window_size = d_dot_samples / i; - } + /* Register the message handlers */ + set_msg_handler ( + pmt::mp ("act_threshold"), + boost::bind (&cw_to_symbol_impl::set_act_threshold_msg_handler, this, + _1)); - /* NOTE: The dot duration should be a perfect multiple of the window */ - while(d_dot_samples % d_window_size != 0) { - d_window_size++; - } + /* + * Reconsider the dot oulse duration based on the confidence level + * and hysteresis + */ + d_dot_samples = d_dot_samples - 2 * (hysteresis * conf_level); - LOG_WARN("Dot symbol samples: %lu", d_dot_samples); - LOG_WARN("Window size: %lu", d_window_size); - /* Set the duration of each symbol in multiples of the window size */ - d_dot_windows_num = d_dot_samples / d_window_size; - d_dash_windows_num = 3 * d_dot_windows_num; - d_short_pause_windows_num = d_dash_windows_num; - d_long_pause_windows_num = 7 * d_dot_windows_num; + /* + * Try to split the CW pulses in smaller windows for detecting faster + * a false alarm. As we use the window size for setting the history + * it should have a reasonably size. + */ + size_t i = 1; + d_window_size = d_dot_samples / i; + while (d_window_size > 64) { + i++; + d_window_size = d_dot_samples / i; + } - const int alignment_multiple = volk_get_alignment () - / (d_window_size * sizeof(float)); - set_alignment (std::max (1, alignment_multiple)); + /* NOTE: The dot duration should be a perfect multiple of the window */ + while (d_dot_samples % d_window_size != 0) { + d_window_size++; + } - d_const_val = (float *) volk_malloc(d_window_size * sizeof(float), - volk_get_alignment ()); - d_tmp = (float *) volk_malloc(d_window_size * sizeof(float), - volk_get_alignment ()); - d_out = (int32_t *) volk_malloc (d_window_size * sizeof(int32_t), + LOG_DEBUG("Dot symbol samples: %lu", d_dot_samples); + LOG_DEBUG("Window size: %lu", d_window_size); + + /* Set the duration of each symbol in multiples of the window size */ + d_dot_windows_num = d_dot_samples / d_window_size; + d_dash_windows_num = 3 * d_dot_windows_num; + d_short_pause_windows_num = d_dash_windows_num; + d_long_pause_windows_num = 7 * d_dot_windows_num; + + const int alignment_multiple = volk_get_alignment () + / (d_window_size * sizeof(float)); + set_alignment (std::max (1, alignment_multiple)); + + d_const_val = (float *) volk_malloc (d_window_size * sizeof(float), volk_get_alignment ()); + d_tmp = (float *) volk_malloc (d_window_size * sizeof(float), + volk_get_alignment ()); + d_out = (int32_t *) volk_malloc (d_window_size * sizeof(int32_t), + volk_get_alignment ()); - if(!d_const_val || !d_tmp || !d_out) { - throw std::runtime_error("cw_to_symbol: Could not allocate memory"); - } + if (!d_const_val || !d_tmp || !d_out) { + throw std::runtime_error ("cw_to_symbol: Could not allocate memory"); + } - for(i = 0; i < d_window_size; i++) { - d_const_val[i] = threshold; - } - set_history(d_window_size); - } + for (i = 0; i < d_window_size; i++) { + d_const_val[i] = threshold; + } + set_history (d_window_size); +} - inline void - cw_to_symbol_impl::send_symbol_msg (morse_symbol_t s) - { - if(s == MORSE_S_SPACE || s == MORSE_L_SPACE) { - d_prev_space_symbol = true; - } - else{ - d_prev_space_symbol = false; - } - message_port_pub (pmt::mp ("out"), pmt::from_long (s)); - } +inline void +cw_to_symbol_impl::send_symbol_msg (morse_symbol_t s) +{ + if (s == MORSE_S_SPACE || s == MORSE_L_SPACE) { + d_prev_space_symbol = true; + } + else { + d_prev_space_symbol = false; + } + message_port_pub (pmt::mp ("out"), pmt::from_long (s)); +} - inline bool - cw_to_symbol_impl::check_conf_level(size_t cnt, size_t target) - { - return ((float)cnt > target * d_confidence_level); - } +inline bool +cw_to_symbol_impl::check_conf_level (size_t cnt, size_t target) +{ + return ((float) cnt > target * d_confidence_level); +} - /* - * Our virtual destructor. - */ - cw_to_symbol_impl::~cw_to_symbol_impl () - { - volk_free (d_const_val); - volk_free (d_tmp); - volk_free (d_out); - } +/* + * Our virtual destructor. + */ +cw_to_symbol_impl::~cw_to_symbol_impl () +{ + volk_free (d_const_val); + volk_free (d_tmp); + volk_free (d_out); +} - inline void - cw_to_symbol_impl::set_idle () - { - d_dec_state = NO_SYNC; - d_window_cnt = 0; - } +inline void +cw_to_symbol_impl::set_idle () +{ + d_dec_state = NO_SYNC; + d_window_cnt = 0; + d_idle_cnt = 0; +} - inline void - cw_to_symbol_impl::set_short_on () - { - d_dec_state = SEARCH_DOT; - d_window_cnt = 1; - } +inline void +cw_to_symbol_impl::set_short_on () +{ + d_dec_state = SEARCH_DOT; + d_window_cnt = 1; +} - inline void - cw_to_symbol_impl::set_long_on () - { - d_dec_state = SEARCH_DASH; - } +inline void +cw_to_symbol_impl::set_long_on () +{ + d_dec_state = SEARCH_DASH; +} - inline void - cw_to_symbol_impl::set_search_space () - { - d_dec_state = SEARCH_SPACE; - d_window_cnt = 1; - } +inline void +cw_to_symbol_impl::set_search_space () +{ + d_dec_state = SEARCH_SPACE; + d_window_cnt = 1; +} - void - cw_to_symbol_impl::set_act_threshold_msg_handler (pmt::pmt_t msg) - { - if (pmt::is_pair (msg)) { - set_act_threshold (pmt::to_double (pmt::cdr (msg))); +void +cw_to_symbol_impl::set_act_threshold_msg_handler (pmt::pmt_t msg) +{ + if (pmt::is_pair (msg)) { + set_act_threshold (pmt::to_double (pmt::cdr (msg))); + } +} + +int +cw_to_symbol_impl::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + bool triggered; + size_t i; + const float *in_old = (const float *) input_items[0]; + const float *in = in_old + history () - 1; + + if (noutput_items < 0) { + return noutput_items; + } + + /* During idle state search for a possible trigger */ + if (d_dec_state == NO_SYNC) { + for (i = 0; i < (size_t) noutput_items; i++) { + /* + * Clamp the input so the window mean is not affected by strong spikes + * Good luck understanding this black magic shit! + */ + triggered = is_triggered (in_old + i, d_window_size); + if (triggered) { + LOG_DEBUG("Triggered!"); + set_short_on (); + return i + 1; } } + d_idle_cnt += noutput_items / d_window_size; + if(d_idle_cnt > 10 * d_long_pause_windows_num) { + send_symbol_msg (MORSE_END_MSG_SPACE); + d_idle_cnt = 0; + } + return noutput_items; + } - int - cw_to_symbol_impl::work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { - bool triggered; - size_t i; - const float *in_old = (const float *) input_items[0]; - const float *in = in_old + history() - 1; - - if(noutput_items < 0) { - return noutput_items; - } - - /* During idle state search for a possible trigger */ - if(d_dec_state == NO_SYNC) { - for(i = 0; i < (size_t)noutput_items; i++) { - /* - * Clamp the input so the window mean is not affected by strong spikes - * Good luck understanding this black magic shit! - */ - triggered = is_triggered(in_old + i, d_window_size); - if(triggered) { - LOG_DEBUG("Triggered!"); - set_short_on(); - return i+1; + /* From now one, we handle the input in multiples of a window */ + for (i = 0; i < (size_t) noutput_items / d_window_size; i++) { + triggered = is_triggered (in + i * d_window_size, d_window_size); + switch (d_dec_state) + { + case SEARCH_DOT: + if (triggered) { + d_window_cnt++; + if (d_window_cnt > d_dot_windows_num) { + set_long_on (); + LOG_DEBUG("Going to search for long sequence"); } } - return noutput_items; - } - - /* From now one, we handle the input in multiples of a window */ - for (i = 0; i < (size_t)noutput_items / d_window_size; i++) { - triggered = is_triggered(in + i * d_window_size, d_window_size); - switch(d_dec_state) { - case SEARCH_DOT: - if(triggered) { - d_window_cnt++; - if(d_window_cnt > d_dot_windows_num) { - set_long_on(); - LOG_DEBUG("Going to search for long sequence"); - } - } - else { - if(check_conf_level(d_window_cnt, d_dot_windows_num)) { - LOG_DEBUG("DOT"); - send_symbol_msg(MORSE_DOT); - } - LOG_DEBUG("Going to search for space: win cnt %lu", d_window_cnt); - set_search_space (); - } - break; - case SEARCH_DASH: - if(triggered) { - d_window_cnt++; - } - else{ - if(check_conf_level(d_window_cnt, d_dash_windows_num)) { - LOG_DEBUG("DASH"); - send_symbol_msg(MORSE_DASH); - } - else{ - LOG_DEBUG("DOT"); - send_symbol_msg(MORSE_DOT); - } - set_search_space (); - LOG_DEBUG("Going to search for space"); - } - break; - case SEARCH_SPACE: - if (triggered) { - if(check_conf_level(d_window_cnt, d_long_pause_windows_num)) { - LOG_DEBUG("LONG SPACE"); - send_symbol_msg(MORSE_L_SPACE); - } - else if(check_conf_level(d_window_cnt, d_short_pause_windows_num)){ - LOG_DEBUG("SHORT SPACE"); - send_symbol_msg(MORSE_S_SPACE); - } - set_short_on(); - LOG_DEBUG("Going to search for dot"); - } - else{ - d_window_cnt++; - if(d_window_cnt > d_long_pause_windows_num) { - LOG_DEBUG("LONG SPACE"); - send_symbol_msg(MORSE_L_SPACE); - set_idle(); - LOG_DEBUG("Going to idle"); - return (i + 1) * d_window_size; - } - } - break; - default: - LOG_ERROR("Invalid decoder state"); + else { + if (check_conf_level (d_window_cnt, d_dot_windows_num)) { + LOG_DEBUG("DOT"); + send_symbol_msg (MORSE_DOT); + } + LOG_DEBUG("Going to search for space: win cnt %lu", d_window_cnt); + set_search_space (); } + break; + case SEARCH_DASH: + if (triggered) { + d_window_cnt++; + } + else { + if (check_conf_level (d_window_cnt, d_dash_windows_num)) { + LOG_DEBUG("DASH"); + send_symbol_msg (MORSE_DASH); + } + else { + LOG_DEBUG("DOT"); + send_symbol_msg (MORSE_DOT); + } + set_search_space (); + LOG_DEBUG("Going to search for space"); + } + break; + case SEARCH_SPACE: + if (triggered) { + if (check_conf_level (d_window_cnt, d_long_pause_windows_num)) { + LOG_DEBUG("LONG SPACE"); + send_symbol_msg (MORSE_L_SPACE); + } + else if (check_conf_level (d_window_cnt, d_short_pause_windows_num)) { + LOG_DEBUG("SHORT SPACE"); + send_symbol_msg (MORSE_S_SPACE); + } + set_short_on (); + LOG_DEBUG("Going to search for dot"); + } + else { + d_window_cnt++; + if (d_window_cnt > d_long_pause_windows_num) { + LOG_DEBUG("LONG SPACE"); + send_symbol_msg (MORSE_L_SPACE); + set_idle (); + LOG_DEBUG("Going to idle"); + return (i + 1) * d_window_size; + } + } + break; + default: + LOG_ERROR("Invalid decoder state"); } - return i * d_window_size; - } + } + return i * d_window_size; +} - /** - * Sets a new activation threshold. - * @param thrhld the new threshold. - */ - void - cw_to_symbol_impl::set_act_threshold (float thrhld) - { - d_act_thrshld = thrhld; - } +/** + * Sets a new activation threshold. + * @param thrhld the new threshold. + */ +void +cw_to_symbol_impl::set_act_threshold (float thrhld) +{ + d_act_thrshld = thrhld; +} - /** - * Clamps the input and performs at the same time binary slicing. - * With this way, a decision based on moving average is not affected - * by strong peaks. - * @param out the output buffer with the binary sliced output - * @param in the input signal - * @param len number of samples to process - */ - inline void - cw_to_symbol_impl::clamp_input (int32_t* out, const float* in, size_t len) - { - volk_32f_x2_subtract_32f(d_tmp, in, d_const_val, len); - volk_32f_binary_slicer_32i(d_out, d_tmp, len); - } +/** + * Clamps the input and performs at the same time binary slicing. + * With this way, a decision based on moving average is not affected + * by strong peaks. + * @param out the output buffer with the binary sliced output + * @param in the input signal + * @param len number of samples to process + */ +inline void +cw_to_symbol_impl::clamp_input (int32_t* out, const float* in, size_t len) +{ + volk_32f_x2_subtract_32f (d_tmp, in, d_const_val, len); + volk_32f_binary_slicer_32i (d_out, d_tmp, len); +} - static inline int32_t - hadd (const int32_t* in, size_t len) - { - size_t i; - int32_t cnt = 0; - for(i = 0; i < len; i++) { - cnt += in[i]; - } - return cnt; - } +static inline int32_t +hadd (const int32_t* in, size_t len) +{ + size_t i; + int32_t cnt = 0; + for (i = 0; i < len; i++) { + cnt += in[i]; + } + return cnt; +} - inline bool - cw_to_symbol_impl::is_triggered (const float* in, size_t len) - { - int32_t cnt; - clamp_input(d_out, in, len); - cnt = hadd(d_out, len); - return (cnt >= (int32_t)(d_window_size * d_confidence_level)) ? true : false; - } +inline bool +cw_to_symbol_impl::is_triggered (const float* in, size_t len) +{ + int32_t cnt; + clamp_input (d_out, in, len); + cnt = hadd (d_out, len); + return (cnt >= (int32_t) (d_window_size * d_confidence_level)) ? true : false; +} - } /* namespace satnogs */ +} /* namespace satnogs */ } /* namespace gr */ diff --git a/lib/cw_to_symbol_impl.h b/lib/cw_to_symbol_impl.h index 59fa4ed..e2fd13b 100644 --- a/lib/cw_to_symbol_impl.h +++ b/lib/cw_to_symbol_impl.h @@ -45,6 +45,7 @@ namespace gr size_t d_dot_samples; size_t d_window_size; size_t d_window_cnt; + size_t d_idle_cnt; size_t d_dot_windows_num; size_t d_dash_windows_num; size_t d_short_pause_windows_num; @@ -84,7 +85,7 @@ namespace gr public: cw_to_symbol_impl (double sampling_rate, float threshold, - float conf_level, size_t wpm); + float conf_level, size_t wpm, size_t hysteresis); ~cw_to_symbol_impl (); // Where all the action really happens diff --git a/lib/morse_decoder_impl.cc b/lib/morse_decoder_impl.cc index c86fb36..e54ddf8 100644 --- a/lib/morse_decoder_impl.cc +++ b/lib/morse_decoder_impl.cc @@ -28,94 +28,99 @@ #include namespace gr { - namespace satnogs - { +namespace satnogs +{ - morse_decoder::sptr - morse_decoder::make (char unrecognized_char, size_t min_frame_len) +morse_decoder::sptr +morse_decoder::make (char unrecognized_char, size_t min_frame_len) +{ + return gnuradio::get_initial_sptr ( + new morse_decoder_impl (unrecognized_char, min_frame_len)); +} + +void +morse_decoder_impl::symbol_msg_handler (pmt::pmt_t msg) +{ + bool res = false; + morse_symbol_t s; + s = (morse_symbol_t) pmt::to_long (msg); + + switch (s) { - return gnuradio::get_initial_sptr ( - new morse_decoder_impl (unrecognized_char, min_frame_len)); - } - - void - morse_decoder_impl::symbol_msg_handler (pmt::pmt_t msg) - { - bool res = false; - std::string str; - morse_symbol_t s; - s = (morse_symbol_t) pmt::to_long (msg); - - switch (s) - { - case MORSE_DOT: - case MORSE_DASH: - case MORSE_S_SPACE: - res = d_morse_tree.received_symbol (s); - break; - /* - * If a word separator occurs it is a good time to retrieve the decoded - * word - */ - case MORSE_L_SPACE: - /* - * Inject a character separator, for the morse decoder to commit - * the outstanding character - */ - res = d_morse_tree.received_symbol (MORSE_S_SPACE); - /* Just ignore the word separator if no word is yet decoded */ - if (d_morse_tree.get_word_len () == 0) { - res = true; - break; - } - str = d_morse_tree.get_word (); - if (str.length () > d_min_frame_len) { - d_morse_tree.reset (); - message_port_pub (pmt::mp ("out"), - pmt::make_blob (str.c_str (), str.length ())); - } - break; - case MORSE_INTRA_SPACE: - /*Ignore it */ - break; - default: - LOG_ERROR("Unknown Morse symbol"); - return; - } - + case MORSE_DOT: + case MORSE_DASH: + case MORSE_S_SPACE: + res = d_morse_tree.received_symbol (s); + break; /* - * If the decoding return false, it means that either an non decode-able - * character situation occurred or the maximum word limit reached + * If a word separator occurs it is a good time to retrieve the decoded + * word */ - if (!res) { - if (d_morse_tree.get_max_word_len () == d_morse_tree.get_word_len ()) { - str = d_morse_tree.get_word (); - d_morse_tree.reset (); - message_port_pub (pmt::mp ("out"), - pmt::make_blob (str.c_str (), str.length ())); - } + case MORSE_L_SPACE: + /* + * Inject a character separator, for the morse decoder to commit + * the outstanding character + */ + res = d_morse_tree.received_symbol (MORSE_S_SPACE); + /* Just ignore the word separator if no word is yet decoded */ + if (d_morse_tree.get_word_len () == 0) { + res = true; + break; } + d_str = d_str.append(d_morse_tree.get_word ()); + d_str = d_str.append(" "); + d_morse_tree.reset (); + break; + case MORSE_INTRA_SPACE: + /*Ignore it */ + break; + case MORSE_END_MSG_SPACE: + if (d_str.length () > d_min_frame_len) { + d_morse_tree.reset (); + message_port_pub (pmt::mp ("out"), + pmt::make_blob (d_str.c_str (), d_str.length ())); + d_str = ""; + } + break; + default: + LOG_ERROR("Unknown Morse symbol"); + return; } - /* - * The private constructor - */ - morse_decoder_impl::morse_decoder_impl (char unrecognized_char, - size_t min_frame_len) : - gr::block ("morse_decoder", gr::io_signature::make (0, 0, 0), - gr::io_signature::make (0, 0, 0)), - d_morse_tree (unrecognized_char), - d_min_frame_len (min_frame_len) - - { - /* Register the input and output msg handler */ - message_port_register_in (pmt::mp ("in")); - message_port_register_out (pmt::mp ("out")); - set_msg_handler ( - pmt::mp ("in"), - boost::bind (&morse_decoder_impl::symbol_msg_handler, this, _1)); + /* + * If the decoding return false, it means that either an non decode-able + * character situation occurred or the maximum word limit reached + */ + if (!res) { + if (d_morse_tree.get_max_word_len () == d_morse_tree.get_word_len ()) { + d_str = d_morse_tree.get_word (); + d_morse_tree.reset (); + message_port_pub (pmt::mp ("out"), + pmt::make_blob (d_str.c_str (), d_str.length ())); } + } +} - } /* namespace satnogs */ +/* + * The private constructor + */ +morse_decoder_impl::morse_decoder_impl (char unrecognized_char, + size_t min_frame_len) : + gr::block ("morse_decoder", gr::io_signature::make (0, 0, 0), + gr::io_signature::make (0, 0, 0)), + d_morse_tree (unrecognized_char), + d_min_frame_len (min_frame_len), + d_str("") + +{ + /* Register the input and output msg handler */ + message_port_register_in (pmt::mp ("in")); + message_port_register_out (pmt::mp ("out")); + set_msg_handler ( + pmt::mp ("in"), + boost::bind (&morse_decoder_impl::symbol_msg_handler, this, _1)); +} + +} /* namespace satnogs */ } /* namespace gr */ diff --git a/lib/morse_decoder_impl.h b/lib/morse_decoder_impl.h index 0094e46..0eceedc 100644 --- a/lib/morse_decoder_impl.h +++ b/lib/morse_decoder_impl.h @@ -24,24 +24,27 @@ #include #include -namespace gr { - namespace satnogs { +namespace gr +{ +namespace satnogs +{ - class morse_decoder_impl : public morse_decoder - { - private: - morse_tree d_morse_tree; - size_t d_min_frame_len; +class morse_decoder_impl : public morse_decoder +{ - void - symbol_msg_handler(pmt::pmt_t msg); +public: + morse_decoder_impl (char unrecognized_char, size_t min_frame_len); - public: - morse_decoder_impl(char unrecognized_char, size_t min_frame_len); +private: + morse_tree d_morse_tree; + size_t d_min_frame_len; + std::string d_str; - }; + void + symbol_msg_handler (pmt::pmt_t msg); +}; - } // namespace satnogs +} // namespace satnogs } // namespace gr #endif /* INCLUDED_SATNOGS_MORSE_DECODER_IMPL_H */ From 4104091066b944bd6c159efbdf06840bdd347829 Mon Sep 17 00:00:00 2001 From: Manolis Surligas Date: Fri, 4 Jan 2019 20:33:55 +0200 Subject: [PATCH 02/24] Increase CW sensitivity * Switch from amplitude based approach to auto-correlation * Limit the bandwidth of the PLL using a low pass filter * Reject noise of the PLL using a very steep low pass after it --- apps/flowgraphs/cw_decoder.grc | 516 +++++++++++++++++++++----- apps/flowgraphs/fsk_ax25.grc | 24 +- apps/flowgraphs/satnogs_cw_decoder.py | 102 +++-- apps/flowgraphs/satnogs_fsk_ax25.py | 13 +- 4 files changed, 503 insertions(+), 152 deletions(-) diff --git a/apps/flowgraphs/cw_decoder.grc b/apps/flowgraphs/cw_decoder.grc index 87eec52..b1a9146 100644 --- a/apps/flowgraphs/cw_decoder.grc +++ b/apps/flowgraphs/cw_decoder.grc @@ -116,6 +116,123 @@ 48000 + + variable + + comment + + + + _enabled + 1 + + + _coordinate + (455, 35) + + + _rotation + 0 + + + id + dec + + + value + 8 + + + + variable + + comment + + + + _enabled + 1 + + + _coordinate + (359, 35) + + + _rotation + 0 + + + id + dot_samples + + + value + int((1.2 / wpm) / (1.0 / (audio_samp_rate / 10.0))) + + + + analog_agc2_xx + + attack_rate + 1e-4 + + + alias + + + + comment + + + + affinity + + + + decay_rate + 1e-4 + + + _enabled + 1 + + + _coordinate + (567, 283) + + + _rotation + 0 + + + gain + 1.0 + + + id + analog_agc2_xx_0 + + + max_gain + 65536 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + reference + 1.0 + + + type + complex + + analog_agc2_xx @@ -179,65 +296,6 @@ complex - - analog_agc_xx - - alias - - - - comment - - - - affinity - - - - _enabled - 1 - - - _coordinate - (1372, 339) - - - _rotation - 0 - - - gain - 1.0 - - - id - analog_agc_xx_0 - - - max_gain - 65536 - - - maxoutbuf - 0 - - - minoutbuf - 0 - - - rate - 1e-3 - - - reference - 1.0 - - - type - float - - analog_pll_carriertracking_cc @@ -258,7 +316,7 @@ _coordinate - (960, 348) + (919, 299) _rotation @@ -270,11 +328,11 @@ w - 2*math.pi/400.0 + 2*math.pi/100 max_freq - 2*math.pi*2e3/audio_samp_rate + 2*math.pi*2500 maxoutbuf @@ -282,7 +340,7 @@ min_freq - -2*math.pi*2e3/audio_samp_rate + -2*math.pi*2500 minoutbuf @@ -496,7 +554,7 @@ tone. This tone is typically 1 kHz. - blocks_complex_to_mag_squared + blocks_complex_to_mag alias @@ -515,15 +573,15 @@ tone. This tone is typically 1 kHz. _coordinate - (1168, 368) + (1630, 479) _rotation - 0 + 180 id - blocks_complex_to_mag_squared_0 + blocks_complex_to_mag_0 maxoutbuf @@ -581,6 +639,104 @@ tone. This tone is typically 1 kHz. 1 + + blocks_delay + + alias + + + + comment + + + + affinity + + + + delay + int(dot_samples)/dec + + + _enabled + 1 + + + _coordinate + (1302, 403) + + + _rotation + 0 + + + id + blocks_delay_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + num_ports + 1 + + + type + complex + + + vlen + 1 + + + + blocks_multiply_conjugate_cc + + alias + + + + comment + + + + affinity + + + + _enabled + 1 + + + _coordinate + (1358, 311) + + + _rotation + 0 + + + id + blocks_multiply_conjugate_cc_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + vlen + 1 + + blocks_multiply_xx @@ -910,6 +1066,61 @@ tone. This tone is typically 1 kHz. test.txt + + fir_filter_xxx + + alias + + + + comment + + + + affinity + + + + decim + 1 + + + _enabled + True + + + _coordinate + (1574, 315) + + + _rotation + 0 + + + id + fir_filter_xxx_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + samp_delay + 0 + + + taps + [1.0] * (int(dot_samples)/dec) + + + type + ccc + + parameter @@ -1134,7 +1345,7 @@ we shift the LO a little further cutoff_freq - 2e3 + 200 decim @@ -1150,7 +1361,7 @@ we shift the LO a little further _coordinate - (1268, 179) + (1102, 267) _rotation @@ -1178,11 +1389,11 @@ we shift the LO a little further samp_rate - audio_samp_rate + audio_samp_rate/10 width - 1e3 + 0.1e3 win @@ -1201,7 +1412,7 @@ we shift the LO a little further comment - Output samplerate: 20k / 4 = 5k + affinity @@ -1209,11 +1420,11 @@ we shift the LO a little further cutoff_freq - 100 + 2500 decim - 4 + 10 _enabled @@ -1221,19 +1432,19 @@ we shift the LO a little further type - fir_filter_fff + fir_filter_ccf _coordinate - (1584, 420) + (743, 267) _rotation - 180 + 0 gain - 4 + 1 id @@ -1257,7 +1468,82 @@ we shift the LO a little further width - 100 + 0.4e3 + + + win + firdes.WIN_HAMMING + + + + low_pass_filter + + beta + 6.76 + + + alias + + + + comment + + + + affinity + + + + cutoff_freq + 2500 + + + decim + 1 + + + _enabled + True + + + type + fir_filter_ccf + + + _coordinate + (1310, 155) + + + _rotation + 0 + + + gain + 1 + + + id + low_pass_filter_0_0_0 + + + interp + 1 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + samp_rate + audio_samp_rate + + + width + 0.8e3 win @@ -3067,7 +3353,7 @@ we shift the LO a little further satnogs_cw_to_symbol threshold - 0.4 + 2.0 alias @@ -3079,7 +3365,7 @@ we shift the LO a little further conf_level - 0.75 + 0.90 affinity @@ -3091,12 +3377,16 @@ we shift the LO a little further _coordinate - (1336, 460) + (1206, 459) _rotation 180 + + hysteresis + dot_samples/dec + id satnogs_cw_to_symbol_0 @@ -3111,7 +3401,7 @@ we shift the LO a little further sampling_rate - audio_samp_rate/4 + audio_samp_rate/10.0 wpm @@ -3224,7 +3514,7 @@ we shift the LO a little further _coordinate - (952, 444) + (951, 483) _rotation @@ -3639,21 +3929,21 @@ we shift the LO a little further 20 + + analog_agc2_xx_0 + low_pass_filter_0_0 + 0 + 0 + analog_agc2_xx_0_0 blocks_multiply_xx_0 0 1 - - analog_agc_xx_0 - low_pass_filter_0_0 - 0 - 0 - analog_pll_carriertracking_cc_0 - blocks_complex_to_mag_squared_0 + low_pass_filter_0 0 0 @@ -3664,8 +3954,8 @@ we shift the LO a little further 0 - blocks_complex_to_mag_squared_0 - analog_agc_xx_0 + blocks_complex_to_mag_0 + satnogs_cw_to_symbol_0 0 0 @@ -3675,6 +3965,18 @@ we shift the LO a little further 0 0 + + blocks_delay_0 + blocks_multiply_conjugate_cc_0 + 0 + 1 + + + blocks_multiply_conjugate_cc_0 + fir_filter_xxx_0 + 0 + 0 + blocks_multiply_xx_0 blocks_complex_to_real_0 @@ -3688,20 +3990,32 @@ we shift the LO a little further 0 - low_pass_filter_0 - analog_agc2_xx_0_0 + fir_filter_xxx_0 + blocks_complex_to_mag_0 0 0 low_pass_filter_0 - analog_pll_carriertracking_cc_0 + blocks_delay_0 + 0 + 0 + + + low_pass_filter_0 + blocks_multiply_conjugate_cc_0 0 0 low_pass_filter_0_0 - satnogs_cw_to_symbol_0 + analog_pll_carriertracking_cc_0 + 0 + 0 + + + low_pass_filter_0_0_0 + analog_agc2_xx_0_0 0 0 @@ -3713,7 +4027,13 @@ we shift the LO a little further pfb_arb_resampler_xxx_0 - low_pass_filter_0 + analog_agc2_xx_0 + 0 + 0 + + + pfb_arb_resampler_xxx_0 + low_pass_filter_0_0_0 0 0 diff --git a/apps/flowgraphs/fsk_ax25.grc b/apps/flowgraphs/fsk_ax25.grc index e389e60..6de43c5 100644 --- a/apps/flowgraphs/fsk_ax25.grc +++ b/apps/flowgraphs/fsk_ax25.grc @@ -136,7 +136,7 @@ _coordinate - (1248, 196) + (975, 395) _rotation @@ -677,7 +677,7 @@ omega - 2 + 4 type @@ -2457,7 +2457,7 @@ we shift the LO a little further atten - 100 + 60 taps @@ -2488,7 +2488,7 @@ we shift the LO a little further _coordinate - (984, 172) + (727, 275) _rotation @@ -2512,7 +2512,7 @@ we shift the LO a little further rrate - (2.0*baudrate)/audio_samp_rate + (4.0*baudrate)/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx) samp_delay @@ -2520,7 +2520,7 @@ we shift the LO a little further atten - 100 + 60 taps @@ -3512,12 +3512,6 @@ we shift the LO a little further 0 0 - - pfb_arb_resampler_xxx_0 - pfb_arb_resampler_xxx_0_0 - 0 - 0 - pfb_arb_resampler_xxx_0 satnogs_iq_sink_0 @@ -3566,6 +3560,12 @@ we shift the LO a little further 0 0 + + satnogs_coarse_doppler_correction_cc_0 + pfb_arb_resampler_xxx_0_0 + 0 + 0 + satnogs_quad_demod_filter_ff_0 digital_binary_slicer_fb_0 diff --git a/apps/flowgraphs/satnogs_cw_decoder.py b/apps/flowgraphs/satnogs_cw_decoder.py index 630ba3c..4c3af5b 100755 --- a/apps/flowgraphs/satnogs_cw_decoder.py +++ b/apps/flowgraphs/satnogs_cw_decoder.py @@ -5,7 +5,7 @@ # Title: CW Decoder # Author: Manolis Surligas (surligas@gmail.com) # Description: A CW (Morse) Decoder -# Generated: Sun Aug 19 21:56:19 2018 +# Generated: Sun Jan 6 13:47:58 2019 ################################################## from gnuradio import analog @@ -25,7 +25,7 @@ import time class satnogs_cw_decoder(gr.top_block): - def __init__(self, antenna=satnogs.not_set_antenna, bb_gain=satnogs.not_set_rx_bb_gain, bfo_freq=1e3, decoded_data_file_path='/tmp/.satnogs/data/data', dev_args=satnogs.not_set_dev_args, doppler_correction_per_sec=1000, enable_iq_dump=0, file_path='test.txt', if_gain=satnogs.not_set_rx_if_gain, iq_file_path='/tmp/iq.dat', lo_offset=100e3, ppm=0, rf_gain=satnogs.not_set_rx_rf_gain, rigctl_port=4532, rx_freq=100e6, rx_sdr_device='usrpb200', udp_IP='127.0.0.1', udp_port=16887, waterfall_file_path='/tmp/waterfall.dat', wpm=20, samp_rate_rx=satnogs.not_set_samp_rate_rx): + def __init__(self, antenna=satnogs.not_set_antenna, bb_gain=satnogs.not_set_rx_bb_gain, bfo_freq=1e3, decoded_data_file_path='/tmp/.satnogs/data/data', dev_args=satnogs.not_set_dev_args, doppler_correction_per_sec=1000, enable_iq_dump=0, file_path='test.txt', if_gain=satnogs.not_set_rx_if_gain, iq_file_path='/tmp/iq.dat', lo_offset=100e3, ppm=0, rf_gain=satnogs.not_set_rx_rf_gain, rigctl_port=4532, rx_freq=100e6, rx_sdr_device='usrpb200', samp_rate_rx=satnogs.not_set_samp_rate_rx, udp_IP='127.0.0.1', udp_port=16887, waterfall_file_path='/tmp/waterfall.dat', wpm=20): gr.top_block.__init__(self, "CW Decoder") ################################################## @@ -47,16 +47,18 @@ class satnogs_cw_decoder(gr.top_block): self.rigctl_port = rigctl_port self.rx_freq = rx_freq self.rx_sdr_device = rx_sdr_device + self.samp_rate_rx = samp_rate_rx self.udp_IP = udp_IP self.udp_port = udp_port self.waterfall_file_path = waterfall_file_path self.wpm = wpm - self.samp_rate_rx = samp_rate_rx ################################################## # Variables ################################################## self.audio_samp_rate = audio_samp_rate = 48000 + self.dot_samples = dot_samples = int((1.2 / wpm) / (1.0 / (audio_samp_rate / 10.0))) + self.dec = dec = 8 ################################################## # Blocks @@ -68,7 +70,7 @@ class satnogs_cw_decoder(gr.top_block): self.satnogs_morse_decoder_0 = satnogs.morse_decoder(ord('#'), 3) self.satnogs_iq_sink_0 = satnogs.iq_sink(16768, iq_file_path, False, enable_iq_dump) self.satnogs_frame_file_sink_0_0 = satnogs.frame_file_sink(decoded_data_file_path, 0) - self.satnogs_cw_to_symbol_0 = satnogs.cw_to_symbol(audio_samp_rate/4, 0.4, 0.75, wpm) + self.satnogs_cw_to_symbol_0 = satnogs.cw_to_symbol(audio_samp_rate/10.0, 2.0, 0.90, wpm, dot_samples/dec) self.satnogs_coarse_doppler_correction_cc_0 = satnogs.coarse_doppler_correction_cc(rx_freq, satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx)) self.pfb_arb_resampler_xxx_0 = pfb.arb_resampler_ccf( audio_samp_rate/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx), @@ -89,20 +91,26 @@ class satnogs_cw_decoder(gr.top_block): self.osmosdr_source_0.set_antenna(satnogs.handle_rx_antenna(rx_sdr_device, antenna), 0) self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx), 0) - self.low_pass_filter_0_0 = filter.fir_filter_fff(4, firdes.low_pass( - 4, audio_samp_rate, 100, 100, firdes.WIN_HAMMING, 6.76)) + self.low_pass_filter_0_0_0 = filter.fir_filter_ccf(1, firdes.low_pass( + 1, audio_samp_rate, 2500, 0.8e3, firdes.WIN_HAMMING, 6.76)) + self.low_pass_filter_0_0 = filter.fir_filter_ccf(10, firdes.low_pass( + 1, audio_samp_rate, 2500, 0.4e3, firdes.WIN_HAMMING, 6.76)) self.low_pass_filter_0 = filter.fir_filter_ccf(1, firdes.low_pass( - 1, audio_samp_rate, 2e3, 1e3, firdes.WIN_HAMMING, 6.76)) + 1, audio_samp_rate/10, 200, 0.1e3, firdes.WIN_HAMMING, 6.76)) + self.fir_filter_xxx_0 = filter.fir_filter_ccc(1, ([1.0] * (int(dot_samples)/dec))) + self.fir_filter_xxx_0.declare_sample_delay(0) self.blocks_rotator_cc_0 = blocks.rotator_cc(-2.0 * math.pi * (lo_offset / satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx))) self.blocks_multiply_xx_0 = blocks.multiply_vcc(1) + self.blocks_multiply_conjugate_cc_0 = blocks.multiply_conjugate_cc(1) + self.blocks_delay_0 = blocks.delay(gr.sizeof_gr_complex*1, int(dot_samples)/dec) self.blocks_complex_to_real_0 = blocks.complex_to_real(1) - self.blocks_complex_to_mag_squared_0 = blocks.complex_to_mag_squared(1) + self.blocks_complex_to_mag_0 = blocks.complex_to_mag(1) self.analog_sig_source_x_0 = analog.sig_source_c(audio_samp_rate, analog.GR_COS_WAVE, bfo_freq, 1, 0) - self.analog_pll_carriertracking_cc_0 = analog.pll_carriertracking_cc(2*math.pi/400.0, 2*math.pi*2e3/audio_samp_rate, -2*math.pi*2e3/audio_samp_rate) - self.analog_agc_xx_0 = analog.agc_ff(1e-3, 1.0, 1.0) - self.analog_agc_xx_0.set_max_gain(65536) + self.analog_pll_carriertracking_cc_0 = analog.pll_carriertracking_cc(2*math.pi/100, 2*math.pi*2500, -2*math.pi*2500) self.analog_agc2_xx_0_0 = analog.agc2_cc(0.01, 0.001, 0.015, 0.0) self.analog_agc2_xx_0_0.set_max_gain(65536) + self.analog_agc2_xx_0 = analog.agc2_cc(1e-4, 1e-4, 1.0, 1.0) + self.analog_agc2_xx_0.set_max_gain(65536) @@ -113,19 +121,24 @@ class satnogs_cw_decoder(gr.top_block): self.msg_connect((self.satnogs_morse_decoder_0, 'out'), (self.satnogs_frame_file_sink_0_0, 'frame')) self.msg_connect((self.satnogs_morse_decoder_0, 'out'), (self.satnogs_udp_msg_sink_0_0, 'in')) self.msg_connect((self.satnogs_tcp_rigctl_msg_source_0, 'freq'), (self.satnogs_coarse_doppler_correction_cc_0, 'freq')) + self.connect((self.analog_agc2_xx_0, 0), (self.low_pass_filter_0_0, 0)) self.connect((self.analog_agc2_xx_0_0, 0), (self.blocks_multiply_xx_0, 1)) - self.connect((self.analog_agc_xx_0, 0), (self.low_pass_filter_0_0, 0)) - self.connect((self.analog_pll_carriertracking_cc_0, 0), (self.blocks_complex_to_mag_squared_0, 0)) + self.connect((self.analog_pll_carriertracking_cc_0, 0), (self.low_pass_filter_0, 0)) self.connect((self.analog_sig_source_x_0, 0), (self.blocks_multiply_xx_0, 0)) - self.connect((self.blocks_complex_to_mag_squared_0, 0), (self.analog_agc_xx_0, 0)) + self.connect((self.blocks_complex_to_mag_0, 0), (self.satnogs_cw_to_symbol_0, 0)) self.connect((self.blocks_complex_to_real_0, 0), (self.satnogs_ogg_encoder_0, 0)) + self.connect((self.blocks_delay_0, 0), (self.blocks_multiply_conjugate_cc_0, 1)) + self.connect((self.blocks_multiply_conjugate_cc_0, 0), (self.fir_filter_xxx_0, 0)) self.connect((self.blocks_multiply_xx_0, 0), (self.blocks_complex_to_real_0, 0)) self.connect((self.blocks_rotator_cc_0, 0), (self.satnogs_coarse_doppler_correction_cc_0, 0)) - self.connect((self.low_pass_filter_0, 0), (self.analog_agc2_xx_0_0, 0)) - self.connect((self.low_pass_filter_0, 0), (self.analog_pll_carriertracking_cc_0, 0)) - self.connect((self.low_pass_filter_0_0, 0), (self.satnogs_cw_to_symbol_0, 0)) + self.connect((self.fir_filter_xxx_0, 0), (self.blocks_complex_to_mag_0, 0)) + self.connect((self.low_pass_filter_0, 0), (self.blocks_delay_0, 0)) + self.connect((self.low_pass_filter_0, 0), (self.blocks_multiply_conjugate_cc_0, 0)) + self.connect((self.low_pass_filter_0_0, 0), (self.analog_pll_carriertracking_cc_0, 0)) + self.connect((self.low_pass_filter_0_0_0, 0), (self.analog_agc2_xx_0_0, 0)) self.connect((self.osmosdr_source_0, 0), (self.blocks_rotator_cc_0, 0)) - self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.low_pass_filter_0, 0)) + self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.analog_agc2_xx_0, 0)) + self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.low_pass_filter_0_0_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.satnogs_iq_sink_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.satnogs_waterfall_sink_0, 0)) self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.pfb_arb_resampler_xxx_0, 0)) @@ -244,6 +257,16 @@ class satnogs_cw_decoder(gr.top_block): self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx), 0) self.blocks_rotator_cc_0.set_phase_inc(-2.0 * math.pi * (self.lo_offset / satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx))) + def get_samp_rate_rx(self): + return self.samp_rate_rx + + def set_samp_rate_rx(self, samp_rate_rx): + self.samp_rate_rx = samp_rate_rx + self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) + self.osmosdr_source_0.set_sample_rate(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) + self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx), 0) + self.blocks_rotator_cc_0.set_phase_inc(-2.0 * math.pi * (self.lo_offset / satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx))) + def get_udp_IP(self): return self.udp_IP @@ -267,28 +290,35 @@ class satnogs_cw_decoder(gr.top_block): def set_wpm(self, wpm): self.wpm = wpm - - def get_samp_rate_rx(self): - return self.samp_rate_rx - - def set_samp_rate_rx(self, samp_rate_rx): - self.samp_rate_rx = samp_rate_rx - self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) - self.osmosdr_source_0.set_sample_rate(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) - self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx), 0) - self.blocks_rotator_cc_0.set_phase_inc(-2.0 * math.pi * (self.lo_offset / satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx))) + self.set_dot_samples(int((1.2 / self.wpm) / (1.0 / (self.audio_samp_rate / 10.0)))) def get_audio_samp_rate(self): return self.audio_samp_rate def set_audio_samp_rate(self, audio_samp_rate): self.audio_samp_rate = audio_samp_rate + self.set_dot_samples(int((1.2 / self.wpm) / (1.0 / (self.audio_samp_rate / 10.0)))) self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) - self.low_pass_filter_0_0.set_taps(firdes.low_pass(4, self.audio_samp_rate, 100, 100, firdes.WIN_HAMMING, 6.76)) - self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, 2e3, 1e3, firdes.WIN_HAMMING, 6.76)) + self.low_pass_filter_0_0_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, 2500, 0.8e3, firdes.WIN_HAMMING, 6.76)) + self.low_pass_filter_0_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, 2500, 0.4e3, firdes.WIN_HAMMING, 6.76)) + self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate/10, 200, 0.1e3, firdes.WIN_HAMMING, 6.76)) self.analog_sig_source_x_0.set_sampling_freq(self.audio_samp_rate) - self.analog_pll_carriertracking_cc_0.set_max_freq(2*math.pi*2e3/self.audio_samp_rate) - self.analog_pll_carriertracking_cc_0.set_min_freq(-2*math.pi*2e3/self.audio_samp_rate) + + def get_dot_samples(self): + return self.dot_samples + + def set_dot_samples(self, dot_samples): + self.dot_samples = dot_samples + self.fir_filter_xxx_0.set_taps(([1.0] * (int(self.dot_samples)/self.dec))) + self.blocks_delay_0.set_dly(int(self.dot_samples)/self.dec) + + def get_dec(self): + return self.dec + + def set_dec(self, dec): + self.dec = dec + self.fir_filter_xxx_0.set_taps(([1.0] * (int(self.dot_samples)/self.dec))) + self.blocks_delay_0.set_dly(int(self.dot_samples)/self.dec) def argument_parser(): @@ -342,6 +372,9 @@ def argument_parser(): parser.add_option( "", "--rx-sdr-device", dest="rx_sdr_device", type="string", default='usrpb200', help="Set rx_sdr_device [default=%default]") + parser.add_option( + "", "--samp-rate-rx", dest="samp_rate_rx", type="eng_float", default=eng_notation.num_to_str(satnogs.not_set_samp_rate_rx), + help="Set samp_rate_rx [default=%default]") parser.add_option( "", "--udp-IP", dest="udp_IP", type="string", default='127.0.0.1', help="Set udp_IP [default=%default]") @@ -354,9 +387,6 @@ def argument_parser(): parser.add_option( "", "--wpm", dest="wpm", type="intx", default=20, help="Set wpm [default=%default]") - parser.add_option( - "", "--samp-rate-rx", dest="samp_rate_rx", type="eng_float", default=eng_notation.num_to_str(satnogs.not_set_samp_rate_rx), - help="Set samp_rate_rx [default=%default]") return parser @@ -364,7 +394,7 @@ def main(top_block_cls=satnogs_cw_decoder, options=None): if options is None: options, _ = argument_parser().parse_args() - tb = top_block_cls(antenna=options.antenna, bb_gain=options.bb_gain, bfo_freq=options.bfo_freq, decoded_data_file_path=options.decoded_data_file_path, dev_args=options.dev_args, doppler_correction_per_sec=options.doppler_correction_per_sec, enable_iq_dump=options.enable_iq_dump, file_path=options.file_path, if_gain=options.if_gain, iq_file_path=options.iq_file_path, lo_offset=options.lo_offset, ppm=options.ppm, rf_gain=options.rf_gain, rigctl_port=options.rigctl_port, rx_freq=options.rx_freq, rx_sdr_device=options.rx_sdr_device, udp_IP=options.udp_IP, udp_port=options.udp_port, waterfall_file_path=options.waterfall_file_path, wpm=options.wpm, samp_rate_rx=options.samp_rate_rx) + tb = top_block_cls(antenna=options.antenna, bb_gain=options.bb_gain, bfo_freq=options.bfo_freq, decoded_data_file_path=options.decoded_data_file_path, dev_args=options.dev_args, doppler_correction_per_sec=options.doppler_correction_per_sec, enable_iq_dump=options.enable_iq_dump, file_path=options.file_path, if_gain=options.if_gain, iq_file_path=options.iq_file_path, lo_offset=options.lo_offset, ppm=options.ppm, rf_gain=options.rf_gain, rigctl_port=options.rigctl_port, rx_freq=options.rx_freq, rx_sdr_device=options.rx_sdr_device, samp_rate_rx=options.samp_rate_rx, udp_IP=options.udp_IP, udp_port=options.udp_port, waterfall_file_path=options.waterfall_file_path, wpm=options.wpm) tb.start() tb.wait() diff --git a/apps/flowgraphs/satnogs_fsk_ax25.py b/apps/flowgraphs/satnogs_fsk_ax25.py index 780b1f4..363a8a1 100755 --- a/apps/flowgraphs/satnogs_fsk_ax25.py +++ b/apps/flowgraphs/satnogs_fsk_ax25.py @@ -5,7 +5,7 @@ # Title: satnogs_fsk_ax25 # Author: Manolis Surligas (surligas@gmail.com) # Description: Generic FSK AX.25 decoder -# Generated: Fri Aug 17 00:38:04 2018 +# Generated: Fri Jan 4 20:33:37 2019 ################################################## from gnuradio import analog @@ -72,7 +72,7 @@ class satnogs_fsk_ax25(gr.top_block): self.satnogs_ax25_decoder_bm_0_0 = satnogs.ax25_decoder_bm('GND', 0, True, False, 1024) self.satnogs_ax25_decoder_bm_0 = satnogs.ax25_decoder_bm('GND', 0, True, True, 1024) self.pfb_arb_resampler_xxx_0_0 = pfb.arb_resampler_ccf( - (2.0*baudrate)/audio_samp_rate, + (4.0*baudrate)/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx), taps=None, flt_size=32) self.pfb_arb_resampler_xxx_0_0.declare_sample_delay(0) @@ -96,7 +96,7 @@ class satnogs_fsk_ax25(gr.top_block): self.osmosdr_source_0.set_antenna(satnogs.handle_rx_antenna(rx_sdr_device, antenna), 0) self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx), 0) - self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(2, 0.25*0.175*0.175, 0.5, 0.175, 0.005) + self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(4, 0.25*0.175*0.175, 0.5, 0.175, 0.005) self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb() self.dc_blocker_xx_0_0 = filter.dc_blocker_ff(1024, True) self.dc_blocker_xx_0 = filter.dc_blocker_ff(1024, True) @@ -124,11 +124,11 @@ class satnogs_fsk_ax25(gr.top_block): self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.satnogs_quad_demod_filter_ff_0, 0)) self.connect((self.osmosdr_source_0, 0), (self.blocks_rotator_cc_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.analog_quadrature_demod_cf_0_0_0, 0)) - self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.pfb_arb_resampler_xxx_0_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.satnogs_iq_sink_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.satnogs_waterfall_sink_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0_0, 0), (self.analog_quadrature_demod_cf_0_0, 0)) self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.pfb_arb_resampler_xxx_0, 0)) + self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.pfb_arb_resampler_xxx_0_0, 0)) self.connect((self.satnogs_quad_demod_filter_ff_0, 0), (self.digital_binary_slicer_fb_0, 0)) def get_antenna(self): @@ -143,7 +143,7 @@ class satnogs_fsk_ax25(gr.top_block): def set_baudrate(self, baudrate): self.baudrate = baudrate - self.pfb_arb_resampler_xxx_0_0.set_rate((2.0*self.baudrate)/self.audio_samp_rate) + self.pfb_arb_resampler_xxx_0_0.set_rate((4.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) def get_bb_gain(self): return self.bb_gain @@ -236,6 +236,7 @@ class satnogs_fsk_ax25(gr.top_block): def set_rx_sdr_device(self, rx_sdr_device): self.rx_sdr_device = rx_sdr_device + self.pfb_arb_resampler_xxx_0_0.set_rate((4.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.osmosdr_source_0.set_sample_rate(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.osmosdr_source_0.set_gain(satnogs.handle_rx_rf_gain(self.rx_sdr_device, self.rf_gain), 0) @@ -250,6 +251,7 @@ class satnogs_fsk_ax25(gr.top_block): def set_samp_rate_rx(self, samp_rate_rx): self.samp_rate_rx = samp_rate_rx + self.pfb_arb_resampler_xxx_0_0.set_rate((4.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.osmosdr_source_0.set_sample_rate(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx), 0) @@ -278,7 +280,6 @@ class satnogs_fsk_ax25(gr.top_block): def set_audio_samp_rate(self, audio_samp_rate): self.audio_samp_rate = audio_samp_rate - self.pfb_arb_resampler_xxx_0_0.set_rate((2.0*self.baudrate)/self.audio_samp_rate) self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) From 35149fc047dc98e66f3d5d03f382ef2762a5a1db Mon Sep 17 00:00:00 2001 From: Manolis Surligas Date: Sun, 6 Jan 2019 14:19:59 +0200 Subject: [PATCH 03/24] Improve sensitivity of FSK/MSK flowgraphs --- apps/flowgraphs/fsk_ax25.grc | 95 +++++++++++++++++++++-- apps/flowgraphs/msk_ax25.grc | 113 ++++++++++++++++++++++++---- apps/flowgraphs/satnogs_fsk_ax25.py | 8 +- apps/flowgraphs/satnogs_msk_ax25.py | 23 +++--- 4 files changed, 205 insertions(+), 34 deletions(-) diff --git a/apps/flowgraphs/fsk_ax25.grc b/apps/flowgraphs/fsk_ax25.grc index 6de43c5..f19499e 100644 --- a/apps/flowgraphs/fsk_ax25.grc +++ b/apps/flowgraphs/fsk_ax25.grc @@ -136,7 +136,7 @@ _coordinate - (975, 395) + (1190, 411) _rotation @@ -179,7 +179,7 @@ _coordinate - (992, 316) + (1030, 195) _rotation @@ -406,7 +406,7 @@ _coordinate - (1432, 188) + (1390, 403) _rotation @@ -457,7 +457,7 @@ _coordinate - (1208, 308) + (1206, 187) _rotation @@ -641,7 +641,7 @@ _coordinate - (1616, 164) + (1590, 379) _rotation @@ -998,6 +998,81 @@ we shift the LO a little further 100e3 + + low_pass_filter + + beta + 6.76 + + + alias + + + + comment + + + + affinity + + + + cutoff_freq + baudrate / 2 + 1500 + + + decim + 1 + + + _enabled + True + + + type + fir_filter_ccf + + + _coordinate + (1007, 363) + + + _rotation + 0 + + + gain + 1 + + + id + low_pass_filter_0 + + + interp + 1 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + samp_rate + 4.0 * baudrate + + + width + 1000 + + + win + firdes.WIN_HAMMING + + osmosdr_source @@ -3088,7 +3163,7 @@ we shift the LO a little further _coordinate - (1384, 300) + (1382, 179) _rotation @@ -3500,6 +3575,12 @@ we shift the LO a little further 0 0 + + low_pass_filter_0 + analog_quadrature_demod_cf_0_0 + 0 + 0 + osmosdr_source_0 blocks_rotator_cc_0 @@ -3526,7 +3607,7 @@ we shift the LO a little further pfb_arb_resampler_xxx_0_0 - analog_quadrature_demod_cf_0_0 + low_pass_filter_0 0 0 diff --git a/apps/flowgraphs/msk_ax25.grc b/apps/flowgraphs/msk_ax25.grc index 321727f..0db7bf8 100644 --- a/apps/flowgraphs/msk_ax25.grc +++ b/apps/flowgraphs/msk_ax25.grc @@ -136,7 +136,7 @@ _coordinate - (1248, 196) + (1214, 419) _rotation @@ -406,7 +406,7 @@ _coordinate - (1432, 188) + (1430, 411) _rotation @@ -641,7 +641,7 @@ _coordinate - (1616, 164) + (1614, 387) _rotation @@ -677,7 +677,7 @@ omega - 2 + 4 type @@ -998,6 +998,81 @@ we shift the LO a little further 100e3 + + low_pass_filter + + beta + 6.76 + + + alias + + + + comment + + + + affinity + + + + cutoff_freq + baudrate / 2 + 1500 + + + decim + 1 + + + _enabled + True + + + type + fir_filter_ccf + + + _coordinate + (1022, 371) + + + _rotation + 0 + + + gain + 1 + + + id + low_pass_filter_0 + + + interp + 1 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + samp_rate + 4.0 * baudrate + + + width + 1000 + + + win + firdes.WIN_HAMMING + + osmosdr_source @@ -2488,7 +2563,7 @@ we shift the LO a little further _coordinate - (984, 172) + (735, 395) _rotation @@ -2496,7 +2571,7 @@ we shift the LO a little further id - pfb_arb_resampler_xxx_0_0 + pfb_arb_resampler_xxx_0_0_0 maxoutbuf @@ -2512,7 +2587,7 @@ we shift the LO a little further rrate - (2.0*baudrate)/audio_samp_rate + (4.0*baudrate)/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx) samp_delay @@ -2520,7 +2595,7 @@ we shift the LO a little further atten - 100 + 60 taps @@ -3500,6 +3575,12 @@ we shift the LO a little further 0 0 + + low_pass_filter_0 + analog_quadrature_demod_cf_0_0 + 0 + 0 + osmosdr_source_0 blocks_rotator_cc_0 @@ -3512,12 +3593,6 @@ we shift the LO a little further 0 0 - - pfb_arb_resampler_xxx_0 - pfb_arb_resampler_xxx_0_0 - 0 - 0 - pfb_arb_resampler_xxx_0 satnogs_iq_sink_0 @@ -3531,8 +3606,8 @@ we shift the LO a little further 0 - pfb_arb_resampler_xxx_0_0 - analog_quadrature_demod_cf_0_0 + pfb_arb_resampler_xxx_0_0_0 + low_pass_filter_0 0 0 @@ -3566,6 +3641,12 @@ we shift the LO a little further 0 0 + + satnogs_coarse_doppler_correction_cc_0 + pfb_arb_resampler_xxx_0_0_0 + 0 + 0 + satnogs_quad_demod_filter_ff_0 digital_binary_slicer_fb_0 diff --git a/apps/flowgraphs/satnogs_fsk_ax25.py b/apps/flowgraphs/satnogs_fsk_ax25.py index 363a8a1..acdef68 100755 --- a/apps/flowgraphs/satnogs_fsk_ax25.py +++ b/apps/flowgraphs/satnogs_fsk_ax25.py @@ -5,7 +5,7 @@ # Title: satnogs_fsk_ax25 # Author: Manolis Surligas (surligas@gmail.com) # Description: Generic FSK AX.25 decoder -# Generated: Fri Jan 4 20:33:37 2019 +# Generated: Sun Jan 6 14:19:34 2019 ################################################## from gnuradio import analog @@ -96,6 +96,8 @@ class satnogs_fsk_ax25(gr.top_block): self.osmosdr_source_0.set_antenna(satnogs.handle_rx_antenna(rx_sdr_device, antenna), 0) self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx), 0) + self.low_pass_filter_0 = filter.fir_filter_ccf(1, firdes.low_pass( + 1, 4.0 * baudrate, baudrate / 2 + 1500, 1000, firdes.WIN_HAMMING, 6.76)) self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(4, 0.25*0.175*0.175, 0.5, 0.175, 0.005) self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb() self.dc_blocker_xx_0_0 = filter.dc_blocker_ff(1024, True) @@ -122,11 +124,12 @@ class satnogs_fsk_ax25(gr.top_block): self.connect((self.digital_binary_slicer_fb_0, 0), (self.satnogs_ax25_decoder_bm_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self.satnogs_ax25_decoder_bm_0_0, 0)) self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.satnogs_quad_demod_filter_ff_0, 0)) + self.connect((self.low_pass_filter_0, 0), (self.analog_quadrature_demod_cf_0_0, 0)) self.connect((self.osmosdr_source_0, 0), (self.blocks_rotator_cc_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.analog_quadrature_demod_cf_0_0_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.satnogs_iq_sink_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.satnogs_waterfall_sink_0, 0)) - self.connect((self.pfb_arb_resampler_xxx_0_0, 0), (self.analog_quadrature_demod_cf_0_0, 0)) + self.connect((self.pfb_arb_resampler_xxx_0_0, 0), (self.low_pass_filter_0, 0)) self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.pfb_arb_resampler_xxx_0, 0)) self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.pfb_arb_resampler_xxx_0_0, 0)) self.connect((self.satnogs_quad_demod_filter_ff_0, 0), (self.digital_binary_slicer_fb_0, 0)) @@ -144,6 +147,7 @@ class satnogs_fsk_ax25(gr.top_block): def set_baudrate(self, baudrate): self.baudrate = baudrate self.pfb_arb_resampler_xxx_0_0.set_rate((4.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) + self.low_pass_filter_0.set_taps(firdes.low_pass(1, 4.0 * self.baudrate, self.baudrate / 2 + 1500, 1000, firdes.WIN_HAMMING, 6.76)) def get_bb_gain(self): return self.bb_gain diff --git a/apps/flowgraphs/satnogs_msk_ax25.py b/apps/flowgraphs/satnogs_msk_ax25.py index 09fe10c..7d12bf6 100755 --- a/apps/flowgraphs/satnogs_msk_ax25.py +++ b/apps/flowgraphs/satnogs_msk_ax25.py @@ -5,7 +5,7 @@ # Title: satnogs_msk_ax25 # Author: Manolis Surligas (surligas@gmail.com) # Description: Generic MSK AX.25 decoder -# Generated: Fri Aug 17 00:38:15 2018 +# Generated: Sun Jan 6 14:17:55 2019 ################################################## from gnuradio import analog @@ -71,11 +71,11 @@ class satnogs_msk_ax25(gr.top_block): self.satnogs_coarse_doppler_correction_cc_0 = satnogs.coarse_doppler_correction_cc(rx_freq, satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx)) self.satnogs_ax25_decoder_bm_0_0 = satnogs.ax25_decoder_bm('GND', 0, True, False, 1024) self.satnogs_ax25_decoder_bm_0 = satnogs.ax25_decoder_bm('GND', 0, True, True, 1024) - self.pfb_arb_resampler_xxx_0_0 = pfb.arb_resampler_ccf( - (2.0*baudrate)/audio_samp_rate, + self.pfb_arb_resampler_xxx_0_0_0 = pfb.arb_resampler_ccf( + (4.0*baudrate)/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx), taps=None, flt_size=32) - self.pfb_arb_resampler_xxx_0_0.declare_sample_delay(0) + self.pfb_arb_resampler_xxx_0_0_0.declare_sample_delay(0) self.pfb_arb_resampler_xxx_0 = pfb.arb_resampler_ccf( audio_samp_rate/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx), @@ -96,7 +96,9 @@ class satnogs_msk_ax25(gr.top_block): self.osmosdr_source_0.set_antenna(satnogs.handle_rx_antenna(rx_sdr_device, antenna), 0) self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx), 0) - self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(2, 0.25*0.175*0.175, 0.5, 0.175, 0.005) + self.low_pass_filter_0 = filter.fir_filter_ccf(1, firdes.low_pass( + 1, 4.0 * baudrate, baudrate / 2 + 1500, 1000, firdes.WIN_HAMMING, 6.76)) + self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(4, 0.25*0.175*0.175, 0.5, 0.175, 0.005) self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb() self.dc_blocker_xx_0_0 = filter.dc_blocker_ff(1024, True) self.dc_blocker_xx_0 = filter.dc_blocker_ff(1024, True) @@ -122,13 +124,14 @@ class satnogs_msk_ax25(gr.top_block): self.connect((self.digital_binary_slicer_fb_0, 0), (self.satnogs_ax25_decoder_bm_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self.satnogs_ax25_decoder_bm_0_0, 0)) self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.satnogs_quad_demod_filter_ff_0, 0)) + self.connect((self.low_pass_filter_0, 0), (self.analog_quadrature_demod_cf_0_0, 0)) self.connect((self.osmosdr_source_0, 0), (self.blocks_rotator_cc_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.analog_quadrature_demod_cf_0_0_0, 0)) - self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.pfb_arb_resampler_xxx_0_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.satnogs_iq_sink_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.satnogs_waterfall_sink_0, 0)) - self.connect((self.pfb_arb_resampler_xxx_0_0, 0), (self.analog_quadrature_demod_cf_0_0, 0)) + self.connect((self.pfb_arb_resampler_xxx_0_0_0, 0), (self.low_pass_filter_0, 0)) self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.pfb_arb_resampler_xxx_0, 0)) + self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.pfb_arb_resampler_xxx_0_0_0, 0)) self.connect((self.satnogs_quad_demod_filter_ff_0, 0), (self.digital_binary_slicer_fb_0, 0)) def get_antenna(self): @@ -143,7 +146,8 @@ class satnogs_msk_ax25(gr.top_block): def set_baudrate(self, baudrate): self.baudrate = baudrate - self.pfb_arb_resampler_xxx_0_0.set_rate((2.0*self.baudrate)/self.audio_samp_rate) + self.pfb_arb_resampler_xxx_0_0_0.set_rate((4.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) + self.low_pass_filter_0.set_taps(firdes.low_pass(1, 4.0 * self.baudrate, self.baudrate / 2 + 1500, 1000, firdes.WIN_HAMMING, 6.76)) def get_bb_gain(self): return self.bb_gain @@ -236,6 +240,7 @@ class satnogs_msk_ax25(gr.top_block): def set_rx_sdr_device(self, rx_sdr_device): self.rx_sdr_device = rx_sdr_device + self.pfb_arb_resampler_xxx_0_0_0.set_rate((4.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.osmosdr_source_0.set_sample_rate(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.osmosdr_source_0.set_gain(satnogs.handle_rx_rf_gain(self.rx_sdr_device, self.rf_gain), 0) @@ -250,6 +255,7 @@ class satnogs_msk_ax25(gr.top_block): def set_samp_rate_rx(self, samp_rate_rx): self.samp_rate_rx = samp_rate_rx + self.pfb_arb_resampler_xxx_0_0_0.set_rate((4.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.osmosdr_source_0.set_sample_rate(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx), 0) @@ -278,7 +284,6 @@ class satnogs_msk_ax25(gr.top_block): def set_audio_samp_rate(self, audio_samp_rate): self.audio_samp_rate = audio_samp_rate - self.pfb_arb_resampler_xxx_0_0.set_rate((2.0*self.baudrate)/self.audio_samp_rate) self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) From a24d236c6646e473588a3a6319985b2fb196eeee Mon Sep 17 00:00:00 2001 From: Manolis Surligas Date: Tue, 22 Jan 2019 13:25:39 +0200 Subject: [PATCH 04/24] Bump up version to 1.5.1 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 19bc950..e9849bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,7 +48,7 @@ list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake/Modules) # Set the version information here set(VERSION_INFO_MAJOR_VERSION 1) set(VERSION_INFO_API_COMPAT 5) -set(VERSION_INFO_MINOR_VERSION 0) +set(VERSION_INFO_MINOR_VERSION 1) set(VERSION_INFO_MAINT_VERSION git) From f235c5f68cfb82ca688f9ca73e0e2504d84f3e24 Mon Sep 17 00:00:00 2001 From: Manolis Surligas Date: Wed, 3 Jul 2019 15:03:24 +0300 Subject: [PATCH 05/24] Remove AX.25 address field check --- lib/ax25_decoder_bm_impl.cc | 42 +------------------------------------ lib/ax25_decoder_bm_impl.h | 2 -- 2 files changed, 1 insertion(+), 43 deletions(-) diff --git a/lib/ax25_decoder_bm_impl.cc b/lib/ax25_decoder_bm_impl.cc index 7b84a09..0cc1250 100644 --- a/lib/ax25_decoder_bm_impl.cc +++ b/lib/ax25_decoder_bm_impl.cc @@ -2,7 +2,7 @@ /* * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module * - * Copyright (C) 2016, 2017, 2018 + * Copyright (C) 2016-2019 * Libre Space Foundation * * This program is free software: you can redistribute it and/or modify @@ -80,9 +80,6 @@ namespace gr size_t nitems) { size_t i; - uint8_t descr_bit; - uint8_t dec_bit; - switch (d_state) { case NO_SYNC: @@ -133,11 +130,6 @@ namespace gr else{ d_decoded_bits++; if(d_decoded_bits == 8) { - /* Check if the received byte is valid */ - if(!check_byte()) { - reset_state (); - return i + 1; - } d_frame_buffer[d_received_bytes] = d_dec_b; d_received_bytes++; d_decoded_bits = 0; @@ -180,8 +172,6 @@ namespace gr ax25_decoder_bm_impl::decode (const uint8_t* in, size_t nitems) { size_t i; - uint8_t descr_bit; - uint8_t dec_bit; switch (d_state) { case NO_SYNC: @@ -231,11 +221,6 @@ namespace gr else { d_decoded_bits++; if (d_decoded_bits == 8) { - /* Check if the received byte is valid */ - if(!check_byte()) { - reset_state (); - return i + 1; - } d_frame_buffer[d_received_bytes] = d_dec_b; d_received_bytes++; d_decoded_bits = 0; @@ -425,30 +410,6 @@ namespace gr d_dec_b = (d_dec_b >> 1) | (dec_bit << 7); } - /** - * Checks if a AX.25 decoded byte is valid. This actually can be checked - * only in the address field, where all fields should have the LS bit - * set to zero. - * @returns true if the decoded byte is valid, false otherwise - */ - inline bool - ax25_decoder_bm_impl::check_byte () - { - if(d_received_bytes < AX25_MIN_ADDR_LEN - 1) { - if(d_dec_b & 0x1) { - return false; - } - } - else if(d_received_bytes == AX25_MIN_ADDR_LEN - 1) { - if(d_dec_b & 0x1) { - return true; - } - return false; - } - return true; - } - - int ax25_decoder_bm_impl::work (int noutput_items, gr_vector_const_void_star &input_items, @@ -457,7 +418,6 @@ namespace gr int ret; const uint8_t *in = (const uint8_t *) input_items[0]; - if(noutput_items < 1) { return noutput_items; } diff --git a/lib/ax25_decoder_bm_impl.h b/lib/ax25_decoder_bm_impl.h index 637e6ce..86ba005 100644 --- a/lib/ax25_decoder_bm_impl.h +++ b/lib/ax25_decoder_bm_impl.h @@ -72,8 +72,6 @@ namespace gr descramble_and_decode_1b (uint8_t in); inline void decode_1b (uint8_t in); - inline bool - check_byte (); public: From 6ff86a25c90e628c6eae76f3d7d9b5876949f441 Mon Sep 17 00:00:00 2001 From: Manolis Surligas Date: Wed, 3 Jul 2019 15:25:00 +0300 Subject: [PATCH 06/24] Add VCO-based frequency correction This commit includes a blind frequency correction mechanism for FM signals. It uses the information of the angle difference between two concecutive samples and a VCO to continuously compenstate any frequency offset. To avoid intermodulations, a low pass filter is used trying to pass only the DC component that is needed. --- apps/flowgraphs/afsk1200_ax25.grc | 368 +++++++++++++++++---- apps/flowgraphs/fsk_ax25.grc | 386 ++++++++++++++++++----- apps/flowgraphs/msk_ax25.grc | 378 ++++++++++++++++++---- apps/flowgraphs/satnogs_afsk1200_ax25.py | 20 +- apps/flowgraphs/satnogs_fsk_ax25.py | 34 +- apps/flowgraphs/satnogs_msk_ax25.py | 34 +- 6 files changed, 988 insertions(+), 232 deletions(-) diff --git a/apps/flowgraphs/afsk1200_ax25.grc b/apps/flowgraphs/afsk1200_ax25.grc index d846ee4..b25a62a 100644 --- a/apps/flowgraphs/afsk1200_ax25.grc +++ b/apps/flowgraphs/afsk1200_ax25.grc @@ -283,6 +283,49 @@ 0 + + analog_quadrature_demod_cf + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (813, 283) + + + _rotation + 0 + + + gain + 1.0 + + + id + analog_quadrature_demod_cf_0_0_0_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + analog_sig_source_x @@ -487,6 +530,61 @@ satnogs.not_set_rx_bb_gain + + blocks_delay + + alias + + + + comment + + + + affinity + + + + delay + 1024/2 + + + _enabled + True + + + _coordinate + (821, 219) + + + _rotation + 0 + + + id + blocks_delay_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + num_ports + 1 + + + type + complex + + + vlen + 1 + + blocks_float_to_complex @@ -530,6 +628,65 @@ 1 + + blocks_moving_average_xx + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (981, 267) + + + _rotation + 0 + + + id + blocks_moving_average_xx_0 + + + vlen + 1 + + + length + 1024 + + + max_iter + 4096 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + scale + 1.0/1024.0 + + + type + float + + blocks_multiply_xx @@ -581,6 +738,57 @@ 1 + + blocks_multiply_xx + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (1308, 223) + + + _rotation + 0 + + + id + blocks_multiply_xx_0_0 + + + type + complex + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + num_inputs + 2 + + + vlen + 1 + + blocks_rotator_cc @@ -624,6 +832,57 @@ -2.0 * math.pi * (lo_offset / satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx)) + + blocks_vco_c + + amplitude + 1.0 + + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (1140, 267) + + + _rotation + 0 + + + id + blocks_vco_c_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + samp_rate + audio_samp_rate + + + sensitivity + -audio_samp_rate + + dc_blocker_xx @@ -789,7 +1048,7 @@ _coordinate - (2034, 606) + (1994, 606) _rotation @@ -1193,7 +1452,7 @@ max_modulation_freq = 3000 _coordinate - (1144, 276) + (853, 347) _rotation @@ -2781,7 +3040,7 @@ max_modulation_freq = 3000 _coordinate - (640, 196) + (534, 195) _rotation @@ -3338,7 +3597,7 @@ max_modulation_freq = 3000 _coordinate - (1304, 28) + (773, 27) _rotation @@ -3381,11 +3640,11 @@ max_modulation_freq = 3000 _coordinate - (368, 452) + (303, 379) _rotation - 0 + 180 id @@ -3400,53 +3659,6 @@ max_modulation_freq = 3000 audio_samp_rate - - satnogs_quad_demod_filter_ff - - alias - - - - comment - - - - affinity - - - - _enabled - True - - - _coordinate - (1795, 578) - - - _rotation - 0 - - - gain - ((audio_samp_rate/10) / baud_rate)/(math.pi*1) - - - id - satnogs_quad_demod_filter_ff_0 - - - maxoutbuf - 0 - - - minoutbuf - 0 - - - win - 80 - - satnogs_tcp_rigctl_msg_source @@ -3526,7 +3738,7 @@ max_modulation_freq = 3000 _coordinate - (1268, 666) + (1292, 785) _rotation @@ -3581,7 +3793,7 @@ max_modulation_freq = 3000 _coordinate - (872, 4) + (550, 3) _rotation @@ -3810,30 +4022,60 @@ max_modulation_freq = 3000 0 0 + + analog_quadrature_demod_cf_0_0_0_0 + blocks_moving_average_xx_0 + 0 + 0 + analog_sig_source_x_0 blocks_multiply_xx_0 0 1 + + blocks_delay_0 + blocks_multiply_xx_0_0 + 0 + 0 + blocks_float_to_complex_0 blocks_multiply_xx_0 0 0 + + blocks_moving_average_xx_0 + blocks_vco_c_0 + 0 + 0 + blocks_multiply_xx_0 low_pass_filter_1 0 0 + + blocks_multiply_xx_0_0 + low_pass_filter_0 + 0 + 0 + blocks_rotator_cc_0 satnogs_coarse_doppler_correction_cc_0 0 0 + + blocks_vco_c_0 + blocks_multiply_xx_0_0 + 0 + 1 + dc_blocker_xx_0 blocks_float_to_complex_0 @@ -3854,7 +4096,7 @@ max_modulation_freq = 3000 digital_clock_recovery_mm_xx_0 - satnogs_quad_demod_filter_ff_0 + digital_binary_slicer_fb_0 0 0 @@ -3878,7 +4120,13 @@ max_modulation_freq = 3000 pfb_arb_resampler_xxx_0 - low_pass_filter_0 + analog_quadrature_demod_cf_0_0_0_0 + 0 + 0 + + + pfb_arb_resampler_xxx_0 + blocks_delay_0 0 0 @@ -3924,12 +4172,6 @@ max_modulation_freq = 3000 0 0 - - satnogs_quad_demod_filter_ff_0 - digital_binary_slicer_fb_0 - 0 - 0 - satnogs_tcp_rigctl_msg_source_0 satnogs_coarse_doppler_correction_cc_0 diff --git a/apps/flowgraphs/fsk_ax25.grc b/apps/flowgraphs/fsk_ax25.grc index f19499e..aa44a2d 100644 --- a/apps/flowgraphs/fsk_ax25.grc +++ b/apps/flowgraphs/fsk_ax25.grc @@ -179,7 +179,7 @@ _coordinate - (1030, 195) + (1316, 83) _rotation @@ -202,6 +202,49 @@ 0 + + analog_quadrature_demod_cf + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (965, 259) + + + _rotation + 0 + + + gain + 1.0 + + + id + analog_quadrature_demod_cf_0_0_0_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + parameter @@ -343,6 +386,171 @@ satnogs.not_set_rx_bb_gain + + blocks_delay + + alias + + + + comment + + + + affinity + + + + delay + 1024/2 + + + _enabled + True + + + _coordinate + (1260, 171) + + + _rotation + 0 + + + id + blocks_delay_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + num_ports + 1 + + + type + complex + + + vlen + 1 + + + + blocks_moving_average_xx + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (1125, 243) + + + _rotation + 0 + + + id + blocks_moving_average_xx_0 + + + vlen + 1 + + + length + 1024 + + + max_iter + 4096 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + scale + 1.0/1024.0 + + + type + float + + + + blocks_multiply_xx + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (1452, 175) + + + _rotation + 0 + + + id + blocks_multiply_xx_0 + + + type + complex + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + num_inputs + 2 + + + vlen + 1 + + blocks_rotator_cc @@ -386,6 +594,57 @@ -2.0 * math.pi * (lo_offset / satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx)) + + blocks_vco_c + + amplitude + 1.0 + + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (1276, 243) + + + _rotation + 0 + + + id + blocks_vco_c_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + samp_rate + audio_samp_rate + + + sensitivity + -audio_samp_rate + + dc_blocker_xx @@ -457,7 +716,7 @@ _coordinate - (1206, 187) + (1492, 75) _rotation @@ -641,7 +900,7 @@ _coordinate - (1590, 379) + (1595, 379) _rotation @@ -677,7 +936,7 @@ omega - 4 + 2 type @@ -1018,7 +1277,7 @@ we shift the LO a little further cutoff_freq - baudrate / 2 + 1500 + (baudrate / 2) + 1500 decim @@ -1034,7 +1293,7 @@ we shift the LO a little further _coordinate - (1007, 363) + (1005, 371) _rotation @@ -1062,7 +1321,7 @@ we shift the LO a little further samp_rate - 4.0 * baudrate + 2.0 * baudrate width @@ -2563,7 +2822,7 @@ we shift the LO a little further _coordinate - (727, 275) + (1563, 163) _rotation @@ -2587,7 +2846,7 @@ we shift the LO a little further rrate - (4.0*baudrate)/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx) + (2.0*baudrate)/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx) samp_delay @@ -3120,7 +3379,7 @@ we shift the LO a little further _coordinate - (992, 68) + (965, 27) _rotation @@ -3163,7 +3422,7 @@ we shift the LO a little further _coordinate - (1382, 179) + (1667, 67) _rotation @@ -3182,53 +3441,6 @@ we shift the LO a little further audio_samp_rate - - satnogs_quad_demod_filter_ff - - alias - - - - comment - - - - affinity - - - - _enabled - True - - - _coordinate - (1664, 580) - - - _rotation - 180 - - - gain - 1.2 - - - id - satnogs_quad_demod_filter_ff_0 - - - maxoutbuf - 0 - - - minoutbuf - 0 - - - win - 80 - - satnogs_tcp_rigctl_msg_source @@ -3363,7 +3575,7 @@ we shift the LO a little further _coordinate - (760, 44) + (726, 3) _rotation @@ -3539,12 +3751,42 @@ we shift the LO a little further 0 0 + + analog_quadrature_demod_cf_0_0_0_0 + blocks_moving_average_xx_0 + 0 + 0 + + + blocks_delay_0 + blocks_multiply_xx_0 + 0 + 0 + + + blocks_moving_average_xx_0 + blocks_vco_c_0 + 0 + 0 + + + blocks_multiply_xx_0 + pfb_arb_resampler_xxx_0_0 + 0 + 0 + blocks_rotator_cc_0 satnogs_coarse_doppler_correction_cc_0 0 0 + + blocks_vco_c_0 + blocks_multiply_xx_0 + 0 + 1 + dc_blocker_xx_0 digital_clock_recovery_mm_xx_0 @@ -3571,7 +3813,7 @@ we shift the LO a little further digital_clock_recovery_mm_xx_0 - satnogs_quad_demod_filter_ff_0 + digital_binary_slicer_fb_0 0 0 @@ -3593,6 +3835,18 @@ we shift the LO a little further 0 0 + + pfb_arb_resampler_xxx_0 + analog_quadrature_demod_cf_0_0_0_0 + 0 + 0 + + + pfb_arb_resampler_xxx_0 + blocks_delay_0 + 0 + 0 + pfb_arb_resampler_xxx_0 satnogs_iq_sink_0 @@ -3641,18 +3895,6 @@ we shift the LO a little further 0 0 - - satnogs_coarse_doppler_correction_cc_0 - pfb_arb_resampler_xxx_0_0 - 0 - 0 - - - satnogs_quad_demod_filter_ff_0 - digital_binary_slicer_fb_0 - 0 - 0 - satnogs_tcp_rigctl_msg_source_0 satnogs_coarse_doppler_correction_cc_0 diff --git a/apps/flowgraphs/msk_ax25.grc b/apps/flowgraphs/msk_ax25.grc index 0db7bf8..84ab838 100644 --- a/apps/flowgraphs/msk_ax25.grc +++ b/apps/flowgraphs/msk_ax25.grc @@ -179,7 +179,7 @@ _coordinate - (992, 316) + (1460, 83) _rotation @@ -202,6 +202,49 @@ 0 + + analog_quadrature_demod_cf + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (981, 291) + + + _rotation + 0 + + + gain + 1.0 + + + id + analog_quadrature_demod_cf_0_0_0_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + parameter @@ -343,6 +386,171 @@ satnogs.not_set_rx_bb_gain + + blocks_delay + + alias + + + + comment + + + + affinity + + + + delay + 1024/2 + + + _enabled + True + + + _coordinate + (1292, 203) + + + _rotation + 0 + + + id + blocks_delay_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + num_ports + 1 + + + type + complex + + + vlen + 1 + + + + blocks_moving_average_xx + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (1164, 275) + + + _rotation + 0 + + + id + blocks_moving_average_xx_0 + + + vlen + 1 + + + length + 1024 + + + max_iter + 4096 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + scale + 1.0/1024.0 + + + type + float + + + + blocks_multiply_xx + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (1531, 239) + + + _rotation + 0 + + + id + blocks_multiply_xx_0 + + + type + complex + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + num_inputs + 2 + + + vlen + 1 + + blocks_rotator_cc @@ -386,6 +594,57 @@ -2.0 * math.pi * (lo_offset / satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx)) + + blocks_vco_c + + amplitude + 1.0 + + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (1324, 275) + + + _rotation + 0 + + + id + blocks_vco_c_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + samp_rate + audio_samp_rate + + + sensitivity + -audio_samp_rate + + dc_blocker_xx @@ -457,7 +716,7 @@ _coordinate - (1208, 308) + (1659, 75) _rotation @@ -641,7 +900,7 @@ _coordinate - (1614, 387) + (1611, 386) _rotation @@ -677,7 +936,7 @@ omega - 4 + 2 type @@ -1062,7 +1321,7 @@ we shift the LO a little further samp_rate - 4.0 * baudrate + 2.0 * baudrate width @@ -2587,7 +2846,7 @@ we shift the LO a little further rrate - (4.0*baudrate)/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx) + (2.0*baudrate)/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx) samp_delay @@ -3120,7 +3379,7 @@ we shift the LO a little further _coordinate - (976, 60) + (965, 59) _rotation @@ -3163,7 +3422,7 @@ we shift the LO a little further _coordinate - (1384, 300) + (1835, 67) _rotation @@ -3182,53 +3441,6 @@ we shift the LO a little further audio_samp_rate - - satnogs_quad_demod_filter_ff - - alias - - - - comment - - - - affinity - - - - _enabled - True - - - _coordinate - (1664, 580) - - - _rotation - 180 - - - gain - 1.2 - - - id - satnogs_quad_demod_filter_ff_0 - - - maxoutbuf - 0 - - - minoutbuf - 0 - - - win - 80 - - satnogs_tcp_rigctl_msg_source @@ -3539,12 +3751,42 @@ we shift the LO a little further 0 0 + + analog_quadrature_demod_cf_0_0_0_0 + blocks_moving_average_xx_0 + 0 + 0 + + + blocks_delay_0 + blocks_multiply_xx_0 + 0 + 0 + + + blocks_moving_average_xx_0 + blocks_vco_c_0 + 0 + 0 + + + blocks_multiply_xx_0 + pfb_arb_resampler_xxx_0_0_0 + 0 + 0 + blocks_rotator_cc_0 satnogs_coarse_doppler_correction_cc_0 0 0 + + blocks_vco_c_0 + blocks_multiply_xx_0 + 0 + 1 + dc_blocker_xx_0 digital_clock_recovery_mm_xx_0 @@ -3571,7 +3813,7 @@ we shift the LO a little further digital_clock_recovery_mm_xx_0 - satnogs_quad_demod_filter_ff_0 + digital_binary_slicer_fb_0 0 0 @@ -3593,6 +3835,18 @@ we shift the LO a little further 0 0 + + pfb_arb_resampler_xxx_0 + analog_quadrature_demod_cf_0_0_0_0 + 0 + 0 + + + pfb_arb_resampler_xxx_0 + blocks_delay_0 + 0 + 0 + pfb_arb_resampler_xxx_0 satnogs_iq_sink_0 @@ -3641,18 +3895,6 @@ we shift the LO a little further 0 0 - - satnogs_coarse_doppler_correction_cc_0 - pfb_arb_resampler_xxx_0_0_0 - 0 - 0 - - - satnogs_quad_demod_filter_ff_0 - digital_binary_slicer_fb_0 - 0 - 0 - satnogs_tcp_rigctl_msg_source_0 satnogs_coarse_doppler_correction_cc_0 diff --git a/apps/flowgraphs/satnogs_afsk1200_ax25.py b/apps/flowgraphs/satnogs_afsk1200_ax25.py index dfba673..37b73e3 100755 --- a/apps/flowgraphs/satnogs_afsk1200_ax25.py +++ b/apps/flowgraphs/satnogs_afsk1200_ax25.py @@ -5,9 +5,10 @@ # Title: AFSK1200 AX.25 decoder # Author: Manolis Surligas (surligas@gmail.com), Vardakis Giorgos (vardakis.grg@gmail.com) # Description: AFSK1200 AX.25 decoder -# Generated: Sun Nov 25 23:43:12 2018 +# GNU Radio version: 3.7.13.5 ################################################## + from gnuradio import analog from gnuradio import blocks from gnuradio import digital @@ -69,7 +70,6 @@ class satnogs_afsk1200_ax25(gr.top_block): self.satnogs_waterfall_sink_0 = satnogs.waterfall_sink(audio_samp_rate, 0.0, 10, 1024, waterfall_file_path, 1) self.satnogs_udp_msg_sink_0_0 = satnogs.udp_msg_sink(udp_IP, udp_port, 1500) self.satnogs_tcp_rigctl_msg_source_0 = satnogs.tcp_rigctl_msg_source("127.0.0.1", rigctl_port, False, 1000, 1500) - self.satnogs_quad_demod_filter_ff_0 = satnogs.quad_demod_filter_ff(((audio_samp_rate/10) / baud_rate)/(math.pi*1)) self.satnogs_ogg_encoder_0 = satnogs.ogg_encoder(file_path, audio_samp_rate, 1.0) self.satnogs_iq_sink_0 = satnogs.iq_sink(16768, iq_file_path, False, enable_iq_dump) self.satnogs_frame_file_sink_0_1_0 = satnogs.frame_file_sink(decoded_data_file_path, 0) @@ -102,10 +102,15 @@ class satnogs_afsk1200_ax25(gr.top_block): self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff((48e3/10)/baud_rate, 0.25*0.175*0.175, 0.5, 0.175, 0.005) self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb() self.dc_blocker_xx_0 = filter.dc_blocker_ff(1024, True) + self.blocks_vco_c_0 = blocks.vco_c(audio_samp_rate, -audio_samp_rate, 1.0) self.blocks_rotator_cc_0 = blocks.rotator_cc(-2.0 * math.pi * (lo_offset / satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx))) + self.blocks_multiply_xx_0_0 = blocks.multiply_vcc(1) self.blocks_multiply_xx_0 = blocks.multiply_vcc(1) + self.blocks_moving_average_xx_0 = blocks.moving_average_ff(1024, 1.0/1024.0, 4096, 1) self.blocks_float_to_complex_0 = blocks.float_to_complex(1) + self.blocks_delay_0 = blocks.delay(gr.sizeof_gr_complex*1, 1024/2) self.analog_sig_source_x_0 = analog.sig_source_c(audio_samp_rate, analog.GR_COS_WAVE, -(1200 + 2200) / 2, 1, 0) + self.analog_quadrature_demod_cf_0_0_0_0 = analog.quadrature_demod_cf(1.0) self.analog_quadrature_demod_cf_0_0 = analog.quadrature_demod_cf((2*math.pi*deviation)/audio_samp_rate) self.analog_quadrature_demod_cf_0 = analog.quadrature_demod_cf(((audio_samp_rate/10) / baud_rate)/(math.pi*1)) @@ -122,22 +127,27 @@ class satnogs_afsk1200_ax25(gr.top_block): self.connect((self.analog_quadrature_demod_cf_0, 0), (self.digital_clock_recovery_mm_xx_0, 0)) self.connect((self.analog_quadrature_demod_cf_0_0, 0), (self.dc_blocker_xx_0, 0)) self.connect((self.analog_quadrature_demod_cf_0_0, 0), (self.satnogs_ogg_encoder_0, 0)) + self.connect((self.analog_quadrature_demod_cf_0_0_0_0, 0), (self.blocks_moving_average_xx_0, 0)) self.connect((self.analog_sig_source_x_0, 0), (self.blocks_multiply_xx_0, 1)) + self.connect((self.blocks_delay_0, 0), (self.blocks_multiply_xx_0_0, 0)) self.connect((self.blocks_float_to_complex_0, 0), (self.blocks_multiply_xx_0, 0)) + self.connect((self.blocks_moving_average_xx_0, 0), (self.blocks_vco_c_0, 0)) self.connect((self.blocks_multiply_xx_0, 0), (self.low_pass_filter_1, 0)) + self.connect((self.blocks_multiply_xx_0_0, 0), (self.low_pass_filter_0, 0)) self.connect((self.blocks_rotator_cc_0, 0), (self.satnogs_coarse_doppler_correction_cc_0, 0)) + self.connect((self.blocks_vco_c_0, 0), (self.blocks_multiply_xx_0_0, 1)) self.connect((self.dc_blocker_xx_0, 0), (self.blocks_float_to_complex_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self.satnogs_ax25_decoder_bm_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self.satnogs_ax25_decoder_bm_0_0, 0)) - self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.satnogs_quad_demod_filter_ff_0, 0)) + self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.digital_binary_slicer_fb_0, 0)) self.connect((self.low_pass_filter_0, 0), (self.analog_quadrature_demod_cf_0_0, 0)) self.connect((self.low_pass_filter_1, 0), (self.analog_quadrature_demod_cf_0, 0)) self.connect((self.osmosdr_source_0, 0), (self.blocks_rotator_cc_0, 0)) - self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.low_pass_filter_0, 0)) + self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.analog_quadrature_demod_cf_0_0_0_0, 0)) + self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.blocks_delay_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.satnogs_iq_sink_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.satnogs_waterfall_sink_0, 0)) self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.pfb_arb_resampler_xxx_0, 0)) - self.connect((self.satnogs_quad_demod_filter_ff_0, 0), (self.digital_binary_slicer_fb_0, 0)) def get_antenna(self): return self.antenna diff --git a/apps/flowgraphs/satnogs_fsk_ax25.py b/apps/flowgraphs/satnogs_fsk_ax25.py index acdef68..1649c74 100755 --- a/apps/flowgraphs/satnogs_fsk_ax25.py +++ b/apps/flowgraphs/satnogs_fsk_ax25.py @@ -5,9 +5,10 @@ # Title: satnogs_fsk_ax25 # Author: Manolis Surligas (surligas@gmail.com) # Description: Generic FSK AX.25 decoder -# Generated: Sun Jan 6 14:19:34 2019 +# GNU Radio version: 3.7.13.5 ################################################## + from gnuradio import analog from gnuradio import blocks from gnuradio import digital @@ -64,7 +65,6 @@ class satnogs_fsk_ax25(gr.top_block): self.satnogs_waterfall_sink_0 = satnogs.waterfall_sink(audio_samp_rate, 0.0, 10, 1024, waterfall_file_path, 1) self.satnogs_udp_msg_sink_0_0 = satnogs.udp_msg_sink(udp_IP, udp_port, 1500) self.satnogs_tcp_rigctl_msg_source_0 = satnogs.tcp_rigctl_msg_source("127.0.0.1", rigctl_port, False, 1000, 1500) - self.satnogs_quad_demod_filter_ff_0 = satnogs.quad_demod_filter_ff(1.2) self.satnogs_ogg_encoder_0 = satnogs.ogg_encoder(file_path, audio_samp_rate, 1.0) self.satnogs_iq_sink_0 = satnogs.iq_sink(16768, iq_file_path, False, enable_iq_dump) self.satnogs_frame_file_sink_0_1_0 = satnogs.frame_file_sink(decoded_data_file_path, 0) @@ -72,7 +72,7 @@ class satnogs_fsk_ax25(gr.top_block): self.satnogs_ax25_decoder_bm_0_0 = satnogs.ax25_decoder_bm('GND', 0, True, False, 1024) self.satnogs_ax25_decoder_bm_0 = satnogs.ax25_decoder_bm('GND', 0, True, True, 1024) self.pfb_arb_resampler_xxx_0_0 = pfb.arb_resampler_ccf( - (4.0*baudrate)/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx), + (2.0*baudrate)/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx), taps=None, flt_size=32) self.pfb_arb_resampler_xxx_0_0.declare_sample_delay(0) @@ -97,12 +97,17 @@ class satnogs_fsk_ax25(gr.top_block): self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx), 0) self.low_pass_filter_0 = filter.fir_filter_ccf(1, firdes.low_pass( - 1, 4.0 * baudrate, baudrate / 2 + 1500, 1000, firdes.WIN_HAMMING, 6.76)) - self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(4, 0.25*0.175*0.175, 0.5, 0.175, 0.005) + 1, 2.0 * baudrate, (baudrate / 2) + 1500, 1000, firdes.WIN_HAMMING, 6.76)) + self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(2, 0.25*0.175*0.175, 0.5, 0.175, 0.005) self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb() self.dc_blocker_xx_0_0 = filter.dc_blocker_ff(1024, True) self.dc_blocker_xx_0 = filter.dc_blocker_ff(1024, True) + self.blocks_vco_c_0 = blocks.vco_c(audio_samp_rate, -audio_samp_rate, 1.0) self.blocks_rotator_cc_0 = blocks.rotator_cc(-2.0 * math.pi * (lo_offset / satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx))) + self.blocks_multiply_xx_0 = blocks.multiply_vcc(1) + self.blocks_moving_average_xx_0 = blocks.moving_average_ff(1024, 1.0/1024.0, 4096, 1) + self.blocks_delay_0 = blocks.delay(gr.sizeof_gr_complex*1, 1024/2) + self.analog_quadrature_demod_cf_0_0_0_0 = analog.quadrature_demod_cf(1.0) self.analog_quadrature_demod_cf_0_0_0 = analog.quadrature_demod_cf(0.9) self.analog_quadrature_demod_cf_0_0 = analog.quadrature_demod_cf(1.2) @@ -118,21 +123,26 @@ class satnogs_fsk_ax25(gr.top_block): self.msg_connect((self.satnogs_tcp_rigctl_msg_source_0, 'freq'), (self.satnogs_coarse_doppler_correction_cc_0, 'freq')) self.connect((self.analog_quadrature_demod_cf_0_0, 0), (self.dc_blocker_xx_0, 0)) self.connect((self.analog_quadrature_demod_cf_0_0_0, 0), (self.dc_blocker_xx_0_0, 0)) + self.connect((self.analog_quadrature_demod_cf_0_0_0_0, 0), (self.blocks_moving_average_xx_0, 0)) + self.connect((self.blocks_delay_0, 0), (self.blocks_multiply_xx_0, 0)) + self.connect((self.blocks_moving_average_xx_0, 0), (self.blocks_vco_c_0, 0)) + self.connect((self.blocks_multiply_xx_0, 0), (self.pfb_arb_resampler_xxx_0_0, 0)) self.connect((self.blocks_rotator_cc_0, 0), (self.satnogs_coarse_doppler_correction_cc_0, 0)) + self.connect((self.blocks_vco_c_0, 0), (self.blocks_multiply_xx_0, 1)) self.connect((self.dc_blocker_xx_0, 0), (self.digital_clock_recovery_mm_xx_0, 0)) self.connect((self.dc_blocker_xx_0_0, 0), (self.satnogs_ogg_encoder_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self.satnogs_ax25_decoder_bm_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self.satnogs_ax25_decoder_bm_0_0, 0)) - self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.satnogs_quad_demod_filter_ff_0, 0)) + self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.digital_binary_slicer_fb_0, 0)) self.connect((self.low_pass_filter_0, 0), (self.analog_quadrature_demod_cf_0_0, 0)) self.connect((self.osmosdr_source_0, 0), (self.blocks_rotator_cc_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.analog_quadrature_demod_cf_0_0_0, 0)) + self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.analog_quadrature_demod_cf_0_0_0_0, 0)) + self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.blocks_delay_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.satnogs_iq_sink_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.satnogs_waterfall_sink_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0_0, 0), (self.low_pass_filter_0, 0)) self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.pfb_arb_resampler_xxx_0, 0)) - self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.pfb_arb_resampler_xxx_0_0, 0)) - self.connect((self.satnogs_quad_demod_filter_ff_0, 0), (self.digital_binary_slicer_fb_0, 0)) def get_antenna(self): return self.antenna @@ -146,8 +156,8 @@ class satnogs_fsk_ax25(gr.top_block): def set_baudrate(self, baudrate): self.baudrate = baudrate - self.pfb_arb_resampler_xxx_0_0.set_rate((4.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) - self.low_pass_filter_0.set_taps(firdes.low_pass(1, 4.0 * self.baudrate, self.baudrate / 2 + 1500, 1000, firdes.WIN_HAMMING, 6.76)) + self.pfb_arb_resampler_xxx_0_0.set_rate((2.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) + self.low_pass_filter_0.set_taps(firdes.low_pass(1, 2.0 * self.baudrate, (self.baudrate / 2) + 1500, 1000, firdes.WIN_HAMMING, 6.76)) def get_bb_gain(self): return self.bb_gain @@ -240,7 +250,7 @@ class satnogs_fsk_ax25(gr.top_block): def set_rx_sdr_device(self, rx_sdr_device): self.rx_sdr_device = rx_sdr_device - self.pfb_arb_resampler_xxx_0_0.set_rate((4.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) + self.pfb_arb_resampler_xxx_0_0.set_rate((2.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.osmosdr_source_0.set_sample_rate(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.osmosdr_source_0.set_gain(satnogs.handle_rx_rf_gain(self.rx_sdr_device, self.rf_gain), 0) @@ -255,7 +265,7 @@ class satnogs_fsk_ax25(gr.top_block): def set_samp_rate_rx(self, samp_rate_rx): self.samp_rate_rx = samp_rate_rx - self.pfb_arb_resampler_xxx_0_0.set_rate((4.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) + self.pfb_arb_resampler_xxx_0_0.set_rate((2.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.osmosdr_source_0.set_sample_rate(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx), 0) diff --git a/apps/flowgraphs/satnogs_msk_ax25.py b/apps/flowgraphs/satnogs_msk_ax25.py index 7d12bf6..1b862db 100755 --- a/apps/flowgraphs/satnogs_msk_ax25.py +++ b/apps/flowgraphs/satnogs_msk_ax25.py @@ -5,9 +5,10 @@ # Title: satnogs_msk_ax25 # Author: Manolis Surligas (surligas@gmail.com) # Description: Generic MSK AX.25 decoder -# Generated: Sun Jan 6 14:17:55 2019 +# GNU Radio version: 3.7.13.5 ################################################## + from gnuradio import analog from gnuradio import blocks from gnuradio import digital @@ -64,7 +65,6 @@ class satnogs_msk_ax25(gr.top_block): self.satnogs_waterfall_sink_0 = satnogs.waterfall_sink(audio_samp_rate, 0.0, 10, 1024, waterfall_file_path, 1) self.satnogs_udp_msg_sink_0_0 = satnogs.udp_msg_sink(udp_IP, udp_port, 1500) self.satnogs_tcp_rigctl_msg_source_0 = satnogs.tcp_rigctl_msg_source("127.0.0.1", rigctl_port, False, 1000, 1500) - self.satnogs_quad_demod_filter_ff_0 = satnogs.quad_demod_filter_ff(1.2) self.satnogs_ogg_encoder_0 = satnogs.ogg_encoder(file_path, audio_samp_rate, 1.0) self.satnogs_iq_sink_0 = satnogs.iq_sink(16768, iq_file_path, False, enable_iq_dump) self.satnogs_frame_file_sink_0_1_0 = satnogs.frame_file_sink(decoded_data_file_path, 0) @@ -72,7 +72,7 @@ class satnogs_msk_ax25(gr.top_block): self.satnogs_ax25_decoder_bm_0_0 = satnogs.ax25_decoder_bm('GND', 0, True, False, 1024) self.satnogs_ax25_decoder_bm_0 = satnogs.ax25_decoder_bm('GND', 0, True, True, 1024) self.pfb_arb_resampler_xxx_0_0_0 = pfb.arb_resampler_ccf( - (4.0*baudrate)/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx), + (2.0*baudrate)/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx), taps=None, flt_size=32) self.pfb_arb_resampler_xxx_0_0_0.declare_sample_delay(0) @@ -97,12 +97,17 @@ class satnogs_msk_ax25(gr.top_block): self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx), 0) self.low_pass_filter_0 = filter.fir_filter_ccf(1, firdes.low_pass( - 1, 4.0 * baudrate, baudrate / 2 + 1500, 1000, firdes.WIN_HAMMING, 6.76)) - self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(4, 0.25*0.175*0.175, 0.5, 0.175, 0.005) + 1, 2.0 * baudrate, baudrate / 2 + 1500, 1000, firdes.WIN_HAMMING, 6.76)) + self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(2, 0.25*0.175*0.175, 0.5, 0.175, 0.005) self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb() self.dc_blocker_xx_0_0 = filter.dc_blocker_ff(1024, True) self.dc_blocker_xx_0 = filter.dc_blocker_ff(1024, True) + self.blocks_vco_c_0 = blocks.vco_c(audio_samp_rate, -audio_samp_rate, 1.0) self.blocks_rotator_cc_0 = blocks.rotator_cc(-2.0 * math.pi * (lo_offset / satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx))) + self.blocks_multiply_xx_0 = blocks.multiply_vcc(1) + self.blocks_moving_average_xx_0 = blocks.moving_average_ff(1024, 1.0/1024.0, 4096, 1) + self.blocks_delay_0 = blocks.delay(gr.sizeof_gr_complex*1, 1024/2) + self.analog_quadrature_demod_cf_0_0_0_0 = analog.quadrature_demod_cf(1.0) self.analog_quadrature_demod_cf_0_0_0 = analog.quadrature_demod_cf(0.9) self.analog_quadrature_demod_cf_0_0 = analog.quadrature_demod_cf(1.2) @@ -118,21 +123,26 @@ class satnogs_msk_ax25(gr.top_block): self.msg_connect((self.satnogs_tcp_rigctl_msg_source_0, 'freq'), (self.satnogs_coarse_doppler_correction_cc_0, 'freq')) self.connect((self.analog_quadrature_demod_cf_0_0, 0), (self.dc_blocker_xx_0, 0)) self.connect((self.analog_quadrature_demod_cf_0_0_0, 0), (self.dc_blocker_xx_0_0, 0)) + self.connect((self.analog_quadrature_demod_cf_0_0_0_0, 0), (self.blocks_moving_average_xx_0, 0)) + self.connect((self.blocks_delay_0, 0), (self.blocks_multiply_xx_0, 0)) + self.connect((self.blocks_moving_average_xx_0, 0), (self.blocks_vco_c_0, 0)) + self.connect((self.blocks_multiply_xx_0, 0), (self.pfb_arb_resampler_xxx_0_0_0, 0)) self.connect((self.blocks_rotator_cc_0, 0), (self.satnogs_coarse_doppler_correction_cc_0, 0)) + self.connect((self.blocks_vco_c_0, 0), (self.blocks_multiply_xx_0, 1)) self.connect((self.dc_blocker_xx_0, 0), (self.digital_clock_recovery_mm_xx_0, 0)) self.connect((self.dc_blocker_xx_0_0, 0), (self.satnogs_ogg_encoder_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self.satnogs_ax25_decoder_bm_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self.satnogs_ax25_decoder_bm_0_0, 0)) - self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.satnogs_quad_demod_filter_ff_0, 0)) + self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.digital_binary_slicer_fb_0, 0)) self.connect((self.low_pass_filter_0, 0), (self.analog_quadrature_demod_cf_0_0, 0)) self.connect((self.osmosdr_source_0, 0), (self.blocks_rotator_cc_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.analog_quadrature_demod_cf_0_0_0, 0)) + self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.analog_quadrature_demod_cf_0_0_0_0, 0)) + self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.blocks_delay_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.satnogs_iq_sink_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.satnogs_waterfall_sink_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0_0_0, 0), (self.low_pass_filter_0, 0)) self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.pfb_arb_resampler_xxx_0, 0)) - self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.pfb_arb_resampler_xxx_0_0_0, 0)) - self.connect((self.satnogs_quad_demod_filter_ff_0, 0), (self.digital_binary_slicer_fb_0, 0)) def get_antenna(self): return self.antenna @@ -146,8 +156,8 @@ class satnogs_msk_ax25(gr.top_block): def set_baudrate(self, baudrate): self.baudrate = baudrate - self.pfb_arb_resampler_xxx_0_0_0.set_rate((4.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) - self.low_pass_filter_0.set_taps(firdes.low_pass(1, 4.0 * self.baudrate, self.baudrate / 2 + 1500, 1000, firdes.WIN_HAMMING, 6.76)) + self.pfb_arb_resampler_xxx_0_0_0.set_rate((2.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) + self.low_pass_filter_0.set_taps(firdes.low_pass(1, 2.0 * self.baudrate, self.baudrate / 2 + 1500, 1000, firdes.WIN_HAMMING, 6.76)) def get_bb_gain(self): return self.bb_gain @@ -240,7 +250,7 @@ class satnogs_msk_ax25(gr.top_block): def set_rx_sdr_device(self, rx_sdr_device): self.rx_sdr_device = rx_sdr_device - self.pfb_arb_resampler_xxx_0_0_0.set_rate((4.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) + self.pfb_arb_resampler_xxx_0_0_0.set_rate((2.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.osmosdr_source_0.set_sample_rate(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.osmosdr_source_0.set_gain(satnogs.handle_rx_rf_gain(self.rx_sdr_device, self.rf_gain), 0) @@ -255,7 +265,7 @@ class satnogs_msk_ax25(gr.top_block): def set_samp_rate_rx(self, samp_rate_rx): self.samp_rate_rx = samp_rate_rx - self.pfb_arb_resampler_xxx_0_0_0.set_rate((4.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) + self.pfb_arb_resampler_xxx_0_0_0.set_rate((2.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.osmosdr_source_0.set_sample_rate(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx), 0) From e6ac68789133c5c6b19f0a9f0046630261943030 Mon Sep 17 00:00:00 2001 From: Manolis Surligas Date: Wed, 3 Jul 2019 17:58:29 +0300 Subject: [PATCH 07/24] Manually remove the vector param Manually remove the vector param from the moving average block in the affected flowgraphs, for compatibility with the GNU Radio 3.7.10 --- apps/flowgraphs/satnogs_afsk1200_ax25.py | 2 +- apps/flowgraphs/satnogs_fsk_ax25.py | 2 +- apps/flowgraphs/satnogs_msk_ax25.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/flowgraphs/satnogs_afsk1200_ax25.py b/apps/flowgraphs/satnogs_afsk1200_ax25.py index 37b73e3..ba8c4e2 100755 --- a/apps/flowgraphs/satnogs_afsk1200_ax25.py +++ b/apps/flowgraphs/satnogs_afsk1200_ax25.py @@ -106,7 +106,7 @@ class satnogs_afsk1200_ax25(gr.top_block): self.blocks_rotator_cc_0 = blocks.rotator_cc(-2.0 * math.pi * (lo_offset / satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx))) self.blocks_multiply_xx_0_0 = blocks.multiply_vcc(1) self.blocks_multiply_xx_0 = blocks.multiply_vcc(1) - self.blocks_moving_average_xx_0 = blocks.moving_average_ff(1024, 1.0/1024.0, 4096, 1) + self.blocks_moving_average_xx_0 = blocks.moving_average_ff(1024, 1.0/1024.0, 4096) self.blocks_float_to_complex_0 = blocks.float_to_complex(1) self.blocks_delay_0 = blocks.delay(gr.sizeof_gr_complex*1, 1024/2) self.analog_sig_source_x_0 = analog.sig_source_c(audio_samp_rate, analog.GR_COS_WAVE, -(1200 + 2200) / 2, 1, 0) diff --git a/apps/flowgraphs/satnogs_fsk_ax25.py b/apps/flowgraphs/satnogs_fsk_ax25.py index 1649c74..b00cafa 100755 --- a/apps/flowgraphs/satnogs_fsk_ax25.py +++ b/apps/flowgraphs/satnogs_fsk_ax25.py @@ -105,7 +105,7 @@ class satnogs_fsk_ax25(gr.top_block): self.blocks_vco_c_0 = blocks.vco_c(audio_samp_rate, -audio_samp_rate, 1.0) self.blocks_rotator_cc_0 = blocks.rotator_cc(-2.0 * math.pi * (lo_offset / satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx))) self.blocks_multiply_xx_0 = blocks.multiply_vcc(1) - self.blocks_moving_average_xx_0 = blocks.moving_average_ff(1024, 1.0/1024.0, 4096, 1) + self.blocks_moving_average_xx_0 = blocks.moving_average_ff(1024, 1.0/1024.0, 4096) self.blocks_delay_0 = blocks.delay(gr.sizeof_gr_complex*1, 1024/2) self.analog_quadrature_demod_cf_0_0_0_0 = analog.quadrature_demod_cf(1.0) self.analog_quadrature_demod_cf_0_0_0 = analog.quadrature_demod_cf(0.9) diff --git a/apps/flowgraphs/satnogs_msk_ax25.py b/apps/flowgraphs/satnogs_msk_ax25.py index 1b862db..c4bcc10 100755 --- a/apps/flowgraphs/satnogs_msk_ax25.py +++ b/apps/flowgraphs/satnogs_msk_ax25.py @@ -105,7 +105,7 @@ class satnogs_msk_ax25(gr.top_block): self.blocks_vco_c_0 = blocks.vco_c(audio_samp_rate, -audio_samp_rate, 1.0) self.blocks_rotator_cc_0 = blocks.rotator_cc(-2.0 * math.pi * (lo_offset / satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx))) self.blocks_multiply_xx_0 = blocks.multiply_vcc(1) - self.blocks_moving_average_xx_0 = blocks.moving_average_ff(1024, 1.0/1024.0, 4096, 1) + self.blocks_moving_average_xx_0 = blocks.moving_average_ff(1024, 1.0/1024.0, 4096) self.blocks_delay_0 = blocks.delay(gr.sizeof_gr_complex*1, 1024/2) self.analog_quadrature_demod_cf_0_0_0_0 = analog.quadrature_demod_cf(1.0) self.analog_quadrature_demod_cf_0_0_0 = analog.quadrature_demod_cf(0.9) From 6e996fc85ad2436cc95e0f1ff42db88d817842be Mon Sep 17 00:00:00 2001 From: Manolis Surligas Date: Thu, 4 Jul 2019 00:56:45 +0300 Subject: [PATCH 08/24] Add a DC blocker and remove filter gain at AFSK --- apps/flowgraphs/afsk1200_ax25.grc | 75 +++++++++++++++++++++--- apps/flowgraphs/satnogs_afsk1200_ax25.py | 24 ++++---- 2 files changed, 79 insertions(+), 20 deletions(-) diff --git a/apps/flowgraphs/afsk1200_ax25.grc b/apps/flowgraphs/afsk1200_ax25.grc index b25a62a..bcd80fd 100644 --- a/apps/flowgraphs/afsk1200_ax25.grc +++ b/apps/flowgraphs/afsk1200_ax25.grc @@ -217,7 +217,7 @@ _coordinate - (1364, 578) + (1168, 580) _rotation @@ -225,7 +225,7 @@ gain - ((audio_samp_rate/10) / baud_rate)/(math.pi*1) + ((audio_samp_rate/20) / baud_rate)/(math.pi*1) id @@ -354,7 +354,7 @@ _coordinate - (750, 646) + (664, 644) _rotation @@ -707,7 +707,7 @@ _coordinate - (957, 566) + (872, 568) _rotation @@ -934,6 +934,57 @@ ff + + dc_blocker_xx + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (1352, 572) + + + _rotation + 0 + + + id + dc_blocker_xx_0_0 + + + length + 1024 + + + long_form + True + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + type + ff + + parameter @@ -1123,7 +1174,7 @@ omega - (48e3/10)/baud_rate + (48e3/20)/baud_rate type @@ -1515,7 +1566,7 @@ max_modulation_freq = 3000 decim - 10 + 20 _enabled @@ -1527,7 +1578,7 @@ max_modulation_freq = 3000 _coordinate - (1152, 532) + (992, 532) _rotation @@ -1535,7 +1586,7 @@ max_modulation_freq = 3000 gain - 10 + 1 id @@ -4006,7 +4057,7 @@ max_modulation_freq = 3000 analog_quadrature_demod_cf_0 - digital_clock_recovery_mm_xx_0 + dc_blocker_xx_0_0 0 0 @@ -4082,6 +4133,12 @@ max_modulation_freq = 3000 0 0 + + dc_blocker_xx_0_0 + digital_clock_recovery_mm_xx_0 + 0 + 0 + digital_binary_slicer_fb_0 satnogs_ax25_decoder_bm_0 diff --git a/apps/flowgraphs/satnogs_afsk1200_ax25.py b/apps/flowgraphs/satnogs_afsk1200_ax25.py index ba8c4e2..5806bc8 100755 --- a/apps/flowgraphs/satnogs_afsk1200_ax25.py +++ b/apps/flowgraphs/satnogs_afsk1200_ax25.py @@ -95,12 +95,13 @@ class satnogs_afsk1200_ax25(gr.top_block): self.osmosdr_source_0.set_antenna(satnogs.handle_rx_antenna(rx_sdr_device, antenna), 0) self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx), 0) - self.low_pass_filter_1 = filter.fir_filter_ccf(10, firdes.low_pass( - 10, audio_samp_rate, (mark_frequency - space_frequency)/2.0, 1000, firdes.WIN_HAMMING, 6.76)) + self.low_pass_filter_1 = filter.fir_filter_ccf(20, firdes.low_pass( + 1, audio_samp_rate, (mark_frequency - space_frequency)/2.0, 1000, firdes.WIN_HAMMING, 6.76)) self.low_pass_filter_0 = filter.fir_filter_ccf(1, firdes.low_pass( 1, audio_samp_rate, deviation+max_modulation_freq, 3000, firdes.WIN_HAMMING, 6.76)) - self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff((48e3/10)/baud_rate, 0.25*0.175*0.175, 0.5, 0.175, 0.005) + self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff((48e3/20)/baud_rate, 0.25*0.175*0.175, 0.5, 0.175, 0.005) self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb() + self.dc_blocker_xx_0_0 = filter.dc_blocker_ff(1024, True) self.dc_blocker_xx_0 = filter.dc_blocker_ff(1024, True) self.blocks_vco_c_0 = blocks.vco_c(audio_samp_rate, -audio_samp_rate, 1.0) self.blocks_rotator_cc_0 = blocks.rotator_cc(-2.0 * math.pi * (lo_offset / satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx))) @@ -112,7 +113,7 @@ class satnogs_afsk1200_ax25(gr.top_block): self.analog_sig_source_x_0 = analog.sig_source_c(audio_samp_rate, analog.GR_COS_WAVE, -(1200 + 2200) / 2, 1, 0) self.analog_quadrature_demod_cf_0_0_0_0 = analog.quadrature_demod_cf(1.0) self.analog_quadrature_demod_cf_0_0 = analog.quadrature_demod_cf((2*math.pi*deviation)/audio_samp_rate) - self.analog_quadrature_demod_cf_0 = analog.quadrature_demod_cf(((audio_samp_rate/10) / baud_rate)/(math.pi*1)) + self.analog_quadrature_demod_cf_0 = analog.quadrature_demod_cf(((audio_samp_rate/20) / baud_rate)/(math.pi*1)) @@ -124,7 +125,7 @@ class satnogs_afsk1200_ax25(gr.top_block): self.msg_connect((self.satnogs_ax25_decoder_bm_0_0, 'pdu'), (self.satnogs_frame_file_sink_0_1_0, 'frame')) self.msg_connect((self.satnogs_ax25_decoder_bm_0_0, 'pdu'), (self.satnogs_udp_msg_sink_0_0, 'in')) self.msg_connect((self.satnogs_tcp_rigctl_msg_source_0, 'freq'), (self.satnogs_coarse_doppler_correction_cc_0, 'freq')) - self.connect((self.analog_quadrature_demod_cf_0, 0), (self.digital_clock_recovery_mm_xx_0, 0)) + self.connect((self.analog_quadrature_demod_cf_0, 0), (self.dc_blocker_xx_0_0, 0)) self.connect((self.analog_quadrature_demod_cf_0_0, 0), (self.dc_blocker_xx_0, 0)) self.connect((self.analog_quadrature_demod_cf_0_0, 0), (self.satnogs_ogg_encoder_0, 0)) self.connect((self.analog_quadrature_demod_cf_0_0_0_0, 0), (self.blocks_moving_average_xx_0, 0)) @@ -137,6 +138,7 @@ class satnogs_afsk1200_ax25(gr.top_block): self.connect((self.blocks_rotator_cc_0, 0), (self.satnogs_coarse_doppler_correction_cc_0, 0)) self.connect((self.blocks_vco_c_0, 0), (self.blocks_multiply_xx_0_0, 1)) self.connect((self.dc_blocker_xx_0, 0), (self.blocks_float_to_complex_0, 0)) + self.connect((self.dc_blocker_xx_0_0, 0), (self.digital_clock_recovery_mm_xx_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self.satnogs_ax25_decoder_bm_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self.satnogs_ax25_decoder_bm_0_0, 0)) self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.digital_binary_slicer_fb_0, 0)) @@ -225,7 +227,7 @@ class satnogs_afsk1200_ax25(gr.top_block): def set_mark_frequency(self, mark_frequency): self.mark_frequency = mark_frequency - self.low_pass_filter_1.set_taps(firdes.low_pass(10, self.audio_samp_rate, (self.mark_frequency - self.space_frequency)/2.0, 1000, firdes.WIN_HAMMING, 6.76)) + self.low_pass_filter_1.set_taps(firdes.low_pass(1, self.audio_samp_rate, (self.mark_frequency - self.space_frequency)/2.0, 1000, firdes.WIN_HAMMING, 6.76)) def get_ppm(self): return self.ppm @@ -284,7 +286,7 @@ class satnogs_afsk1200_ax25(gr.top_block): def set_space_frequency(self, space_frequency): self.space_frequency = space_frequency - self.low_pass_filter_1.set_taps(firdes.low_pass(10, self.audio_samp_rate, (self.mark_frequency - self.space_frequency)/2.0, 1000, firdes.WIN_HAMMING, 6.76)) + self.low_pass_filter_1.set_taps(firdes.low_pass(1, self.audio_samp_rate, (self.mark_frequency - self.space_frequency)/2.0, 1000, firdes.WIN_HAMMING, 6.76)) def get_udp_IP(self): return self.udp_IP @@ -324,8 +326,8 @@ class satnogs_afsk1200_ax25(gr.top_block): def set_baud_rate(self, baud_rate): self.baud_rate = baud_rate - self.digital_clock_recovery_mm_xx_0.set_omega((48e3/10)/self.baud_rate) - self.analog_quadrature_demod_cf_0.set_gain(((self.audio_samp_rate/10) / self.baud_rate)/(math.pi*1)) + self.digital_clock_recovery_mm_xx_0.set_omega((48e3/20)/self.baud_rate) + self.analog_quadrature_demod_cf_0.set_gain(((self.audio_samp_rate/20) / self.baud_rate)/(math.pi*1)) def get_audio_samp_rate(self): return self.audio_samp_rate @@ -333,11 +335,11 @@ class satnogs_afsk1200_ax25(gr.top_block): def set_audio_samp_rate(self, audio_samp_rate): self.audio_samp_rate = audio_samp_rate self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) - self.low_pass_filter_1.set_taps(firdes.low_pass(10, self.audio_samp_rate, (self.mark_frequency - self.space_frequency)/2.0, 1000, firdes.WIN_HAMMING, 6.76)) + self.low_pass_filter_1.set_taps(firdes.low_pass(1, self.audio_samp_rate, (self.mark_frequency - self.space_frequency)/2.0, 1000, firdes.WIN_HAMMING, 6.76)) self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, self.deviation+self.max_modulation_freq, 3000, firdes.WIN_HAMMING, 6.76)) self.analog_sig_source_x_0.set_sampling_freq(self.audio_samp_rate) self.analog_quadrature_demod_cf_0_0.set_gain((2*math.pi*self.deviation)/self.audio_samp_rate) - self.analog_quadrature_demod_cf_0.set_gain(((self.audio_samp_rate/10) / self.baud_rate)/(math.pi*1)) + self.analog_quadrature_demod_cf_0.set_gain(((self.audio_samp_rate/20) / self.baud_rate)/(math.pi*1)) def argument_parser(): From 767e4e3d3834a094e8553edd8446e498369be9f2 Mon Sep 17 00:00:00 2001 From: Manolis Surligas Date: Thu, 18 Jul 2019 16:39:26 +0300 Subject: [PATCH 09/24] Redesign of the AX.25 decoder This commits introduces a significant redesign of the AX.25 decoding block. Due to the poor AX.25 sync flag, the decoders exhibited too many false alarms. To deal with this problem, we introduced the quadrature demod filter block, that tried to measure the SNR based on the running variance of the signal. The problem with that was that the user should have to fine tune two parameters, the one related with the amplitude of the incoming signal and the second one related with the window that the calculations should take place. This solution worked until now, but we can always increase the performance. The new AX.25 decoder stores the bitstream in a queue and always tries to exlpoit possible valid frames in the queue. If now sync flags have been encountered, the queue is flushed. After a valid frame extraction, bits corresponding to this frame are also deleted from the queue. This technique requires more memory and CPU, but it increases a lot the decoding performance. --- include/satnogs/ax25.h | 5 +- lib/ax25_decoder_bm_impl.cc | 651 +++++++++++++++--------------------- lib/ax25_decoder_bm_impl.h | 17 +- 3 files changed, 285 insertions(+), 388 deletions(-) diff --git a/include/satnogs/ax25.h b/include/satnogs/ax25.h index 1c0d543..9971c72 100644 --- a/include/satnogs/ax25.h +++ b/include/satnogs/ax25.h @@ -197,7 +197,10 @@ namespace gr out[i++] = fcs & 0xFF; out[i++] = (fcs >> 8) & 0xFF; memset (out + i, AX25_SYNC_FLAG, postamble_len); - + for(size_t j = preamble_len; j < i; j++) { + printf("0x%02x ", out[j]); + } + printf("\n"); return i + postamble_len; } diff --git a/lib/ax25_decoder_bm_impl.cc b/lib/ax25_decoder_bm_impl.cc index 0cc1250..2dd8b2a 100644 --- a/lib/ax25_decoder_bm_impl.cc +++ b/lib/ax25_decoder_bm_impl.cc @@ -30,406 +30,299 @@ namespace gr { - namespace satnogs - { +namespace satnogs +{ - ax25_decoder_bm::sptr - ax25_decoder_bm::make (const std::string& addr, uint8_t ssid, bool promisc, - bool descramble, size_t max_frame_len) - { - return gnuradio::get_initial_sptr ( - new ax25_decoder_bm_impl (addr, ssid, promisc, descramble, - max_frame_len)); - } +ax25_decoder_bm::sptr +ax25_decoder_bm::make (const std::string &addr, uint8_t ssid, bool promisc, + bool descramble, size_t max_frame_len) +{ + return gnuradio::get_initial_sptr ( + new ax25_decoder_bm_impl (addr, ssid, promisc, descramble, max_frame_len)); +} - /* - * The private constructor - */ - ax25_decoder_bm_impl::ax25_decoder_bm_impl (const std::string& addr, - uint8_t ssid, bool promisc, - bool descramble, - size_t max_frame_len) : - gr::sync_block ("ax25_decoder_bm", - gr::io_signature::make (1, 1, sizeof(uint8_t)), - gr::io_signature::make (0, 0, 0)), - d_promisc (promisc), - d_descramble (descramble), - d_max_frame_len (max_frame_len), - d_state (NO_SYNC), - d_shift_reg (0x0), - d_dec_b (0x0), - d_prev_bit_nrzi (0), - d_received_bytes (0), - d_decoded_bits (0), - d_lfsr (0x21, 0x0, 16), - d_frame_buffer ( - new uint8_t[max_frame_len + AX25_MAX_ADDR_LEN - + AX25_MAX_CTRL_LEN + sizeof(uint16_t)]) - { - /* Valid PDUs output message port */ - message_port_register_out (pmt::mp ("pdu")); - /* - * Valid invalid (wrong CRC, different destination Callsign/SSID, - * wrong frame size)PDUs output message port - */ - message_port_register_out (pmt::mp ("failed_pdu")); - } +/* + * The private constructor + */ +ax25_decoder_bm_impl::ax25_decoder_bm_impl (const std::string &addr, + uint8_t ssid, bool promisc, + bool descramble, + size_t max_frame_len) : + gr::sync_block ("ax25_decoder_bm", + gr::io_signature::make (1, 1, sizeof(uint8_t)), + gr::io_signature::make (0, 0, 0)), + d_promisc (promisc), + d_descramble (descramble), + d_max_frame_len (max_frame_len), + d_state (NO_SYNC), + d_shift_reg (0x0), + d_dec_b (0x0), + d_prev_bit_nrzi (0), + d_received_bytes (0), + d_decoded_bits (0), + d_lfsr (0x21, 0x0, 16), + d_frame_buffer ( + new uint8_t[max_frame_len + AX25_MAX_ADDR_LEN + AX25_MAX_CTRL_LEN + + sizeof(uint16_t)]), + d_start_idx(0) +{ + /* Valid PDUs output message port */ + message_port_register_out (pmt::mp ("pdu")); + /* + * Valid invalid (wrong CRC, different destination Callsign/SSID, + * wrong frame size)PDUs output message port + */ + message_port_register_out (pmt::mp ("failed_pdu")); +} - size_t - ax25_decoder_bm_impl::descramble_and_decode (const uint8_t* in, - size_t nitems) - { - size_t i; - switch (d_state) - { - case NO_SYNC: - for (i = 0; i < nitems; i++) { - descramble_and_decode_1b (in[i]); - if (d_shift_reg == AX25_SYNC_FLAG) { - enter_sync_state (); - return i + 1; - } - } - return nitems; - case IN_SYNC: - /* - * Most of the transmitters repeat several times the AX.25 SYNC - * In case of G3RUH this is mandatory to allow the self synchronizing - * scrambler to settle - */ - for (i = 0; i < nitems; i++) { - descramble_and_decode_1b (in[i]); - d_decoded_bits++; - if(d_decoded_bits == 8) { - /* Perhaps we are in frame! */ - if(d_shift_reg != AX25_SYNC_FLAG) { - enter_decoding_state(); - return i+1; - } - d_decoded_bits = 0; - } - } - return nitems; - case DECODING: - for (i = 0; i < nitems; i++) { - descramble_and_decode_1b (in[i]); - if (d_shift_reg == AX25_SYNC_FLAG) { - LOG_DEBUG("Found frame end"); - enter_frame_end(); - return i+1; - } - else if ((d_shift_reg & 0xfc) == 0x7c) { - /*This was a stuffed bit */ - d_dec_b <<= 1; - } - else if((d_shift_reg & 0xfe) == 0xfe) { - LOG_DEBUG("Invalid shift register value %u", d_received_bytes); - reset_state (); - return i+1; - } - else{ - d_decoded_bits++; - if(d_decoded_bits == 8) { - d_frame_buffer[d_received_bytes] = d_dec_b; - d_received_bytes++; - d_decoded_bits = 0; - /*Check if the frame limit was reached */ - if (d_received_bytes >= d_max_frame_len) { - LOG_DEBUG("Wrong size"); - message_port_pub ( - pmt::mp ("failed_pdu"), - pmt::make_blob (d_frame_buffer, d_max_frame_len)); - reset_state (); - return i+1; - } - } - } +void +ax25_decoder_bm_impl::decode () +{ + while (1) { + bool cont = false; + switch (d_state) + { + case NO_SYNC: + for (size_t i = 0; i < d_bitstream.size (); i++) { + decode_1b (d_bitstream[i]); + if (d_shift_reg == AX25_SYNC_FLAG) { + d_bitstream.erase (d_bitstream.begin (), + d_bitstream.begin () + i + 1); + enter_sync_state (); + d_start_idx = 0; + cont = true; + break; } - return nitems; - case FRAME_END: - for (i = 0; i < nitems; i++) { - descramble_and_decode_1b (in[i]); - d_decoded_bits++; - if (d_decoded_bits == 8) { - /* Repetitions of the trailing SYNC flag finished */ - if (d_shift_reg != AX25_SYNC_FLAG) { - reset_state(); - return i + 1; - } - d_decoded_bits = 0; - } - } - return nitems; - default: - LOG_ERROR("Invalid decoding state"); - reset_state(); - return nitems; } - } - - size_t - ax25_decoder_bm_impl::decode (const uint8_t* in, size_t nitems) - { - size_t i; - switch (d_state) - { - case NO_SYNC: - for (i = 0; i < nitems; i++) { - decode_1b (in[i]); - if (d_shift_reg == AX25_SYNC_FLAG) { - enter_sync_state (); - return i + 1; - } - } - return nitems; - case IN_SYNC: - /* - * Most of the transmitters repeat several times the AX.25 SYNC - * In case of G3RUH this is mandatory to allow the self synchronizing - * scrambler to settle - */ - for (i = 0; i < nitems; i++) { - decode_1b (in[i]); - d_decoded_bits++; - if (d_decoded_bits == 8) { - /* Perhaps we are in frame! */ - if (d_shift_reg != AX25_SYNC_FLAG) { - enter_decoding_state (); - return i + 1; - } - d_decoded_bits = 0; - } - } - return nitems; - case DECODING: - for (i = 0; i < nitems; i++) { - decode_1b (in[i]); - if (d_shift_reg == AX25_SYNC_FLAG) { - enter_frame_end (); - return i + 1; - } - else if ((d_shift_reg & 0xfc) == 0x7c) { - /*This was a stuffed bit */ - d_dec_b <<= 1; - } - else if ((d_shift_reg & 0xfe) == 0xfe) { - LOG_DEBUG("Invalid shift register value"); - reset_state (); - return i + 1; - } - else { - d_decoded_bits++; - if (d_decoded_bits == 8) { - d_frame_buffer[d_received_bytes] = d_dec_b; - d_received_bytes++; - d_decoded_bits = 0; - - /*Check if the frame limit was reached */ - if (d_received_bytes >= d_max_frame_len) { - LOG_DEBUG("Wrong size"); - message_port_pub ( - pmt::mp ("failed_pdu"), - pmt::make_blob (d_frame_buffer, d_max_frame_len)); - reset_state (); - return i + 1; - } - } - } - } - return nitems; - case FRAME_END: - for (i = 0; i < nitems; i++) { - decode_1b (in[i]); - d_decoded_bits++; - if (d_decoded_bits == 8) { - /* Repetitions of the trailing SYNC flag finished */ - if (d_shift_reg != AX25_SYNC_FLAG) { - reset_state (); - return i + 1; - } - d_decoded_bits = 0; - } - } - return nitems; - default: - LOG_ERROR("Invalid decoding state"); - reset_state (); - return nitems; + if(cont) { + continue; } - } - - /* - * Our virtual destructor. - */ - ax25_decoder_bm_impl::~ax25_decoder_bm_impl () - { - delete [] d_frame_buffer; - } - - void - ax25_decoder_bm_impl::reset_state () - { - d_state = NO_SYNC; - d_dec_b = 0x0; - d_shift_reg = 0x0; - d_decoded_bits = 0; - d_received_bytes = 0; - d_prev_bit_nrzi = 0; - } - - void - ax25_decoder_bm_impl::enter_sync_state () - { - d_state = IN_SYNC; - d_dec_b = 0x0; - d_shift_reg = 0x0; - d_decoded_bits = 0; - d_received_bytes = 0; - } - - void - ax25_decoder_bm_impl::enter_decoding_state () - { - uint8_t tmp; - d_state = DECODING; - d_decoded_bits = 0; - d_shift_reg = 0x0; - - /* - * Due to the possibility of bit stuffing on the first byte some special - * handling is necessary - */ - tmp = d_dec_b; - d_dec_b = 0x0; - for (size_t i = 0; i < 8; i++) { - d_shift_reg = (d_shift_reg >> 1) | (((tmp >> i) & 0x1) << 7); - d_dec_b = (d_dec_b >> 1) | (((tmp >> i) & 0x1) << 7); - if ((d_shift_reg & 0xfc) == 0x7c) { - /*This was a stuffed bit */ - d_dec_b <<= 1; - } - else{ + d_bitstream.clear (); + return; + case IN_SYNC: + /* + * Most of the transmitters repeat several times the AX.25 SYNC + * In case of G3RUH this is mandatory to allow the self synchronizing + * scrambler to settle + */ + for (size_t i = d_start_idx; i < d_bitstream.size (); i++) { + decode_1b (d_bitstream[i]); d_decoded_bits++; + if (d_decoded_bits == 8) { + /* Perhaps we are in frame! */ + if (d_shift_reg != AX25_SYNC_FLAG) { + d_start_idx = i + 1; + enter_decoding_state (); + cont = true; + break; + } + d_decoded_bits = 0; + } } - } + if(cont) { + continue; + } + d_start_idx = d_bitstream.size (); + return; + case DECODING: + for (size_t i = d_start_idx; i < d_bitstream.size (); i++) { + decode_1b (d_bitstream[i]); + if (d_shift_reg == AX25_SYNC_FLAG) { + LOG_DEBUG("Found frame end"); + if (enter_frame_end ()) { + d_bitstream.erase (d_bitstream.begin (), + d_bitstream.begin () + i + 1); + } + cont = true; + break; + } + else if ((d_shift_reg & 0xfc) == 0x7c) { + /*This was a stuffed bit */ + d_dec_b <<= 1; + } + else if ((d_shift_reg & 0xfe) == 0xfe) { + LOG_DEBUG("Invalid shift register value %u", d_received_bytes); + reset_state (); + cont = true; + break; + } + else { + d_decoded_bits++; + if (d_decoded_bits == 8) { + d_frame_buffer[d_received_bytes++] = d_dec_b; + d_decoded_bits = 0; - if(d_decoded_bits == 8) { - d_frame_buffer[0] = d_dec_b; - d_decoded_bits = 0; - d_received_bytes = 1; - } - else { - d_received_bytes = 0; - } - - } - - void - ax25_decoder_bm_impl::enter_frame_end () - { - uint16_t fcs; - uint16_t recv_fcs = 0x0; - - /* First check if the size of the frame is valid */ - if (d_received_bytes < AX25_MIN_ADDR_LEN + sizeof(uint16_t)) { - d_dec_b = 0x0; - d_shift_reg = 0x0; - d_decoded_bits = 0; - d_received_bytes = 0; - d_state = FRAME_END; + /*Check if the frame limit was reached */ + if (d_received_bytes >= d_max_frame_len) { + LOG_DEBUG("Wrong size"); + reset_state (); + cont = true; + break; + } + } + } + } + if(cont) { + continue; + } + d_start_idx = d_bitstream.size (); + return; + default: + LOG_ERROR("Invalid decoding state"); + reset_state (); return; } + } +} - /* Check if the frame is correct using the FCS field */ - fcs = ax25_fcs (d_frame_buffer, d_received_bytes - sizeof(uint16_t)); - recv_fcs = (((uint16_t) d_frame_buffer[d_received_bytes - 1]) << 8) - | d_frame_buffer[d_received_bytes - 2]; +/* + * Our virtual destructor. + */ +ax25_decoder_bm_impl::~ax25_decoder_bm_impl () +{ + delete[] d_frame_buffer; + LOG_DEBUG("Left over: %lu", d_bitstream.size()); +} - if (fcs == recv_fcs) { - message_port_pub ( - pmt::mp ("pdu"), - pmt::make_blob (d_frame_buffer, - d_received_bytes - sizeof(uint16_t))); - } - else { - message_port_pub ( - pmt::mp ("failed_pdu"), - pmt::make_blob (d_frame_buffer, - d_received_bytes - sizeof(uint16_t))); - LOG_DEBUG("Wrong crc"); - } - d_dec_b = 0x0; - d_shift_reg = 0x0; - d_decoded_bits = 0; - d_received_bytes = 0; - d_state = FRAME_END; - } +void +ax25_decoder_bm_impl::reset_state () +{ + d_state = NO_SYNC; + d_dec_b = 0x0; + d_shift_reg = 0x0; + d_decoded_bits = 0; + d_received_bytes = 0; +} - /** - * Performs descrambling and NRZI decoding of an input bit. - * The decoded bit is then shifted in front of the d_shift_reg and the d_dec_b - * variables. This shift in front is due to the LS bit first transmission - * of the Ax.25 protocol. - * - * @param in input bit - */ - inline void - ax25_decoder_bm_impl::descramble_and_decode_1b (uint8_t in) - { - uint8_t descr_bit; - uint8_t dec_bit; +void +ax25_decoder_bm_impl::enter_sync_state () +{ + d_state = IN_SYNC; + d_dec_b = 0x0; + d_shift_reg = 0x0; + d_decoded_bits = 0; + d_received_bytes = 0; +} - in &= 0x1; +void +ax25_decoder_bm_impl::enter_decoding_state () +{ + uint8_t tmp; + d_state = DECODING; + d_decoded_bits = 0; + d_received_bytes = 0; + /* + * Due to the possibility of bit stuffing on the first byte some special + * handling is necessary + */ + if ((d_shift_reg & 0xfc) == 0x7c) { + /*This was a stuffed bit */ + d_dec_b <<= 1; + d_decoded_bits = 7; + } + else { + d_frame_buffer[0] = d_dec_b; + d_decoded_bits = 0; + d_received_bytes = 1; + } +} + +bool +ax25_decoder_bm_impl::enter_frame_end () +{ + uint16_t fcs; + uint16_t recv_fcs = 0x0; + + /* First check if the size of the frame is valid */ + if (d_received_bytes < AX25_MIN_ADDR_LEN + sizeof(uint16_t)) { + reset_state (); + return false; + } + + /* + * Check if the frame is correct using the FCS field + * Using this field also try to correct up to 2 error bits + */ + if (frame_check ()) { + message_port_pub ( + pmt::mp ("pdu"), + pmt::make_blob (d_frame_buffer, d_received_bytes - sizeof(uint16_t))); + reset_state (); + return true; + } + else { + message_port_pub ( + pmt::mp ("failed_pdu"), + pmt::make_blob (d_frame_buffer, d_received_bytes - sizeof(uint16_t))); + LOG_DEBUG("Wrong crc"); + reset_state (); + return false; + } +} + + +inline void +ax25_decoder_bm_impl::decode_1b (uint8_t in) +{ + + /* In AX.25 the LS bit is sent first */ + d_shift_reg = (d_shift_reg >> 1) | (in << 7); + d_dec_b = (d_dec_b >> 1) | (in << 7); +} + +bool +ax25_decoder_bm_impl::frame_check () +{ + uint16_t fcs; + uint16_t recv_fcs = 0x0; + uint8_t orig_byte; + + /* Check if the frame is correct using the FCS field */ + fcs = ax25_fcs (d_frame_buffer, d_received_bytes - sizeof(uint16_t)); + recv_fcs = (((uint16_t) d_frame_buffer[d_received_bytes - 1]) << 8) + | d_frame_buffer[d_received_bytes - 2]; + if (fcs == recv_fcs) { + return true; + } + return false; +} + +int +ax25_decoder_bm_impl::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + int ret; + const uint8_t *in = (const uint8_t*) input_items[0]; + + if (noutput_items < 1) { + return noutput_items; + } + + + if (d_descramble) { + for (int i = 0; i < noutput_items; i++) { /* Perform NRZI decoding */ - dec_bit = (~((in - d_prev_bit_nrzi) % 2)) & 0x1; - d_prev_bit_nrzi = in; - - - /* Descramble the input bit */ - descr_bit = d_lfsr.next_bit_descramble (dec_bit); - - /* In AX.25 the LS bit is sent first */ - d_shift_reg = (d_shift_reg >> 1) | (descr_bit << 7); - d_dec_b = (d_dec_b >> 1) | (descr_bit << 7); + uint8_t b = (~((in[i] - d_prev_bit_nrzi) % 2)) & 0x1; + d_prev_bit_nrzi = in[i]; + b = d_lfsr.next_bit_descramble (b); + d_bitstream.push_back (b); } - - inline void - ax25_decoder_bm_impl::decode_1b (uint8_t in) - { - uint8_t dec_bit; - in &= 0x1; - + } + else { + for (int i = 0; i < noutput_items; i++) { /* Perform NRZI decoding */ - dec_bit = (~((in - d_prev_bit_nrzi) % 2)) & 0x1; - d_prev_bit_nrzi = in; - - /* In AX.25 the LS bit is sent first */ - d_shift_reg = (d_shift_reg >> 1) | (dec_bit << 7); - d_dec_b = (d_dec_b >> 1) | (dec_bit << 7); + uint8_t b = (~((in[i] - d_prev_bit_nrzi) % 2)) & 0x1; + d_prev_bit_nrzi = in[i]; + d_bitstream.push_back (b); } + } + decode(); + return noutput_items; +} - int - ax25_decoder_bm_impl::work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { - int ret; - const uint8_t *in = (const uint8_t *) input_items[0]; - - if(noutput_items < 1) { - return noutput_items; - } - if (d_descramble) { - ret = descramble_and_decode (in, noutput_items); - } - else { - ret = decode (in, noutput_items); - } - return ret; - } - - } /* namespace satnogs */ +} /* namespace satnogs */ } /* namespace gr */ diff --git a/lib/ax25_decoder_bm_impl.h b/lib/ax25_decoder_bm_impl.h index 86ba005..a6f1eab 100644 --- a/lib/ax25_decoder_bm_impl.h +++ b/lib/ax25_decoder_bm_impl.h @@ -24,6 +24,7 @@ #include #include +#include namespace gr { @@ -35,7 +36,7 @@ namespace gr private: typedef enum { - NO_SYNC, IN_SYNC, DECODING, FRAME_END + NO_SYNC, IN_SYNC, DECODING } decoding_state_t; /** @@ -53,6 +54,8 @@ namespace gr size_t d_decoded_bits; digital::lfsr d_lfsr; uint8_t *d_frame_buffer; + std::deque d_bitstream; + size_t d_start_idx; void reset_state (); @@ -60,18 +63,16 @@ namespace gr enter_sync_state (); void enter_decoding_state (); - void + bool enter_frame_end (); - size_t - descramble_and_decode (const uint8_t *in, size_t nitems); - size_t - decode (const uint8_t *in, size_t nitems); + void + decode (); - inline void - descramble_and_decode_1b (uint8_t in); inline void decode_1b (uint8_t in); + bool + frame_check(); public: From f227b94ef1117a89012cd78adfc64a9964aa7bfc Mon Sep 17 00:00:00 2001 From: Manolis Surligas Date: Thu, 18 Jul 2019 18:48:15 +0300 Subject: [PATCH 10/24] Improve FSK/MSK flowgraphs sensitivity --- apps/flowgraphs/afsk1200_ax25.grc | 198 +++++++++++++++++++++-- apps/flowgraphs/fsk_ax25.grc | 119 +++++++++++--- apps/flowgraphs/msk_ax25.grc | 121 +++++++++++--- apps/flowgraphs/satnogs_afsk1200_ax25.py | 34 ++-- apps/flowgraphs/satnogs_fsk_ax25.py | 31 ++-- apps/flowgraphs/satnogs_msk_ax25.py | 19 ++- 6 files changed, 434 insertions(+), 88 deletions(-) diff --git a/apps/flowgraphs/afsk1200_ax25.grc b/apps/flowgraphs/afsk1200_ax25.grc index bcd80fd..dd1dcf9 100644 --- a/apps/flowgraphs/afsk1200_ax25.grc +++ b/apps/flowgraphs/afsk1200_ax25.grc @@ -260,7 +260,7 @@ _coordinate - (574, 394) + (936, 396) _rotation @@ -436,6 +436,85 @@ satnogs.not_set_antenna + + band_pass_filter + + beta + 6.76 + + + alias + + + + comment + + + + affinity + + + + decim + 1 + + + _enabled + True + + + type + fir_filter_fff + + + _coordinate + (360, 492) + + + _rotation + 0 + + + gain + 1 + + + high_cutoff_freq + 2400 + + + id + band_pass_filter_0 + + + interp + 1 + + + low_cutoff_freq + 1000 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + samp_rate + audio_samp_rate + + + width + 400 + + + win + firdes.WIN_HAMMING + + parameter @@ -480,7 +559,7 @@ value - 9600.0 + 1200.0 @@ -903,7 +982,7 @@ _coordinate - (534, 538) + (544, 540) _rotation @@ -954,7 +1033,7 @@ _coordinate - (1352, 572) + (1344, 572) _rotation @@ -1099,11 +1178,11 @@ _coordinate - (1994, 606) + (1928, 752) _rotation - 0 + 180 id @@ -1138,7 +1217,7 @@ _coordinate - (1563, 550) + (1928, 548) _rotation @@ -1146,11 +1225,11 @@ gain_mu - 0.175 + 0.5/8.0 gain_omega - 0.25*0.175*0.175 + 2*math.pi/100.0 id @@ -1170,7 +1249,7 @@ omega_relative_limit - 0.005 + 0.01 omega @@ -1503,7 +1582,7 @@ max_modulation_freq = 3000 _coordinate - (853, 347) + (1208, 348) _rotation @@ -1535,7 +1614,7 @@ max_modulation_freq = 3000 width - 3000 + 1000 win @@ -1562,7 +1641,7 @@ max_modulation_freq = 3000 cutoff_freq - (mark_frequency - space_frequency)/2.0 + (mark_frequency - space_frequency)/2.0 + 250 decim @@ -1610,7 +1689,82 @@ max_modulation_freq = 3000 width - 1000 + 500 + + + win + firdes.WIN_HAMMING + + + + low_pass_filter + + beta + 6.76 + + + alias + + + + comment + + + + affinity + + + + cutoff_freq + baudrate /2+ 500 /2 + + + decim + 1 + + + _enabled + 1 + + + type + fir_filter_fff + + + _coordinate + (1760, 532) + + + _rotation + 0 + + + gain + 1 + + + id + low_pass_filter_2_0 + + + interp + 1 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + samp_rate + baudrate*2 + + + width + 500 win @@ -4063,7 +4217,7 @@ max_modulation_freq = 3000 analog_quadrature_demod_cf_0_0 - dc_blocker_xx_0 + band_pass_filter_0 0 0 @@ -4085,6 +4239,12 @@ max_modulation_freq = 3000 0 1 + + band_pass_filter_0 + dc_blocker_xx_0 + 0 + 0 + blocks_delay_0 blocks_multiply_xx_0_0 @@ -4135,7 +4295,7 @@ max_modulation_freq = 3000 dc_blocker_xx_0_0 - digital_clock_recovery_mm_xx_0 + low_pass_filter_2_0 0 0 @@ -4169,6 +4329,12 @@ max_modulation_freq = 3000 0 0 + + low_pass_filter_2_0 + digital_clock_recovery_mm_xx_0 + 0 + 0 + osmosdr_source_0 blocks_rotator_cc_0 diff --git a/apps/flowgraphs/fsk_ax25.grc b/apps/flowgraphs/fsk_ax25.grc index aa44a2d..c742d9e 100644 --- a/apps/flowgraphs/fsk_ax25.grc +++ b/apps/flowgraphs/fsk_ax25.grc @@ -136,7 +136,7 @@ _coordinate - (1190, 411) + (1328, 420) _rotation @@ -665,7 +665,7 @@ _coordinate - (1390, 403) + (1824, 412) _rotation @@ -900,19 +900,19 @@ _coordinate - (1595, 379) + (1768, 556) _rotation - 0 + 180 gain_mu - 0.175 + 0.5/8.0 gain_omega - 0.25*0.175*0.175 + 2 * math.pi / 100 id @@ -932,7 +932,7 @@ omega_relative_limit - 0.005 + 0.01 omega @@ -1269,7 +1269,7 @@ we shift the LO a little further comment - + Avoid aliasing of the polyphase resampler affinity @@ -1277,7 +1277,7 @@ we shift the LO a little further cutoff_freq - (baudrate / 2) + 1500 + 0.75 * baudrate decim @@ -1285,7 +1285,7 @@ we shift the LO a little further _enabled - True + 1 type @@ -1293,7 +1293,7 @@ we shift the LO a little further _coordinate - (1005, 371) + (832, 372) _rotation @@ -1321,7 +1321,7 @@ we shift the LO a little further samp_rate - 2.0 * baudrate + audio_samp_rate width @@ -1332,6 +1332,81 @@ we shift the LO a little further firdes.WIN_HAMMING + + low_pass_filter + + beta + 6.76 + + + alias + + + + comment + + + + affinity + + + + cutoff_freq + baudrate * 0.60 + + + decim + 1 + + + _enabled + 1 + + + type + fir_filter_fff + + + _coordinate + (1584, 372) + + + _rotation + 0 + + + gain + 1 + + + id + low_pass_filter_1 + + + interp + 1 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + samp_rate + 2 * baudrate + + + width + baudrate / 8.0 + + + win + firdes.WIN_HAMMING + + osmosdr_source @@ -2822,7 +2897,7 @@ we shift the LO a little further _coordinate - (1563, 163) + (1016, 396) _rotation @@ -2830,7 +2905,7 @@ we shift the LO a little further id - pfb_arb_resampler_xxx_0_0 + pfb_arb_resampler_xxx_0_0_0 maxoutbuf @@ -3741,7 +3816,7 @@ we shift the LO a little further analog_quadrature_demod_cf_0_0 - dc_blocker_xx_0 + low_pass_filter_1 0 0 @@ -3771,7 +3846,7 @@ we shift the LO a little further blocks_multiply_xx_0 - pfb_arb_resampler_xxx_0_0 + low_pass_filter_0 0 0 @@ -3819,7 +3894,13 @@ we shift the LO a little further low_pass_filter_0 - analog_quadrature_demod_cf_0_0 + pfb_arb_resampler_xxx_0_0_0 + 0 + 0 + + + low_pass_filter_1 + dc_blocker_xx_0 0 0 @@ -3860,8 +3941,8 @@ we shift the LO a little further 0 - pfb_arb_resampler_xxx_0_0 - low_pass_filter_0 + pfb_arb_resampler_xxx_0_0_0 + analog_quadrature_demod_cf_0_0 0 0 diff --git a/apps/flowgraphs/msk_ax25.grc b/apps/flowgraphs/msk_ax25.grc index 84ab838..4b94bbf 100644 --- a/apps/flowgraphs/msk_ax25.grc +++ b/apps/flowgraphs/msk_ax25.grc @@ -136,7 +136,7 @@ _coordinate - (1214, 419) + (1544, 420) _rotation @@ -410,7 +410,7 @@ _coordinate - (1292, 203) + (1360, 228) _rotation @@ -665,7 +665,7 @@ _coordinate - (1430, 411) + (1912, 412) _rotation @@ -861,7 +861,7 @@ _coordinate - (1512, 592) + (1520, 592) _rotation @@ -900,19 +900,19 @@ _coordinate - (1611, 386) + (1704, 556) _rotation - 0 + 180 gain_mu - 0.175 + 0.5/8.0 gain_omega - 0.25*0.175*0.175 + 2 * math.pi / 100 id @@ -932,7 +932,7 @@ omega_relative_limit - 0.005 + 0.01 omega @@ -1269,7 +1269,7 @@ we shift the LO a little further comment - + Avoid aliasing of the polyphase resampler affinity @@ -1277,7 +1277,7 @@ we shift the LO a little further cutoff_freq - baudrate / 2 + 1500 + 0.75 * baudrate decim @@ -1285,7 +1285,7 @@ we shift the LO a little further _enabled - True + 1 type @@ -1293,7 +1293,7 @@ we shift the LO a little further _coordinate - (1022, 371) + (768, 372) _rotation @@ -1321,7 +1321,7 @@ we shift the LO a little further samp_rate - 2.0 * baudrate + audio_samp_rate width @@ -1332,6 +1332,81 @@ we shift the LO a little further firdes.WIN_HAMMING + + low_pass_filter + + beta + 6.76 + + + alias + + + + comment + + + + affinity + + + + cutoff_freq + baudrate * 0.60 + + + decim + 1 + + + _enabled + 1 + + + type + fir_filter_fff + + + _coordinate + (1712, 372) + + + _rotation + 0 + + + gain + 1 + + + id + low_pass_filter_1 + + + interp + 1 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + samp_rate + 2 * baudrate + + + width + baudrate / 8.0 + + + win + firdes.WIN_HAMMING + + osmosdr_source @@ -2822,7 +2897,7 @@ we shift the LO a little further _coordinate - (735, 395) + (1288, 396) _rotation @@ -3379,7 +3454,7 @@ we shift the LO a little further _coordinate - (965, 59) + (1008, 60) _rotation @@ -3741,7 +3816,7 @@ we shift the LO a little further analog_quadrature_demod_cf_0_0 - dc_blocker_xx_0 + low_pass_filter_1 0 0 @@ -3771,7 +3846,7 @@ we shift the LO a little further blocks_multiply_xx_0 - pfb_arb_resampler_xxx_0_0_0 + low_pass_filter_0 0 0 @@ -3819,7 +3894,13 @@ we shift the LO a little further low_pass_filter_0 - analog_quadrature_demod_cf_0_0 + pfb_arb_resampler_xxx_0_0_0 + 0 + 0 + + + low_pass_filter_1 + dc_blocker_xx_0 0 0 @@ -3861,7 +3942,7 @@ we shift the LO a little further pfb_arb_resampler_xxx_0_0_0 - low_pass_filter_0 + analog_quadrature_demod_cf_0_0 0 0 diff --git a/apps/flowgraphs/satnogs_afsk1200_ax25.py b/apps/flowgraphs/satnogs_afsk1200_ax25.py index 5806bc8..45a36e8 100755 --- a/apps/flowgraphs/satnogs_afsk1200_ax25.py +++ b/apps/flowgraphs/satnogs_afsk1200_ax25.py @@ -27,7 +27,7 @@ import time class satnogs_afsk1200_ax25(gr.top_block): - def __init__(self, antenna=satnogs.not_set_antenna, baudrate=9600.0, bb_gain=satnogs.not_set_rx_bb_gain, decoded_data_file_path='/tmp/.satnogs/data/data', dev_args=satnogs.not_set_dev_args, doppler_correction_per_sec=1000, enable_iq_dump=0, file_path='test.wav', if_gain=satnogs.not_set_rx_if_gain, iq_file_path='/tmp/iq.dat', lo_offset=100e3, mark_frequency=2200.0, ppm=0, rf_gain=satnogs.not_set_rx_rf_gain, rigctl_port=4532, rx_freq=100e6, rx_sdr_device='usrpb200', samp_rate_rx=satnogs.not_set_samp_rate_rx, space_frequency=1200.0, udp_IP='127.0.0.1', udp_port=16887, waterfall_file_path='/tmp/waterfall.dat'): + def __init__(self, antenna=satnogs.not_set_antenna, baudrate=1200.0, bb_gain=satnogs.not_set_rx_bb_gain, decoded_data_file_path='/tmp/.satnogs/data/data', dev_args=satnogs.not_set_dev_args, doppler_correction_per_sec=1000, enable_iq_dump=0, file_path='test.wav', if_gain=satnogs.not_set_rx_if_gain, iq_file_path='/tmp/iq.dat', lo_offset=100e3, mark_frequency=2200.0, ppm=0, rf_gain=satnogs.not_set_rx_rf_gain, rigctl_port=4532, rx_freq=100e6, rx_sdr_device='usrpb200', samp_rate_rx=satnogs.not_set_samp_rate_rx, space_frequency=1200.0, udp_IP='127.0.0.1', udp_port=16887, waterfall_file_path='/tmp/waterfall.dat'): gr.top_block.__init__(self, "AFSK1200 AX.25 decoder ") ################################################## @@ -95,11 +95,13 @@ class satnogs_afsk1200_ax25(gr.top_block): self.osmosdr_source_0.set_antenna(satnogs.handle_rx_antenna(rx_sdr_device, antenna), 0) self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx), 0) + self.low_pass_filter_2_0 = filter.fir_filter_fff(1, firdes.low_pass( + 1, baudrate*2, baudrate /2+ 500 /2, 500, firdes.WIN_HAMMING, 6.76)) self.low_pass_filter_1 = filter.fir_filter_ccf(20, firdes.low_pass( - 1, audio_samp_rate, (mark_frequency - space_frequency)/2.0, 1000, firdes.WIN_HAMMING, 6.76)) + 1, audio_samp_rate, (mark_frequency - space_frequency)/2.0 + 250, 500, firdes.WIN_HAMMING, 6.76)) self.low_pass_filter_0 = filter.fir_filter_ccf(1, firdes.low_pass( - 1, audio_samp_rate, deviation+max_modulation_freq, 3000, firdes.WIN_HAMMING, 6.76)) - self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff((48e3/20)/baud_rate, 0.25*0.175*0.175, 0.5, 0.175, 0.005) + 1, audio_samp_rate, deviation+max_modulation_freq, 1000, firdes.WIN_HAMMING, 6.76)) + self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff((48e3/20)/baud_rate, 2*math.pi/100.0, 0.5, 0.5/8.0, 0.01) self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb() self.dc_blocker_xx_0_0 = filter.dc_blocker_ff(1024, True) self.dc_blocker_xx_0 = filter.dc_blocker_ff(1024, True) @@ -110,6 +112,8 @@ class satnogs_afsk1200_ax25(gr.top_block): self.blocks_moving_average_xx_0 = blocks.moving_average_ff(1024, 1.0/1024.0, 4096) self.blocks_float_to_complex_0 = blocks.float_to_complex(1) self.blocks_delay_0 = blocks.delay(gr.sizeof_gr_complex*1, 1024/2) + self.band_pass_filter_0 = filter.fir_filter_fff(1, firdes.band_pass( + 1, audio_samp_rate, 1000, 2400, 400, firdes.WIN_HAMMING, 6.76)) self.analog_sig_source_x_0 = analog.sig_source_c(audio_samp_rate, analog.GR_COS_WAVE, -(1200 + 2200) / 2, 1, 0) self.analog_quadrature_demod_cf_0_0_0_0 = analog.quadrature_demod_cf(1.0) self.analog_quadrature_demod_cf_0_0 = analog.quadrature_demod_cf((2*math.pi*deviation)/audio_samp_rate) @@ -126,10 +130,11 @@ class satnogs_afsk1200_ax25(gr.top_block): self.msg_connect((self.satnogs_ax25_decoder_bm_0_0, 'pdu'), (self.satnogs_udp_msg_sink_0_0, 'in')) self.msg_connect((self.satnogs_tcp_rigctl_msg_source_0, 'freq'), (self.satnogs_coarse_doppler_correction_cc_0, 'freq')) self.connect((self.analog_quadrature_demod_cf_0, 0), (self.dc_blocker_xx_0_0, 0)) - self.connect((self.analog_quadrature_demod_cf_0_0, 0), (self.dc_blocker_xx_0, 0)) + self.connect((self.analog_quadrature_demod_cf_0_0, 0), (self.band_pass_filter_0, 0)) self.connect((self.analog_quadrature_demod_cf_0_0, 0), (self.satnogs_ogg_encoder_0, 0)) self.connect((self.analog_quadrature_demod_cf_0_0_0_0, 0), (self.blocks_moving_average_xx_0, 0)) self.connect((self.analog_sig_source_x_0, 0), (self.blocks_multiply_xx_0, 1)) + self.connect((self.band_pass_filter_0, 0), (self.dc_blocker_xx_0, 0)) self.connect((self.blocks_delay_0, 0), (self.blocks_multiply_xx_0_0, 0)) self.connect((self.blocks_float_to_complex_0, 0), (self.blocks_multiply_xx_0, 0)) self.connect((self.blocks_moving_average_xx_0, 0), (self.blocks_vco_c_0, 0)) @@ -138,12 +143,13 @@ class satnogs_afsk1200_ax25(gr.top_block): self.connect((self.blocks_rotator_cc_0, 0), (self.satnogs_coarse_doppler_correction_cc_0, 0)) self.connect((self.blocks_vco_c_0, 0), (self.blocks_multiply_xx_0_0, 1)) self.connect((self.dc_blocker_xx_0, 0), (self.blocks_float_to_complex_0, 0)) - self.connect((self.dc_blocker_xx_0_0, 0), (self.digital_clock_recovery_mm_xx_0, 0)) + self.connect((self.dc_blocker_xx_0_0, 0), (self.low_pass_filter_2_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self.satnogs_ax25_decoder_bm_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self.satnogs_ax25_decoder_bm_0_0, 0)) self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.digital_binary_slicer_fb_0, 0)) self.connect((self.low_pass_filter_0, 0), (self.analog_quadrature_demod_cf_0_0, 0)) self.connect((self.low_pass_filter_1, 0), (self.analog_quadrature_demod_cf_0, 0)) + self.connect((self.low_pass_filter_2_0, 0), (self.digital_clock_recovery_mm_xx_0, 0)) self.connect((self.osmosdr_source_0, 0), (self.blocks_rotator_cc_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.analog_quadrature_demod_cf_0_0_0_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.blocks_delay_0, 0)) @@ -163,6 +169,7 @@ class satnogs_afsk1200_ax25(gr.top_block): def set_baudrate(self, baudrate): self.baudrate = baudrate + self.low_pass_filter_2_0.set_taps(firdes.low_pass(1, self.baudrate*2, self.baudrate /2+ 500 /2, 500, firdes.WIN_HAMMING, 6.76)) def get_bb_gain(self): return self.bb_gain @@ -227,7 +234,7 @@ class satnogs_afsk1200_ax25(gr.top_block): def set_mark_frequency(self, mark_frequency): self.mark_frequency = mark_frequency - self.low_pass_filter_1.set_taps(firdes.low_pass(1, self.audio_samp_rate, (self.mark_frequency - self.space_frequency)/2.0, 1000, firdes.WIN_HAMMING, 6.76)) + self.low_pass_filter_1.set_taps(firdes.low_pass(1, self.audio_samp_rate, (self.mark_frequency - self.space_frequency)/2.0 + 250, 500, firdes.WIN_HAMMING, 6.76)) def get_ppm(self): return self.ppm @@ -286,7 +293,7 @@ class satnogs_afsk1200_ax25(gr.top_block): def set_space_frequency(self, space_frequency): self.space_frequency = space_frequency - self.low_pass_filter_1.set_taps(firdes.low_pass(1, self.audio_samp_rate, (self.mark_frequency - self.space_frequency)/2.0, 1000, firdes.WIN_HAMMING, 6.76)) + self.low_pass_filter_1.set_taps(firdes.low_pass(1, self.audio_samp_rate, (self.mark_frequency - self.space_frequency)/2.0 + 250, 500, firdes.WIN_HAMMING, 6.76)) def get_udp_IP(self): return self.udp_IP @@ -311,14 +318,14 @@ class satnogs_afsk1200_ax25(gr.top_block): def set_max_modulation_freq(self, max_modulation_freq): self.max_modulation_freq = max_modulation_freq - self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, self.deviation+self.max_modulation_freq, 3000, firdes.WIN_HAMMING, 6.76)) + self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, self.deviation+self.max_modulation_freq, 1000, firdes.WIN_HAMMING, 6.76)) def get_deviation(self): return self.deviation def set_deviation(self, deviation): self.deviation = deviation - self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, self.deviation+self.max_modulation_freq, 3000, firdes.WIN_HAMMING, 6.76)) + self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, self.deviation+self.max_modulation_freq, 1000, firdes.WIN_HAMMING, 6.76)) self.analog_quadrature_demod_cf_0_0.set_gain((2*math.pi*self.deviation)/self.audio_samp_rate) def get_baud_rate(self): @@ -335,8 +342,9 @@ class satnogs_afsk1200_ax25(gr.top_block): def set_audio_samp_rate(self, audio_samp_rate): self.audio_samp_rate = audio_samp_rate self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) - self.low_pass_filter_1.set_taps(firdes.low_pass(1, self.audio_samp_rate, (self.mark_frequency - self.space_frequency)/2.0, 1000, firdes.WIN_HAMMING, 6.76)) - self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, self.deviation+self.max_modulation_freq, 3000, firdes.WIN_HAMMING, 6.76)) + self.low_pass_filter_1.set_taps(firdes.low_pass(1, self.audio_samp_rate, (self.mark_frequency - self.space_frequency)/2.0 + 250, 500, firdes.WIN_HAMMING, 6.76)) + self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, self.deviation+self.max_modulation_freq, 1000, firdes.WIN_HAMMING, 6.76)) + self.band_pass_filter_0.set_taps(firdes.band_pass(1, self.audio_samp_rate, 1000, 2400, 400, firdes.WIN_HAMMING, 6.76)) self.analog_sig_source_x_0.set_sampling_freq(self.audio_samp_rate) self.analog_quadrature_demod_cf_0_0.set_gain((2*math.pi*self.deviation)/self.audio_samp_rate) self.analog_quadrature_demod_cf_0.set_gain(((self.audio_samp_rate/20) / self.baud_rate)/(math.pi*1)) @@ -349,7 +357,7 @@ def argument_parser(): "", "--antenna", dest="antenna", type="string", default=satnogs.not_set_antenna, help="Set antenna [default=%default]") parser.add_option( - "", "--baudrate", dest="baudrate", type="eng_float", default=eng_notation.num_to_str(9600.0), + "", "--baudrate", dest="baudrate", type="eng_float", default=eng_notation.num_to_str(1200.0), help="Set baudrate [default=%default]") parser.add_option( "", "--bb-gain", dest="bb_gain", type="eng_float", default=eng_notation.num_to_str(satnogs.not_set_rx_bb_gain), diff --git a/apps/flowgraphs/satnogs_fsk_ax25.py b/apps/flowgraphs/satnogs_fsk_ax25.py index b00cafa..84f4d34 100755 --- a/apps/flowgraphs/satnogs_fsk_ax25.py +++ b/apps/flowgraphs/satnogs_fsk_ax25.py @@ -71,11 +71,11 @@ class satnogs_fsk_ax25(gr.top_block): self.satnogs_coarse_doppler_correction_cc_0 = satnogs.coarse_doppler_correction_cc(rx_freq, satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx)) self.satnogs_ax25_decoder_bm_0_0 = satnogs.ax25_decoder_bm('GND', 0, True, False, 1024) self.satnogs_ax25_decoder_bm_0 = satnogs.ax25_decoder_bm('GND', 0, True, True, 1024) - self.pfb_arb_resampler_xxx_0_0 = pfb.arb_resampler_ccf( + self.pfb_arb_resampler_xxx_0_0_0 = pfb.arb_resampler_ccf( (2.0*baudrate)/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx), taps=None, flt_size=32) - self.pfb_arb_resampler_xxx_0_0.declare_sample_delay(0) + self.pfb_arb_resampler_xxx_0_0_0.declare_sample_delay(0) self.pfb_arb_resampler_xxx_0 = pfb.arb_resampler_ccf( audio_samp_rate/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx), @@ -96,16 +96,18 @@ class satnogs_fsk_ax25(gr.top_block): self.osmosdr_source_0.set_antenna(satnogs.handle_rx_antenna(rx_sdr_device, antenna), 0) self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx), 0) + self.low_pass_filter_1 = filter.fir_filter_fff(1, firdes.low_pass( + 1, 2 * baudrate, baudrate * 0.60, baudrate / 8.0, firdes.WIN_HAMMING, 6.76)) self.low_pass_filter_0 = filter.fir_filter_ccf(1, firdes.low_pass( - 1, 2.0 * baudrate, (baudrate / 2) + 1500, 1000, firdes.WIN_HAMMING, 6.76)) - self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(2, 0.25*0.175*0.175, 0.5, 0.175, 0.005) + 1, audio_samp_rate, 0.75 * baudrate, 1000, firdes.WIN_HAMMING, 6.76)) + self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(2, 2 * math.pi / 100, 0.5, 0.5/8.0, 0.01) self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb() self.dc_blocker_xx_0_0 = filter.dc_blocker_ff(1024, True) self.dc_blocker_xx_0 = filter.dc_blocker_ff(1024, True) self.blocks_vco_c_0 = blocks.vco_c(audio_samp_rate, -audio_samp_rate, 1.0) self.blocks_rotator_cc_0 = blocks.rotator_cc(-2.0 * math.pi * (lo_offset / satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx))) self.blocks_multiply_xx_0 = blocks.multiply_vcc(1) - self.blocks_moving_average_xx_0 = blocks.moving_average_ff(1024, 1.0/1024.0, 4096) + self.blocks_moving_average_xx_0 = blocks.moving_average_ff(1024, 1.0/1024.0, 4096) self.blocks_delay_0 = blocks.delay(gr.sizeof_gr_complex*1, 1024/2) self.analog_quadrature_demod_cf_0_0_0_0 = analog.quadrature_demod_cf(1.0) self.analog_quadrature_demod_cf_0_0_0 = analog.quadrature_demod_cf(0.9) @@ -121,12 +123,12 @@ class satnogs_fsk_ax25(gr.top_block): self.msg_connect((self.satnogs_ax25_decoder_bm_0_0, 'pdu'), (self.satnogs_frame_file_sink_0_1_0, 'frame')) self.msg_connect((self.satnogs_ax25_decoder_bm_0_0, 'pdu'), (self.satnogs_udp_msg_sink_0_0, 'in')) self.msg_connect((self.satnogs_tcp_rigctl_msg_source_0, 'freq'), (self.satnogs_coarse_doppler_correction_cc_0, 'freq')) - self.connect((self.analog_quadrature_demod_cf_0_0, 0), (self.dc_blocker_xx_0, 0)) + self.connect((self.analog_quadrature_demod_cf_0_0, 0), (self.low_pass_filter_1, 0)) self.connect((self.analog_quadrature_demod_cf_0_0_0, 0), (self.dc_blocker_xx_0_0, 0)) self.connect((self.analog_quadrature_demod_cf_0_0_0_0, 0), (self.blocks_moving_average_xx_0, 0)) self.connect((self.blocks_delay_0, 0), (self.blocks_multiply_xx_0, 0)) self.connect((self.blocks_moving_average_xx_0, 0), (self.blocks_vco_c_0, 0)) - self.connect((self.blocks_multiply_xx_0, 0), (self.pfb_arb_resampler_xxx_0_0, 0)) + self.connect((self.blocks_multiply_xx_0, 0), (self.low_pass_filter_0, 0)) self.connect((self.blocks_rotator_cc_0, 0), (self.satnogs_coarse_doppler_correction_cc_0, 0)) self.connect((self.blocks_vco_c_0, 0), (self.blocks_multiply_xx_0, 1)) self.connect((self.dc_blocker_xx_0, 0), (self.digital_clock_recovery_mm_xx_0, 0)) @@ -134,14 +136,15 @@ class satnogs_fsk_ax25(gr.top_block): self.connect((self.digital_binary_slicer_fb_0, 0), (self.satnogs_ax25_decoder_bm_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self.satnogs_ax25_decoder_bm_0_0, 0)) self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.digital_binary_slicer_fb_0, 0)) - self.connect((self.low_pass_filter_0, 0), (self.analog_quadrature_demod_cf_0_0, 0)) + self.connect((self.low_pass_filter_0, 0), (self.pfb_arb_resampler_xxx_0_0_0, 0)) + self.connect((self.low_pass_filter_1, 0), (self.dc_blocker_xx_0, 0)) self.connect((self.osmosdr_source_0, 0), (self.blocks_rotator_cc_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.analog_quadrature_demod_cf_0_0_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.analog_quadrature_demod_cf_0_0_0_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.blocks_delay_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.satnogs_iq_sink_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.satnogs_waterfall_sink_0, 0)) - self.connect((self.pfb_arb_resampler_xxx_0_0, 0), (self.low_pass_filter_0, 0)) + self.connect((self.pfb_arb_resampler_xxx_0_0_0, 0), (self.analog_quadrature_demod_cf_0_0, 0)) self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.pfb_arb_resampler_xxx_0, 0)) def get_antenna(self): @@ -156,8 +159,9 @@ class satnogs_fsk_ax25(gr.top_block): def set_baudrate(self, baudrate): self.baudrate = baudrate - self.pfb_arb_resampler_xxx_0_0.set_rate((2.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) - self.low_pass_filter_0.set_taps(firdes.low_pass(1, 2.0 * self.baudrate, (self.baudrate / 2) + 1500, 1000, firdes.WIN_HAMMING, 6.76)) + self.pfb_arb_resampler_xxx_0_0_0.set_rate((2.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) + self.low_pass_filter_1.set_taps(firdes.low_pass(1, 2 * self.baudrate, self.baudrate * 0.60, self.baudrate / 8.0, firdes.WIN_HAMMING, 6.76)) + self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, 0.75 * self.baudrate, 1000, firdes.WIN_HAMMING, 6.76)) def get_bb_gain(self): return self.bb_gain @@ -250,7 +254,7 @@ class satnogs_fsk_ax25(gr.top_block): def set_rx_sdr_device(self, rx_sdr_device): self.rx_sdr_device = rx_sdr_device - self.pfb_arb_resampler_xxx_0_0.set_rate((2.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) + self.pfb_arb_resampler_xxx_0_0_0.set_rate((2.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.osmosdr_source_0.set_sample_rate(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.osmosdr_source_0.set_gain(satnogs.handle_rx_rf_gain(self.rx_sdr_device, self.rf_gain), 0) @@ -265,7 +269,7 @@ class satnogs_fsk_ax25(gr.top_block): def set_samp_rate_rx(self, samp_rate_rx): self.samp_rate_rx = samp_rate_rx - self.pfb_arb_resampler_xxx_0_0.set_rate((2.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) + self.pfb_arb_resampler_xxx_0_0_0.set_rate((2.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.osmosdr_source_0.set_sample_rate(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx), 0) @@ -295,6 +299,7 @@ class satnogs_fsk_ax25(gr.top_block): def set_audio_samp_rate(self, audio_samp_rate): self.audio_samp_rate = audio_samp_rate self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) + self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, 0.75 * self.baudrate, 1000, firdes.WIN_HAMMING, 6.76)) def argument_parser(): diff --git a/apps/flowgraphs/satnogs_msk_ax25.py b/apps/flowgraphs/satnogs_msk_ax25.py index c4bcc10..a0137fd 100755 --- a/apps/flowgraphs/satnogs_msk_ax25.py +++ b/apps/flowgraphs/satnogs_msk_ax25.py @@ -96,9 +96,11 @@ class satnogs_msk_ax25(gr.top_block): self.osmosdr_source_0.set_antenna(satnogs.handle_rx_antenna(rx_sdr_device, antenna), 0) self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx), 0) + self.low_pass_filter_1 = filter.fir_filter_fff(1, firdes.low_pass( + 1, 2 * baudrate, baudrate * 0.60, baudrate / 8.0, firdes.WIN_HAMMING, 6.76)) self.low_pass_filter_0 = filter.fir_filter_ccf(1, firdes.low_pass( - 1, 2.0 * baudrate, baudrate / 2 + 1500, 1000, firdes.WIN_HAMMING, 6.76)) - self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(2, 0.25*0.175*0.175, 0.5, 0.175, 0.005) + 1, audio_samp_rate, 0.75 * baudrate, 1000, firdes.WIN_HAMMING, 6.76)) + self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(2, 2 * math.pi / 100, 0.5, 0.5/8.0, 0.01) self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb() self.dc_blocker_xx_0_0 = filter.dc_blocker_ff(1024, True) self.dc_blocker_xx_0 = filter.dc_blocker_ff(1024, True) @@ -121,12 +123,12 @@ class satnogs_msk_ax25(gr.top_block): self.msg_connect((self.satnogs_ax25_decoder_bm_0_0, 'pdu'), (self.satnogs_frame_file_sink_0_1_0, 'frame')) self.msg_connect((self.satnogs_ax25_decoder_bm_0_0, 'pdu'), (self.satnogs_udp_msg_sink_0_0, 'in')) self.msg_connect((self.satnogs_tcp_rigctl_msg_source_0, 'freq'), (self.satnogs_coarse_doppler_correction_cc_0, 'freq')) - self.connect((self.analog_quadrature_demod_cf_0_0, 0), (self.dc_blocker_xx_0, 0)) + self.connect((self.analog_quadrature_demod_cf_0_0, 0), (self.low_pass_filter_1, 0)) self.connect((self.analog_quadrature_demod_cf_0_0_0, 0), (self.dc_blocker_xx_0_0, 0)) self.connect((self.analog_quadrature_demod_cf_0_0_0_0, 0), (self.blocks_moving_average_xx_0, 0)) self.connect((self.blocks_delay_0, 0), (self.blocks_multiply_xx_0, 0)) self.connect((self.blocks_moving_average_xx_0, 0), (self.blocks_vco_c_0, 0)) - self.connect((self.blocks_multiply_xx_0, 0), (self.pfb_arb_resampler_xxx_0_0_0, 0)) + self.connect((self.blocks_multiply_xx_0, 0), (self.low_pass_filter_0, 0)) self.connect((self.blocks_rotator_cc_0, 0), (self.satnogs_coarse_doppler_correction_cc_0, 0)) self.connect((self.blocks_vco_c_0, 0), (self.blocks_multiply_xx_0, 1)) self.connect((self.dc_blocker_xx_0, 0), (self.digital_clock_recovery_mm_xx_0, 0)) @@ -134,14 +136,15 @@ class satnogs_msk_ax25(gr.top_block): self.connect((self.digital_binary_slicer_fb_0, 0), (self.satnogs_ax25_decoder_bm_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self.satnogs_ax25_decoder_bm_0_0, 0)) self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.digital_binary_slicer_fb_0, 0)) - self.connect((self.low_pass_filter_0, 0), (self.analog_quadrature_demod_cf_0_0, 0)) + self.connect((self.low_pass_filter_0, 0), (self.pfb_arb_resampler_xxx_0_0_0, 0)) + self.connect((self.low_pass_filter_1, 0), (self.dc_blocker_xx_0, 0)) self.connect((self.osmosdr_source_0, 0), (self.blocks_rotator_cc_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.analog_quadrature_demod_cf_0_0_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.analog_quadrature_demod_cf_0_0_0_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.blocks_delay_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.satnogs_iq_sink_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.satnogs_waterfall_sink_0, 0)) - self.connect((self.pfb_arb_resampler_xxx_0_0_0, 0), (self.low_pass_filter_0, 0)) + self.connect((self.pfb_arb_resampler_xxx_0_0_0, 0), (self.analog_quadrature_demod_cf_0_0, 0)) self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.pfb_arb_resampler_xxx_0, 0)) def get_antenna(self): @@ -157,7 +160,8 @@ class satnogs_msk_ax25(gr.top_block): def set_baudrate(self, baudrate): self.baudrate = baudrate self.pfb_arb_resampler_xxx_0_0_0.set_rate((2.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) - self.low_pass_filter_0.set_taps(firdes.low_pass(1, 2.0 * self.baudrate, self.baudrate / 2 + 1500, 1000, firdes.WIN_HAMMING, 6.76)) + self.low_pass_filter_1.set_taps(firdes.low_pass(1, 2 * self.baudrate, self.baudrate * 0.60, self.baudrate / 8.0, firdes.WIN_HAMMING, 6.76)) + self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, 0.75 * self.baudrate, 1000, firdes.WIN_HAMMING, 6.76)) def get_bb_gain(self): return self.bb_gain @@ -295,6 +299,7 @@ class satnogs_msk_ax25(gr.top_block): def set_audio_samp_rate(self, audio_samp_rate): self.audio_samp_rate = audio_samp_rate self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) + self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, 0.75 * self.baudrate, 1000, firdes.WIN_HAMMING, 6.76)) def argument_parser(): From 8b74aa8e82a5484c2d6cedb693c93a336fec4512 Mon Sep 17 00:00:00 2001 From: Ilias Daradimos Date: Wed, 5 Jun 2019 11:36:58 +0000 Subject: [PATCH 11/24] Update README.md --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ff0793a..660f009 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ for decoding signals from various scientific and academic sattelites. * libpng * libpng++ * git +* swig **Optional** * gr-osmocom (for using the flowgraphs with real SDR hardware) @@ -23,14 +24,15 @@ for decoding signals from various scientific and academic sattelites. ``` apt install -y build-essential cmake gnuradio g++ \ python-mako python-six libogg-dev \ - libvorbis-dev libpng-dev libpng++-dev + libvorbis-dev libpng-dev libpng++-dev \ + swig cd /tmp git clone https://github.com/gnuradio/volk.git cd volk mkdir build cd build cmake .. -make -j 8 +make -j $(nproc --all) sudo make install ``` From b08ade0dc77484c57f948913c43bc01624d6988d Mon Sep 17 00:00:00 2001 From: Ilias Daradimos Date: Wed, 5 Jun 2019 11:37:54 +0000 Subject: [PATCH 12/24] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 660f009..f06be6d 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ sudo make install 3. `mkdir build` 4. `cd build` 5. `cmake ..` -6. `make` +6. `make -j $(nproc --all)` 7. `sudo make install` If this is the first time you are building the gr-satnogs module run From 5c870335d85f1bf5a517255a176d7e2f777f11f4 Mon Sep 17 00:00:00 2001 From: Manolis Surligas Date: Thu, 18 Jul 2019 23:49:42 +0300 Subject: [PATCH 13/24] Fix Airspy gain setting --- python/hw_settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/hw_settings.py b/python/hw_settings.py index 61eaa75..f388583 100644 --- a/python/hw_settings.py +++ b/python/hw_settings.py @@ -43,7 +43,7 @@ hw_rx_settings = {'usrpb200' : {'rf_gain' : 50.0, 'if_gain' : 0.0, 'usrpx3x0' : {'rf_gain' : 26.0, 'if_gain' : 0.0, 'bb_gain' : 0.0, 'samp_rate' : 2e6, 'antenna' : 'TX/RX', 'dev_arg': 'uhd'}, - 'airspy' : {'rf_gain' : 30.0, 'if_gain' : 0.0, + 'airspy' : {'rf_gain' : 19.0, 'if_gain' : 0.0, 'bb_gain' : 0.0, 'samp_rate' : 10e6, 'antenna' : '', 'dev_arg': 'airspy'}, 'airspymini' : {'rf_gain' : 15.0, 'if_gain' : 0.0, From 7d190e0b907364c3cf818080ce2a3b740bae48ea Mon Sep 17 00:00:00 2001 From: Manolis Surligas Date: Fri, 19 Jul 2019 14:39:55 +0300 Subject: [PATCH 14/24] Adapt FSK improvements for the Reaktor flowgraph --- .../reaktor_hello_world_fsk9600_decoder.grc | 535 ++++++++++++++++-- ...ogs_reaktor_hello_world_fsk9600_decoder.py | 45 +- 2 files changed, 529 insertions(+), 51 deletions(-) diff --git a/apps/flowgraphs/satellites/reaktor_hello_world_fsk9600_decoder.grc b/apps/flowgraphs/satellites/reaktor_hello_world_fsk9600_decoder.grc index 678597e..69b6807 100644 --- a/apps/flowgraphs/satellites/reaktor_hello_world_fsk9600_decoder.grc +++ b/apps/flowgraphs/satellites/reaktor_hello_world_fsk9600_decoder.grc @@ -175,7 +175,7 @@ _coordinate - (1248, 196) + (904, 412) _rotation @@ -183,11 +183,11 @@ gain - 1.2 + 0.9 id - analog_quadrature_demod_cf_0_0 + analog_quadrature_demod_cf_0_0_0 maxoutbuf @@ -214,11 +214,11 @@ _enabled - True + 1 _coordinate - (992, 316) + (952, 316) _rotation @@ -226,11 +226,54 @@ gain - 0.9 + 1.0 id - analog_quadrature_demod_cf_0_0_0 + analog_quadrature_demod_cf_0_0_0_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + + analog_quadrature_demod_cf + + alias + + + + comment + + + + affinity + + + + _enabled + 1 + + + _coordinate + (1824, 180) + + + _rotation + 0 + + + gain + 1.2 + + + id + analog_quadrature_demod_cf_0_0_0_1 maxoutbuf @@ -382,6 +425,171 @@ satnogs.not_set_rx_bb_gain + + blocks_delay + + alias + + + + comment + + + + affinity + + + + delay + 1024/2 + + + _enabled + 1 + + + _coordinate + (992, 164) + + + _rotation + 0 + + + id + blocks_delay_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + num_ports + 1 + + + type + complex + + + vlen + 1 + + + + blocks_moving_average_xx + + alias + + + + comment + + + + affinity + + + + _enabled + 1 + + + _coordinate + (1136, 300) + + + _rotation + 0 + + + id + blocks_moving_average_xx_0 + + + vlen + 1 + + + length + 1024 + + + max_iter + 4096 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + scale + 1.0/1024.0 + + + type + float + + + + blocks_multiply_xx + + alias + + + + comment + + + + affinity + + + + _enabled + 1 + + + _coordinate + (1296, 168) + + + _rotation + 0 + + + id + blocks_multiply_xx_0_0 + + + type + complex + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + num_inputs + 2 + + + vlen + 1 + + blocks_rotator_cc @@ -402,7 +610,7 @@ _coordinate - (472, 372) + (368, 372) _rotation @@ -425,6 +633,57 @@ -2.0 * math.pi * (lo_offset / satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx)) + + blocks_vco_c + + amplitude + 1.0 + + + alias + + + + comment + + + + affinity + + + + _enabled + 1 + + + _coordinate + (1296, 300) + + + _rotation + 0 + + + id + blocks_vco_c_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + samp_rate + audio_samp_rate + + + sensitivity + -audio_samp_rate + + dc_blocker_xx @@ -445,7 +704,7 @@ _coordinate - (1432, 188) + (1120, 404) _rotation @@ -453,7 +712,7 @@ id - dc_blocker_xx_0 + dc_blocker_xx_0_0 length @@ -492,19 +751,19 @@ _enabled - True + 1 _coordinate - (1208, 308) + (1912, 556) _rotation - 0 + 180 id - dc_blocker_xx_0_0 + dc_blocker_xx_0_0_0 length @@ -680,19 +939,19 @@ _coordinate - (1616, 164) + (1672, 532) _rotation - 0 + 180 gain_mu - 0.175 + 0.5/8.0 gain_omega - 0.25*0.175*0.175 + 2 * math.pi / 100 id @@ -712,7 +971,7 @@ omega_relative_limit - 0.005 + 0.01 omega @@ -1037,6 +1296,156 @@ we shift the LO a little further 100e3 + + low_pass_filter + + beta + 6.76 + + + alias + + + + comment + + + + affinity + + + + cutoff_freq + 0.75 * baudrate + + + decim + 1 + + + _enabled + 1 + + + type + fir_filter_ccf + + + _coordinate + (1424, 132) + + + _rotation + 0 + + + gain + 1 + + + id + low_pass_filter_0 + + + interp + 1 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + samp_rate + audio_samp_rate + + + width + 1000 + + + win + firdes.WIN_HAMMING + + + + low_pass_filter + + beta + 6.76 + + + alias + + + + comment + + + + affinity + + + + cutoff_freq + baudrate * 0.60 + + + decim + 1 + + + _enabled + 1 + + + type + fir_filter_fff + + + _coordinate + (1984, 132) + + + _rotation + 0 + + + gain + 1 + + + id + low_pass_filter_1 + + + interp + 1 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + samp_rate + 2 * baudrate + + + width + baudrate / 8.0 + + + win + firdes.WIN_HAMMING + + osmosdr_source @@ -2341,7 +2750,7 @@ we shift the LO a little further _coordinate - (216, 284) + (112, 284) _rotation @@ -2464,7 +2873,7 @@ we shift the LO a little further _coordinate - (728, 172) + (624, 172) _rotation @@ -2523,11 +2932,11 @@ we shift the LO a little further _enabled - True + 1 _coordinate - (984, 172) + (1592, 156) _rotation @@ -2535,7 +2944,7 @@ we shift the LO a little further id - pfb_arb_resampler_xxx_0_0 + pfb_arb_resampler_xxx_0_0_0 maxoutbuf @@ -2872,7 +3281,7 @@ we shift the LO a little further _coordinate - (496, 184) + (392, 184) _rotation @@ -3045,7 +3454,7 @@ we shift the LO a little further _coordinate - (992, 68) + (888, 44) _rotation @@ -3088,7 +3497,7 @@ we shift the LO a little further _coordinate - (1384, 300) + (1296, 396) _rotation @@ -3127,7 +3536,7 @@ we shift the LO a little further _coordinate - (216, 148) + (112, 148) _rotation @@ -3241,7 +3650,7 @@ we shift the LO a little further _coordinate - (760, 44) + (656, 44) _rotation @@ -3406,14 +3815,38 @@ we shift the LO a little further - analog_quadrature_demod_cf_0_0 - dc_blocker_xx_0 + analog_quadrature_demod_cf_0_0_0 + dc_blocker_xx_0_0 0 0 - analog_quadrature_demod_cf_0_0_0 - dc_blocker_xx_0_0 + analog_quadrature_demod_cf_0_0_0_0 + blocks_moving_average_xx_0 + 0 + 0 + + + analog_quadrature_demod_cf_0_0_0_1 + low_pass_filter_1 + 0 + 0 + + + blocks_delay_0 + blocks_multiply_xx_0_0 + 0 + 0 + + + blocks_moving_average_xx_0 + blocks_vco_c_0 + 0 + 0 + + + blocks_multiply_xx_0_0 + low_pass_filter_0 0 0 @@ -3424,10 +3857,10 @@ we shift the LO a little further 0 - dc_blocker_xx_0 - digital_clock_recovery_mm_xx_0 + blocks_vco_c_0 + blocks_multiply_xx_0_0 0 - 0 + 1 dc_blocker_xx_0_0 @@ -3435,6 +3868,12 @@ we shift the LO a little further 0 0 + + dc_blocker_xx_0_0_0 + digital_clock_recovery_mm_xx_0 + 0 + 0 + digital_binary_slicer_fb_0 satnogs_frame_acquisition_0 @@ -3447,6 +3886,18 @@ we shift the LO a little further 0 0 + + low_pass_filter_0 + pfb_arb_resampler_xxx_0_0_0 + 0 + 0 + + + low_pass_filter_1 + dc_blocker_xx_0_0_0 + 0 + 0 + osmosdr_source_0 blocks_rotator_cc_0 @@ -3461,7 +3912,13 @@ we shift the LO a little further pfb_arb_resampler_xxx_0 - pfb_arb_resampler_xxx_0_0 + analog_quadrature_demod_cf_0_0_0_0 + 0 + 0 + + + pfb_arb_resampler_xxx_0 + blocks_delay_0 0 0 @@ -3478,8 +3935,8 @@ we shift the LO a little further 0 - pfb_arb_resampler_xxx_0_0 - analog_quadrature_demod_cf_0_0 + pfb_arb_resampler_xxx_0_0_0 + analog_quadrature_demod_cf_0_0_0_1 0 0 diff --git a/apps/flowgraphs/satellites/satnogs_reaktor_hello_world_fsk9600_decoder.py b/apps/flowgraphs/satellites/satnogs_reaktor_hello_world_fsk9600_decoder.py index cc74286..78d6a87 100755 --- a/apps/flowgraphs/satellites/satnogs_reaktor_hello_world_fsk9600_decoder.py +++ b/apps/flowgraphs/satellites/satnogs_reaktor_hello_world_fsk9600_decoder.py @@ -5,9 +5,10 @@ # Title: satnogs_reaktor_hello_world_fsk9600_decoder # Author: Manolis Surligas (surligas@gmail.com) # Description: FSK 9600 Decoder for the Reaktor-Hello-World satellite -# Generated: Mon Dec 3 11:51:46 2018 +# GNU Radio version: 3.7.13.5 ################################################## + from gnuradio import analog from gnuradio import blocks from gnuradio import digital @@ -70,11 +71,11 @@ class satnogs_reaktor_hello_world_fsk9600_decoder(gr.top_block): self.satnogs_frame_file_sink_0_1_0 = satnogs.frame_file_sink(decoded_data_file_path, 0) self.satnogs_frame_acquisition_0 = satnogs.frame_acquisition(1, [0xAA, 0xAA, 0xAA, 0xAA], 4, [0x35, 0x2E, 0x35, 0x2E], 3, 1, 256, 3, variable_whitening_0, 2048) self.satnogs_coarse_doppler_correction_cc_0 = satnogs.coarse_doppler_correction_cc(rx_freq, satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx)) - self.pfb_arb_resampler_xxx_0_0 = pfb.arb_resampler_ccf( + self.pfb_arb_resampler_xxx_0_0_0 = pfb.arb_resampler_ccf( (2.0*baudrate)/audio_samp_rate, taps=None, flt_size=32) - self.pfb_arb_resampler_xxx_0_0.declare_sample_delay(0) + self.pfb_arb_resampler_xxx_0_0_0.declare_sample_delay(0) self.pfb_arb_resampler_xxx_0 = pfb.arb_resampler_ccf( audio_samp_rate/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx), @@ -95,13 +96,22 @@ class satnogs_reaktor_hello_world_fsk9600_decoder(gr.top_block): self.osmosdr_source_0.set_antenna(satnogs.handle_rx_antenna(rx_sdr_device, antenna), 0) self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx), 0) - self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(2, 0.25*0.175*0.175, 0.5, 0.175, 0.005) + self.low_pass_filter_1 = filter.fir_filter_fff(1, firdes.low_pass( + 1, 2 * baudrate, baudrate * 0.60, baudrate / 8.0, firdes.WIN_HAMMING, 6.76)) + self.low_pass_filter_0 = filter.fir_filter_ccf(1, firdes.low_pass( + 1, audio_samp_rate, 0.75 * baudrate, 1000, firdes.WIN_HAMMING, 6.76)) + self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(2, 2 * math.pi / 100, 0.5, 0.5/8.0, 0.01) self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb() + self.dc_blocker_xx_0_0_0 = filter.dc_blocker_ff(1024, True) self.dc_blocker_xx_0_0 = filter.dc_blocker_ff(1024, True) - self.dc_blocker_xx_0 = filter.dc_blocker_ff(1024, True) + self.blocks_vco_c_0 = blocks.vco_c(audio_samp_rate, -audio_samp_rate, 1.0) self.blocks_rotator_cc_0 = blocks.rotator_cc(-2.0 * math.pi * (lo_offset / satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx))) + self.blocks_multiply_xx_0_0 = blocks.multiply_vcc(1) + self.blocks_moving_average_xx_0 = blocks.moving_average_ff(1024, 1.0/1024.0, 4096) + self.blocks_delay_0 = blocks.delay(gr.sizeof_gr_complex*1, 1024/2) + self.analog_quadrature_demod_cf_0_0_0_1 = analog.quadrature_demod_cf(1.2) + self.analog_quadrature_demod_cf_0_0_0_0 = analog.quadrature_demod_cf(1.0) self.analog_quadrature_demod_cf_0_0_0 = analog.quadrature_demod_cf(0.9) - self.analog_quadrature_demod_cf_0_0 = analog.quadrature_demod_cf(1.2) @@ -111,19 +121,27 @@ class satnogs_reaktor_hello_world_fsk9600_decoder(gr.top_block): self.msg_connect((self.satnogs_frame_acquisition_0, 'out'), (self.satnogs_frame_file_sink_0_1_0, 'frame')) self.msg_connect((self.satnogs_frame_acquisition_0, 'out'), (self.satnogs_udp_msg_sink_0_0, 'in')) self.msg_connect((self.satnogs_tcp_rigctl_msg_source_0, 'freq'), (self.satnogs_coarse_doppler_correction_cc_0, 'freq')) - self.connect((self.analog_quadrature_demod_cf_0_0, 0), (self.dc_blocker_xx_0, 0)) self.connect((self.analog_quadrature_demod_cf_0_0_0, 0), (self.dc_blocker_xx_0_0, 0)) + self.connect((self.analog_quadrature_demod_cf_0_0_0_0, 0), (self.blocks_moving_average_xx_0, 0)) + self.connect((self.analog_quadrature_demod_cf_0_0_0_1, 0), (self.low_pass_filter_1, 0)) + self.connect((self.blocks_delay_0, 0), (self.blocks_multiply_xx_0_0, 0)) + self.connect((self.blocks_moving_average_xx_0, 0), (self.blocks_vco_c_0, 0)) + self.connect((self.blocks_multiply_xx_0_0, 0), (self.low_pass_filter_0, 0)) self.connect((self.blocks_rotator_cc_0, 0), (self.satnogs_coarse_doppler_correction_cc_0, 0)) - self.connect((self.dc_blocker_xx_0, 0), (self.digital_clock_recovery_mm_xx_0, 0)) + self.connect((self.blocks_vco_c_0, 0), (self.blocks_multiply_xx_0_0, 1)) self.connect((self.dc_blocker_xx_0_0, 0), (self.satnogs_ogg_encoder_0, 0)) + self.connect((self.dc_blocker_xx_0_0_0, 0), (self.digital_clock_recovery_mm_xx_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self.satnogs_frame_acquisition_0, 0)) self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.digital_binary_slicer_fb_0, 0)) + self.connect((self.low_pass_filter_0, 0), (self.pfb_arb_resampler_xxx_0_0_0, 0)) + self.connect((self.low_pass_filter_1, 0), (self.dc_blocker_xx_0_0_0, 0)) self.connect((self.osmosdr_source_0, 0), (self.blocks_rotator_cc_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.analog_quadrature_demod_cf_0_0_0, 0)) - self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.pfb_arb_resampler_xxx_0_0, 0)) + self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.analog_quadrature_demod_cf_0_0_0_0, 0)) + self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.blocks_delay_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.satnogs_iq_sink_0, 0)) self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.satnogs_waterfall_sink_0, 0)) - self.connect((self.pfb_arb_resampler_xxx_0_0, 0), (self.analog_quadrature_demod_cf_0_0, 0)) + self.connect((self.pfb_arb_resampler_xxx_0_0_0, 0), (self.analog_quadrature_demod_cf_0_0_0_1, 0)) self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.pfb_arb_resampler_xxx_0, 0)) def get_antenna(self): @@ -138,7 +156,9 @@ class satnogs_reaktor_hello_world_fsk9600_decoder(gr.top_block): def set_baudrate(self, baudrate): self.baudrate = baudrate - self.pfb_arb_resampler_xxx_0_0.set_rate((2.0*self.baudrate)/self.audio_samp_rate) + self.pfb_arb_resampler_xxx_0_0_0.set_rate((2.0*self.baudrate)/self.audio_samp_rate) + self.low_pass_filter_1.set_taps(firdes.low_pass(1, 2 * self.baudrate, self.baudrate * 0.60, self.baudrate / 8.0, firdes.WIN_HAMMING, 6.76)) + self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, 0.75 * self.baudrate, 1000, firdes.WIN_HAMMING, 6.76)) def get_bb_gain(self): return self.bb_gain @@ -279,8 +299,9 @@ class satnogs_reaktor_hello_world_fsk9600_decoder(gr.top_block): def set_audio_samp_rate(self, audio_samp_rate): self.audio_samp_rate = audio_samp_rate - self.pfb_arb_resampler_xxx_0_0.set_rate((2.0*self.baudrate)/self.audio_samp_rate) + self.pfb_arb_resampler_xxx_0_0_0.set_rate((2.0*self.baudrate)/self.audio_samp_rate) self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) + self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, 0.75 * self.baudrate, 1000, firdes.WIN_HAMMING, 6.76)) def argument_parser(): From 60cbe5294b51a9549a7343e121575bde58576154 Mon Sep 17 00:00:00 2001 From: Manolis Surligas Date: Fri, 19 Jul 2019 22:48:43 +0300 Subject: [PATCH 15/24] Fix resampling ratio --- apps/flowgraphs/fsk_ax25.grc | 2 +- apps/flowgraphs/msk_ax25.grc | 2 +- apps/flowgraphs/satnogs_fsk_ax25.py | 9 ++++----- apps/flowgraphs/satnogs_msk_ax25.py | 7 +++---- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/apps/flowgraphs/fsk_ax25.grc b/apps/flowgraphs/fsk_ax25.grc index c742d9e..e48e177 100644 --- a/apps/flowgraphs/fsk_ax25.grc +++ b/apps/flowgraphs/fsk_ax25.grc @@ -2921,7 +2921,7 @@ we shift the LO a little further rrate - (2.0*baudrate)/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx) + (2.0*baudrate)/audio_samp_rate samp_delay diff --git a/apps/flowgraphs/msk_ax25.grc b/apps/flowgraphs/msk_ax25.grc index 4b94bbf..c42e5da 100644 --- a/apps/flowgraphs/msk_ax25.grc +++ b/apps/flowgraphs/msk_ax25.grc @@ -2921,7 +2921,7 @@ we shift the LO a little further rrate - (2.0*baudrate)/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx) + (2.0*baudrate)/audio_samp_rate samp_delay diff --git a/apps/flowgraphs/satnogs_fsk_ax25.py b/apps/flowgraphs/satnogs_fsk_ax25.py index 84f4d34..576ee1a 100755 --- a/apps/flowgraphs/satnogs_fsk_ax25.py +++ b/apps/flowgraphs/satnogs_fsk_ax25.py @@ -72,7 +72,7 @@ class satnogs_fsk_ax25(gr.top_block): self.satnogs_ax25_decoder_bm_0_0 = satnogs.ax25_decoder_bm('GND', 0, True, False, 1024) self.satnogs_ax25_decoder_bm_0 = satnogs.ax25_decoder_bm('GND', 0, True, True, 1024) self.pfb_arb_resampler_xxx_0_0_0 = pfb.arb_resampler_ccf( - (2.0*baudrate)/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx), + (2.0*baudrate)/audio_samp_rate, taps=None, flt_size=32) self.pfb_arb_resampler_xxx_0_0_0.declare_sample_delay(0) @@ -107,7 +107,7 @@ class satnogs_fsk_ax25(gr.top_block): self.blocks_vco_c_0 = blocks.vco_c(audio_samp_rate, -audio_samp_rate, 1.0) self.blocks_rotator_cc_0 = blocks.rotator_cc(-2.0 * math.pi * (lo_offset / satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx))) self.blocks_multiply_xx_0 = blocks.multiply_vcc(1) - self.blocks_moving_average_xx_0 = blocks.moving_average_ff(1024, 1.0/1024.0, 4096) + self.blocks_moving_average_xx_0 = blocks.moving_average_ff(1024, 1.0/1024.0, 4096) self.blocks_delay_0 = blocks.delay(gr.sizeof_gr_complex*1, 1024/2) self.analog_quadrature_demod_cf_0_0_0_0 = analog.quadrature_demod_cf(1.0) self.analog_quadrature_demod_cf_0_0_0 = analog.quadrature_demod_cf(0.9) @@ -159,7 +159,7 @@ class satnogs_fsk_ax25(gr.top_block): def set_baudrate(self, baudrate): self.baudrate = baudrate - self.pfb_arb_resampler_xxx_0_0_0.set_rate((2.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) + self.pfb_arb_resampler_xxx_0_0_0.set_rate((2.0*self.baudrate)/self.audio_samp_rate) self.low_pass_filter_1.set_taps(firdes.low_pass(1, 2 * self.baudrate, self.baudrate * 0.60, self.baudrate / 8.0, firdes.WIN_HAMMING, 6.76)) self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, 0.75 * self.baudrate, 1000, firdes.WIN_HAMMING, 6.76)) @@ -254,7 +254,6 @@ class satnogs_fsk_ax25(gr.top_block): def set_rx_sdr_device(self, rx_sdr_device): self.rx_sdr_device = rx_sdr_device - self.pfb_arb_resampler_xxx_0_0_0.set_rate((2.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.osmosdr_source_0.set_sample_rate(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.osmosdr_source_0.set_gain(satnogs.handle_rx_rf_gain(self.rx_sdr_device, self.rf_gain), 0) @@ -269,7 +268,6 @@ class satnogs_fsk_ax25(gr.top_block): def set_samp_rate_rx(self, samp_rate_rx): self.samp_rate_rx = samp_rate_rx - self.pfb_arb_resampler_xxx_0_0_0.set_rate((2.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.osmosdr_source_0.set_sample_rate(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx), 0) @@ -298,6 +296,7 @@ class satnogs_fsk_ax25(gr.top_block): def set_audio_samp_rate(self, audio_samp_rate): self.audio_samp_rate = audio_samp_rate + self.pfb_arb_resampler_xxx_0_0_0.set_rate((2.0*self.baudrate)/self.audio_samp_rate) self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, 0.75 * self.baudrate, 1000, firdes.WIN_HAMMING, 6.76)) diff --git a/apps/flowgraphs/satnogs_msk_ax25.py b/apps/flowgraphs/satnogs_msk_ax25.py index a0137fd..7e1f4f7 100755 --- a/apps/flowgraphs/satnogs_msk_ax25.py +++ b/apps/flowgraphs/satnogs_msk_ax25.py @@ -72,7 +72,7 @@ class satnogs_msk_ax25(gr.top_block): self.satnogs_ax25_decoder_bm_0_0 = satnogs.ax25_decoder_bm('GND', 0, True, False, 1024) self.satnogs_ax25_decoder_bm_0 = satnogs.ax25_decoder_bm('GND', 0, True, True, 1024) self.pfb_arb_resampler_xxx_0_0_0 = pfb.arb_resampler_ccf( - (2.0*baudrate)/satnogs.handle_samp_rate_rx(rx_sdr_device, samp_rate_rx), + (2.0*baudrate)/audio_samp_rate, taps=None, flt_size=32) self.pfb_arb_resampler_xxx_0_0_0.declare_sample_delay(0) @@ -159,7 +159,7 @@ class satnogs_msk_ax25(gr.top_block): def set_baudrate(self, baudrate): self.baudrate = baudrate - self.pfb_arb_resampler_xxx_0_0_0.set_rate((2.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) + self.pfb_arb_resampler_xxx_0_0_0.set_rate((2.0*self.baudrate)/self.audio_samp_rate) self.low_pass_filter_1.set_taps(firdes.low_pass(1, 2 * self.baudrate, self.baudrate * 0.60, self.baudrate / 8.0, firdes.WIN_HAMMING, 6.76)) self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, 0.75 * self.baudrate, 1000, firdes.WIN_HAMMING, 6.76)) @@ -254,7 +254,6 @@ class satnogs_msk_ax25(gr.top_block): def set_rx_sdr_device(self, rx_sdr_device): self.rx_sdr_device = rx_sdr_device - self.pfb_arb_resampler_xxx_0_0_0.set_rate((2.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.osmosdr_source_0.set_sample_rate(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.osmosdr_source_0.set_gain(satnogs.handle_rx_rf_gain(self.rx_sdr_device, self.rf_gain), 0) @@ -269,7 +268,6 @@ class satnogs_msk_ax25(gr.top_block): def set_samp_rate_rx(self, samp_rate_rx): self.samp_rate_rx = samp_rate_rx - self.pfb_arb_resampler_xxx_0_0_0.set_rate((2.0*self.baudrate)/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.osmosdr_source_0.set_sample_rate(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.osmosdr_source_0.set_bandwidth(satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx), 0) @@ -298,6 +296,7 @@ class satnogs_msk_ax25(gr.top_block): def set_audio_samp_rate(self, audio_samp_rate): self.audio_samp_rate = audio_samp_rate + self.pfb_arb_resampler_xxx_0_0_0.set_rate((2.0*self.baudrate)/self.audio_samp_rate) self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate/satnogs.handle_samp_rate_rx(self.rx_sdr_device, self.samp_rate_rx)) self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, 0.75 * self.baudrate, 1000, firdes.WIN_HAMMING, 6.76)) From 27394340e3947a3f840b582a63b2be3651029766 Mon Sep 17 00:00:00 2001 From: Julien Date: Mon, 18 Mar 2019 15:12:17 +0000 Subject: [PATCH 16/24] Update hw_settings.py to add support for USRP1 --- python/hw_settings.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/python/hw_settings.py b/python/hw_settings.py index f388583..b3a85fb 100644 --- a/python/hw_settings.py +++ b/python/hw_settings.py @@ -37,6 +37,9 @@ hw_tx_settings = {'usrpb200' : {'rf_gain' : 60.0, 'if_gain' : 0.0, hw_rx_settings = {'usrpb200' : {'rf_gain' : 50.0, 'if_gain' : 0.0, 'bb_gain' : 0.0, 'samp_rate' : 5e5, 'antenna' : 'TX/RX', 'dev_arg': 'uhd'}, + 'usrp1' : {'rf_gain' : 500.0, 'if_gain' : 30.0, + 'bb_gain' : 0.0, 'samp_rate' : 5e5, + 'antenna' : 'RX', 'dev_arg': 'uhd'}, 'usrp2' : {'rf_gain' : 50.0, 'if_gain' : 0.0, 'bb_gain' : 0.0, 'samp_rate' : 5e5, 'antenna' : 'TX/RX', 'dev_arg': 'uhd'}, From 05c82193cafb026a84c5897544fc6e43894168ec Mon Sep 17 00:00:00 2001 From: Manolis Surligas Date: Wed, 18 Jul 2018 13:39:00 +0300 Subject: [PATCH 17/24] Add contributors list and update versioning scheme --- CONTRIBUTORS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index e95f764..602f7e8 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -8,11 +8,11 @@ # Contributors * Corey Shields (cshields@gmail.com) -* LongHairedHacker(sebastian@sebastians-site.de) +* Sebastian Schumb (sebastian@sebastians-site.de) * Nikos Karamolegkos (nkaramolegos@csd.uoc.g) * Mark Jessop (vk5qi@rfhead.net) * Fabian P. Schmidt (kerel-fs@gmx.de) * Thanos Gkiolias (agiolias@csd.uoc.gr) * Patrick Dohmen (dl4pd@darc.de) * Kostis Triantayllakis (ctriant@csd.uoc.gr) -* Alexander Jenke \ No newline at end of file +* Alexander Jenke From 71be84ac858e6d9169d915970ae038a1f1cad836 Mon Sep 17 00:00:00 2001 From: LongHairedHacker Date: Sat, 30 Mar 2019 18:03:40 +0100 Subject: [PATCH 18/24] Added module Added sync detection to module --- grc/CMakeLists.txt | 9 ++- grc/satnogs_sstv_pd120_sink.xml | 31 ++++++++ include/satnogs/CMakeLists.txt | 7 +- include/satnogs/sstv_pd120_sink.h | 56 ++++++++++++++ lib/CMakeLists.txt | 3 +- lib/sstv_pd120_sink_impl.cc | 123 ++++++++++++++++++++++++++++++ lib/sstv_pd120_sink_impl.h | 55 +++++++++++++ swig/satnogs_swig0.i | 4 + 8 files changed, 280 insertions(+), 8 deletions(-) create mode 100644 grc/satnogs_sstv_pd120_sink.xml create mode 100644 include/satnogs/sstv_pd120_sink.h create mode 100644 lib/sstv_pd120_sink_impl.cc create mode 100644 lib/sstv_pd120_sink_impl.h diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt index 01034c8..d56f76a 100644 --- a/grc/CMakeLists.txt +++ b/grc/CMakeLists.txt @@ -24,7 +24,7 @@ list(APPEND debug_blocks satnogs_debug_msg_source.xml satnogs_debug_msg_source_raw.xml satnogs_leo_channel.xml - satnogs_cw_encoder.xml + satnogs_cw_encoder.xml ) list(APPEND enabled_blocks @@ -36,11 +36,11 @@ list(APPEND enabled_blocks satnogs_fox_telem_mm.xml satnogs_frame_file_sink.xml satnogs_iq_sink.xml - satnogs_lrpt_decoder.xml - satnogs_lrpt_sync.xml + satnogs_lrpt_decoder.xml + satnogs_lrpt_sync.xml satnogs_morse_decoder.xml satnogs_multi_format_msg_sink.xml - satnogs_ogg_encoder.xml + satnogs_ogg_encoder.xml satnogs_cw_to_symbol.xml satnogs_udp_msg_source.xml satnogs_tcp_rigctl_msg_source.xml @@ -53,6 +53,7 @@ list(APPEND enabled_blocks satnogs_noaa_apt_sink.xml satnogs_whitening.xml satnogs_frame_acquisition.xml + satnogs_sstv_pd120_sink.xml ) if(${INCLUDE_DEBUG_BLOCKS}) diff --git a/grc/satnogs_sstv_pd120_sink.xml b/grc/satnogs_sstv_pd120_sink.xml new file mode 100644 index 0000000..95f830a --- /dev/null +++ b/grc/satnogs_sstv_pd120_sink.xml @@ -0,0 +1,31 @@ + + SSTV PD120 sink + satnogs_sstv_pd120_sink + [SATNOGS] + import satnogs + satnogs.sstv_pd120_sink($filename_png, $split) + + Output PNG Filename + filename_png + + file_save + + + Split + split + False + bool + + + + + in + float + + diff --git a/include/satnogs/CMakeLists.txt b/include/satnogs/CMakeLists.txt index 7af04b4..0ec4861 100644 --- a/include/satnogs/CMakeLists.txt +++ b/include/satnogs/CMakeLists.txt @@ -24,7 +24,7 @@ list(APPEND DEBUG_HEADER_FILES morse_debug_source.h debug_msg_source_raw.h debug_msg_source.h - cw_encoder.h + cw_encoder.h ) list(APPEND HEADER_FILES @@ -37,7 +37,7 @@ list(APPEND HEADER_FILES morse.h morse_decoder.h multi_format_msg_sink.h - ogg_encoder.h + ogg_encoder.h cw_to_symbol.h utils.h udp_msg_source.h @@ -59,6 +59,7 @@ list(APPEND HEADER_FILES noaa_apt_sink.h frame_file_sink.h iq_sink.h + sstv_pd120_sink.h ) if(${INCLUDE_DEBUG_BLOCKS}) @@ -76,4 +77,4 @@ install(FILES frame_acquisition.h shift_reg.h golay24.h DESTINATION include/satnogs -) \ No newline at end of file +) diff --git a/include/satnogs/sstv_pd120_sink.h b/include/satnogs/sstv_pd120_sink.h new file mode 100644 index 0000000..f1a47e4 --- /dev/null +++ b/include/satnogs/sstv_pd120_sink.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module + * + * Copyright (C) 2017, Libre Space Foundation + * + * This program 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 of the License, or + * (at your option) any later version. + * + * This program 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 this program. If not, see . + */ + + + +#ifndef INCLUDED_SATNOGS_SSTV_PD120_SINK_H +#define INCLUDED_SATNOGS_SSTV_PD120_SINK_H + +#include +#include + +namespace gr { + namespace satnogs { + + /*! + * \brief <+description of block+> + * \ingroup satnogs + * + */ + class SATNOGS_API sstv_pd120_sink : virtual public gr::sync_block + { + public: + typedef boost::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of satnogs::sstv_pd120_sink. + * + * To avoid accidental use of raw pointers, satnogs::sstv_pd120_sink's + * constructor is in a private implementation + * class. satnogs::sstv_pd120_sink::make is the public interface for + * creating new instances. + */ + static sptr make(const char *filename_png, bool split); + }; + + } // namespace satnogs +} // namespace gr + +#endif /* INCLUDED_SATNOGS_SSTV_PD120_SINK_H */ diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 998fa24..e71ce2d 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -74,7 +74,8 @@ list(APPEND satnogs_sources lrpt_decoder_impl.cc frame_acquisition_impl.cc shift_reg.cc - golay24.cc) + golay24.cc + sstv_pd120_sink_impl.cc) if(${INCLUDE_DEBUG_BLOCKS}) list(APPEND satnogs_sources ${satnogs_debug_sources}) diff --git a/lib/sstv_pd120_sink_impl.cc b/lib/sstv_pd120_sink_impl.cc new file mode 100644 index 0000000..8750ae5 --- /dev/null +++ b/lib/sstv_pd120_sink_impl.cc @@ -0,0 +1,123 @@ +/* -*- c++ -*- */ +/* + * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module + * + * Copyright (C) 2018, Libre Space Foundation + * + * This program 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 of the License, or + * (at your option) any later version. + * + * This program 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 this program. If not, see . + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "sstv_pd120_sink_impl.h" + +namespace gr { + namespace satnogs { + + const size_t image_width = 640; + const size_t sync_length = 105; + const size_t sync_thresh = 100; + const size_t porch_length = 10; + const size_t line_length = sync_length + porch_length + 4 * image_width; + + const float max_dev = 600; + const float center = 1750; + const float min_freq = 1200; + const float max_freq = 2300; + + const float color_low = 1500; + const float color_high = max_freq; + + + sstv_pd120_sink::sptr + sstv_pd120_sink::make(const char *filename_png, bool split) + { + return gnuradio::get_initial_sptr + (new sstv_pd120_sink_impl(filename_png, split)); + } + + /* + * The private constructor + */ + sstv_pd120_sink_impl::sstv_pd120_sink_impl(const char *filename_png, bool split) + : gr::sync_block("sstv_pd120_sink", + gr::io_signature::make (1, 1, sizeof(float)), + gr::io_signature::make (0, 0, 0)), + d_filename_png (filename_png), + d_split (split), + d_has_sync(false) + { + set_history(sync_length); + d_line = new float[line_length]; + } + + /* + * Our virtual destructor. + */ + sstv_pd120_sink_impl::~sstv_pd120_sink_impl() + { + delete[] d_line; + } + + float + sstv_pd120_sink_impl::to_frequency(float sample) { + float freq = center + sample * max_dev; + freq = std::max(min_freq, freq); + freq = std::min(max_freq, freq); + return freq; + } + + bool + sstv_pd120_sink_impl::is_sync(size_t pos, const float *samples) { + size_t count = 0; + for(size_t i = 0; i < sync_length; i++) { + float sample = to_frequency(samples[pos - (sync_length - 1) + i]); + if(sample < color_low) { + count += 1; + } + } + + bool res = count > sync_length && !d_has_sync; + d_has_sync = count > sync_length; + + std::cout << "Count: " << count << " " << d_has_sync << std::endl; + + return res; + } + + int + sstv_pd120_sink_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const float *in = (const float *) input_items[0]; + + std::cout << "foo" << std::endl; + for (size_t i = sync_length - 1; + i < noutput_items + sync_length - 1; i++) { + + if(is_sync(i, in)) { + std::cout << "Sync: " << i << std::endl; + } + } + + // Tell runtime system how many output items we produced. + return noutput_items; + } + + } /* namespace satnogs */ +} /* namespace gr */ diff --git a/lib/sstv_pd120_sink_impl.h b/lib/sstv_pd120_sink_impl.h new file mode 100644 index 0000000..b831563 --- /dev/null +++ b/lib/sstv_pd120_sink_impl.h @@ -0,0 +1,55 @@ +/* -*- c++ -*- */ +/* + * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module + * + * Copyright (C) 2018, Libre Space Foundation + * + * This program 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 of the License, or + * (at your option) any later version. + * + * This program 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 this program. If not, see . + */ + + +#ifndef INCLUDED_SATNOGS_SSTV_PD120_SINK_IMPL_H +#define INCLUDED_SATNOGS_SSTV_PD120_SINK_IMPL_H + +#include + +namespace gr { + namespace satnogs { + + class sstv_pd120_sink_impl : public sstv_pd120_sink + { + private: + std::string d_filename_png; + bool d_split; + bool d_has_sync; + + float *d_line; + + float to_frequency(float sample); + bool is_sync(size_t pos, const float *samples); + + public: + sstv_pd120_sink_impl(const char *filename_png, bool split); + ~sstv_pd120_sink_impl(); + + // Where all the action really happens + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } // namespace satnogs +} // namespace gr + +#endif /* INCLUDED_SATNOGS_SSTV_PD120_SINK_IMPL_H */ diff --git a/swig/satnogs_swig0.i b/swig/satnogs_swig0.i index 40d4064..b9933b9 100644 --- a/swig/satnogs_swig0.i +++ b/swig/satnogs_swig0.i @@ -33,6 +33,7 @@ #include "satnogs/ogg_encoder.h" #include "satnogs/ogg_source.h" #include "satnogs/noaa_apt_sink.h" +#include "satnogs/sstv_pd120_sink.h" #include "satnogs/frame_file_sink.h" #include "satnogs/iq_sink.h" #include "satnogs/quad_demod_filter_ff.h" @@ -103,6 +104,9 @@ GR_SWIG_BLOCK_MAGIC2(satnogs, ogg_source); %include "satnogs/noaa_apt_sink.h" GR_SWIG_BLOCK_MAGIC2(satnogs, noaa_apt_sink); +%include "satnogs/sstv_pd120_sink.h" +GR_SWIG_BLOCK_MAGIC2(satnogs, sstv_pd120_sink); + %include "satnogs/frame_file_sink.h" GR_SWIG_BLOCK_MAGIC2(satnogs, frame_file_sink); From 09e9ac688cff11275cc081a7d56edb3378c7baac Mon Sep 17 00:00:00 2001 From: LongHairedHacker Date: Sun, 31 Mar 2019 17:35:28 +0200 Subject: [PATCH 19/24] Added color conversion and stub for rendering --- lib/sstv_pd120_sink_impl.cc | 82 +++++++++++++++++++++++++++++++++---- lib/sstv_pd120_sink_impl.h | 12 ++++++ 2 files changed, 87 insertions(+), 7 deletions(-) diff --git a/lib/sstv_pd120_sink_impl.cc b/lib/sstv_pd120_sink_impl.cc index 8750ae5..ba79f96 100644 --- a/lib/sstv_pd120_sink_impl.cc +++ b/lib/sstv_pd120_sink_impl.cc @@ -29,6 +29,7 @@ namespace gr { namespace satnogs { const size_t image_width = 640; + const size_t image_height = 496; const size_t sync_length = 105; const size_t sync_thresh = 100; const size_t porch_length = 10; @@ -59,7 +60,10 @@ namespace gr { gr::io_signature::make (0, 0, 0)), d_filename_png (filename_png), d_split (split), - d_has_sync(false) + d_has_sync(false), + d_initial_sync(true), + d_line_pos(0), + d_image_y (0) { set_history(sync_length); d_line = new float[line_length]; @@ -81,6 +85,33 @@ namespace gr { return freq; } + int + sstv_pd120_sink_impl::to_color(float sample) { + sample = (sample - color_low) / (color_high - color_low); + int color = int(sample * 255); + color = std::max(color, 0); + color = std::min(color, 255); + return color; + } + + void + ycbcr_to_rgb(int ycbcr[3], int rgb[3]) { + int y = ycbcr[0]; + int cb = ycbcr[1]; + int cr = ycbcr[2]; + + //https://stackoverflow.com/questions/4041840/function-to-convert-ycbcr-to-rgb/15333019#15333019 + cr = cr - 128; + cb = cb - 128; + int r = y + 45 * cr / 32; + int g = y - (11 * cb + 23 * cr) / 32; + int b = y + 113 * cb / 64; + + rgb[0] = r; + rgb[1] = g; + rgb[2] = b; + } + bool sstv_pd120_sink_impl::is_sync(size_t pos, const float *samples) { size_t count = 0; @@ -91,14 +122,42 @@ namespace gr { } } - bool res = count > sync_length && !d_has_sync; - d_has_sync = count > sync_length; + bool res = count > sync_thresh && !d_has_sync; + d_has_sync = count > sync_thresh; - std::cout << "Count: " << count << " " << d_has_sync << std::endl; + d_initial_sync = false; return res; } + + void + sstv_pd120_sink_impl::render_line() { + int start_pos = d_line_pos - sync_length - 4 * image_width; + if(start_pos < 0) { + return; + } + + for(size_t x = 0; x < image_width; x++) { + int y0 = to_color(d_line[start_pos + x]); + int cr = to_color(d_line[start_pos + image_width + x]); + int cb = to_color(d_line[start_pos + 2 * image_width + x]); + int y1 = to_color(d_line[start_pos + 3 * image_width + x]); + + int rgb0[3]; + int ycrcb0[] = {y0, cr, cb}; + ycbcr_to_rgb(ycrcb0, rgb0); + + int rgb1[3]; + int ycrcb1[] = {y1, cr, cb}; + ycbcr_to_rgb(ycrcb1, rgb1); + + //Todo: Write pixels + } + + d_image_y += 2; + } + int sstv_pd120_sink_impl::work(int noutput_items, gr_vector_const_void_star &input_items, @@ -106,12 +165,21 @@ namespace gr { { const float *in = (const float *) input_items[0]; - std::cout << "foo" << std::endl; for (size_t i = sync_length - 1; i < noutput_items + sync_length - 1; i++) { - if(is_sync(i, in)) { - std::cout << "Sync: " << i << std::endl; + float sample = to_frequency(in[i]); + d_line[d_line_pos] = sample; + d_line_pos++; + + if(is_sync(i, in) || d_line_pos >= line_length) { + if(d_initial_sync) { + d_image_y = 0; + } + else if(!d_initial_sync && d_line_pos > line_length - porch_length) { + std::cout << "Rendering after: " << d_line_pos << std::endl; + } + d_line_pos = 0; } } diff --git a/lib/sstv_pd120_sink_impl.h b/lib/sstv_pd120_sink_impl.h index b831563..ddb47d2 100644 --- a/lib/sstv_pd120_sink_impl.h +++ b/lib/sstv_pd120_sink_impl.h @@ -24,6 +24,9 @@ #include +#define PNG_DEBUG 3 +#include + namespace gr { namespace satnogs { @@ -33,12 +36,21 @@ namespace gr { std::string d_filename_png; bool d_split; bool d_has_sync; + bool d_initial_sync; float *d_line; + size_t d_line_pos; + size_t d_image_y; + + png::image d_image; float to_frequency(float sample); + int to_color(float sample); + void ycbcr_to_rgb(int ycbcr[3], int rgb[3]); bool is_sync(size_t pos, const float *samples); + void render_line(); + public: sstv_pd120_sink_impl(const char *filename_png, bool split); ~sstv_pd120_sink_impl(); From c0740f1f61713762eafa9b676cd385c73d1091bf Mon Sep 17 00:00:00 2001 From: LongHairedHacker Date: Mon, 1 Apr 2019 00:03:58 +0200 Subject: [PATCH 20/24] First version that renders images Dropped split parameter --- grc/satnogs_sstv_pd120_sink.xml | 16 +------------- include/satnogs/sstv_pd120_sink.h | 2 +- lib/sstv_pd120_sink_impl.cc | 35 ++++++++++++++++++------------- lib/sstv_pd120_sink_impl.h | 3 +-- 4 files changed, 23 insertions(+), 33 deletions(-) diff --git a/grc/satnogs_sstv_pd120_sink.xml b/grc/satnogs_sstv_pd120_sink.xml index 95f830a..a034929 100644 --- a/grc/satnogs_sstv_pd120_sink.xml +++ b/grc/satnogs_sstv_pd120_sink.xml @@ -3,27 +3,13 @@ satnogs_sstv_pd120_sink [SATNOGS] import satnogs - satnogs.sstv_pd120_sink($filename_png, $split) + satnogs.sstv_pd120_sink($filename_png) Output PNG Filename filename_png file_save - - Split - split - False - bool - - - in float diff --git a/include/satnogs/sstv_pd120_sink.h b/include/satnogs/sstv_pd120_sink.h index f1a47e4..891eb74 100644 --- a/include/satnogs/sstv_pd120_sink.h +++ b/include/satnogs/sstv_pd120_sink.h @@ -47,7 +47,7 @@ namespace gr { * class. satnogs::sstv_pd120_sink::make is the public interface for * creating new instances. */ - static sptr make(const char *filename_png, bool split); + static sptr make(const char *filename_png); }; } // namespace satnogs diff --git a/lib/sstv_pd120_sink_impl.cc b/lib/sstv_pd120_sink_impl.cc index ba79f96..5cb050c 100644 --- a/lib/sstv_pd120_sink_impl.cc +++ b/lib/sstv_pd120_sink_impl.cc @@ -45,21 +45,20 @@ namespace gr { sstv_pd120_sink::sptr - sstv_pd120_sink::make(const char *filename_png, bool split) + sstv_pd120_sink::make(const char *filename_png) { return gnuradio::get_initial_sptr - (new sstv_pd120_sink_impl(filename_png, split)); + (new sstv_pd120_sink_impl(filename_png)); } /* * The private constructor */ - sstv_pd120_sink_impl::sstv_pd120_sink_impl(const char *filename_png, bool split) + sstv_pd120_sink_impl::sstv_pd120_sink_impl(const char *filename_png) : gr::sync_block("sstv_pd120_sink", gr::io_signature::make (1, 1, sizeof(float)), gr::io_signature::make (0, 0, 0)), d_filename_png (filename_png), - d_split (split), d_has_sync(false), d_initial_sync(true), d_line_pos(0), @@ -67,6 +66,7 @@ namespace gr { { set_history(sync_length); d_line = new float[line_length]; + d_image = png::image(image_width, image_height); } /* @@ -88,14 +88,14 @@ namespace gr { int sstv_pd120_sink_impl::to_color(float sample) { sample = (sample - color_low) / (color_high - color_low); - int color = int(sample * 255); - color = std::max(color, 0); - color = std::min(color, 255); - return color; + sample = sample * 255.0f; + sample = std::max(sample, 0.0f); + sample = std::min(sample, 255.0f); + return int(sample); } void - ycbcr_to_rgb(int ycbcr[3], int rgb[3]) { + sstv_pd120_sink_impl::ycbcr_to_rgb(int ycbcr[3], int rgb[3]) { int y = ycbcr[0]; int cb = ycbcr[1]; int cr = ycbcr[2]; @@ -144,18 +144,22 @@ namespace gr { int cb = to_color(d_line[start_pos + 2 * image_width + x]); int y1 = to_color(d_line[start_pos + 3 * image_width + x]); - int rgb0[3]; - int ycrcb0[] = {y0, cr, cb}; + int rgb0[3] = {0, 0, 0}; + int ycrcb0[] = {y0, cb, cr}; ycbcr_to_rgb(ycrcb0, rgb0); - int rgb1[3]; - int ycrcb1[] = {y1, cr, cb}; - ycbcr_to_rgb(ycrcb1, rgb1); + d_image.set_pixel(x, d_image_y, png::rgb_pixel(rgb0[0], rgb0[1], rgb0[2])); - //Todo: Write pixels + int rgb1[] = {0, 0, 0}; + int ycrcb1[] = {y1, cb, cr}; + ycbcr_to_rgb(ycrcb1, rgb1); + d_image.set_pixel(x, d_image_y + 1, png::rgb_pixel(rgb1[0], rgb1[1], rgb1[2])); } d_image_y += 2; + + std::cout << "Writing " << d_filename_png << std::endl; + d_image.write(d_filename_png); } int @@ -178,6 +182,7 @@ namespace gr { } else if(!d_initial_sync && d_line_pos > line_length - porch_length) { std::cout << "Rendering after: " << d_line_pos << std::endl; + render_line(); } d_line_pos = 0; } diff --git a/lib/sstv_pd120_sink_impl.h b/lib/sstv_pd120_sink_impl.h index ddb47d2..329f4a1 100644 --- a/lib/sstv_pd120_sink_impl.h +++ b/lib/sstv_pd120_sink_impl.h @@ -34,7 +34,6 @@ namespace gr { { private: std::string d_filename_png; - bool d_split; bool d_has_sync; bool d_initial_sync; @@ -52,7 +51,7 @@ namespace gr { void render_line(); public: - sstv_pd120_sink_impl(const char *filename_png, bool split); + sstv_pd120_sink_impl(const char *filename_png); ~sstv_pd120_sink_impl(); // Where all the action really happens From 33a4f9f5c5925930e2f4cbe3cab636a0b8079d4b Mon Sep 17 00:00:00 2001 From: LongHairedHacker Date: Mon, 1 Apr 2019 00:27:53 +0200 Subject: [PATCH 21/24] Fixed intial sync, clamped rgb values --- lib/.clang_complete | 1 + lib/sstv_pd120_sink_impl.cc | 11 +++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) create mode 100644 lib/.clang_complete diff --git a/lib/.clang_complete b/lib/.clang_complete new file mode 100644 index 0000000..b817a53 --- /dev/null +++ b/lib/.clang_complete @@ -0,0 +1 @@ +-I.. diff --git a/lib/sstv_pd120_sink_impl.cc b/lib/sstv_pd120_sink_impl.cc index 5cb050c..a25bf84 100644 --- a/lib/sstv_pd120_sink_impl.cc +++ b/lib/sstv_pd120_sink_impl.cc @@ -107,9 +107,9 @@ namespace gr { int g = y - (11 * cb + 23 * cr) / 32; int b = y + 113 * cb / 64; - rgb[0] = r; - rgb[1] = g; - rgb[2] = b; + rgb[0] = std::min(255, std::max(r, 0)); + rgb[1] = std::min(255, std::max(g, 0)); + rgb[2] = std::min(255, std::max(b, 0)); } bool @@ -117,6 +117,7 @@ namespace gr { size_t count = 0; for(size_t i = 0; i < sync_length; i++) { float sample = to_frequency(samples[pos - (sync_length - 1) + i]); + //std::cout << sample << std::endl; if(sample < color_low) { count += 1; } @@ -125,7 +126,9 @@ namespace gr { bool res = count > sync_thresh && !d_has_sync; d_has_sync = count > sync_thresh; - d_initial_sync = false; + if(res) { + d_initial_sync = false; + } return res; } From 12b4ef63ba8835a44e17d4021d0950b7f7f367c8 Mon Sep 17 00:00:00 2001 From: LongHairedHacker Date: Thu, 4 Apr 2019 20:29:29 +0200 Subject: [PATCH 22/24] Splitting images works --- grc/satnogs_sstv_pd120_sink.xml | 2 +- lib/sstv_pd120_sink_impl.cc | 17 ++++++++++++++--- lib/sstv_pd120_sink_impl.h | 1 + 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/grc/satnogs_sstv_pd120_sink.xml b/grc/satnogs_sstv_pd120_sink.xml index a034929..077853c 100644 --- a/grc/satnogs_sstv_pd120_sink.xml +++ b/grc/satnogs_sstv_pd120_sink.xml @@ -1,7 +1,7 @@ SSTV PD120 sink satnogs_sstv_pd120_sink - [SATNOGS] + [satnogs] import satnogs satnogs.sstv_pd120_sink($filename_png) diff --git a/lib/sstv_pd120_sink_impl.cc b/lib/sstv_pd120_sink_impl.cc index a25bf84..d3674bd 100644 --- a/lib/sstv_pd120_sink_impl.cc +++ b/lib/sstv_pd120_sink_impl.cc @@ -62,7 +62,8 @@ namespace gr { d_has_sync(false), d_initial_sync(true), d_line_pos(0), - d_image_y (0) + d_image_y (0), + d_num_image(0) { set_history(sync_length); d_line = new float[line_length]; @@ -159,10 +160,20 @@ namespace gr { d_image.set_pixel(x, d_image_y + 1, png::rgb_pixel(rgb1[0], rgb1[1], rgb1[2])); } + std::string file_name = std::string(d_filename_png) + "_" + std::to_string(d_num_image) + ".png"; + std::cout << "Writing " << file_name << std::endl; + d_image.write(file_name.c_str()); + + std::cout << "Line number: " << d_image_y << std::endl; + d_image_y += 2; - std::cout << "Writing " << d_filename_png << std::endl; - d_image.write(d_filename_png); + if(d_image_y >= image_height){ + std::cout << "Finished image, resetting." << std::endl; + d_image_y = 0; + d_initial_sync = true; + d_num_image++; + } } int diff --git a/lib/sstv_pd120_sink_impl.h b/lib/sstv_pd120_sink_impl.h index 329f4a1..36d734a 100644 --- a/lib/sstv_pd120_sink_impl.h +++ b/lib/sstv_pd120_sink_impl.h @@ -40,6 +40,7 @@ namespace gr { float *d_line; size_t d_line_pos; size_t d_image_y; + size_t d_num_image; png::image d_image; From 756f5db292d28e757f52047a1b1b1178f43a3288 Mon Sep 17 00:00:00 2001 From: LongHairedHacker Date: Fri, 5 Apr 2019 23:33:45 +0200 Subject: [PATCH 23/24] Added flowgraph --- apps/CMakeLists.txt | 1 + apps/flowgraphs/satnogs_sstv_pd120_demod.py | 356 ++ apps/flowgraphs/sstv_pd120_demod.grc | 3319 +++++++++++++++++++ 3 files changed, 3676 insertions(+) create mode 100755 apps/flowgraphs/satnogs_sstv_pd120_demod.py create mode 100644 apps/flowgraphs/sstv_pd120_demod.grc diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index b54538f..332ac66 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -37,5 +37,6 @@ GR_PYTHON_INSTALL( flowgraphs/satnogs_fsk_ax25.py flowgraphs/satnogs_msk_ax25.py flowgraphs/satnogs_bpsk_ax25.py + flowgraphs/satnogs_sstv_pd120_demod.py DESTINATION bin ) diff --git a/apps/flowgraphs/satnogs_sstv_pd120_demod.py b/apps/flowgraphs/satnogs_sstv_pd120_demod.py new file mode 100755 index 0000000..6315b41 --- /dev/null +++ b/apps/flowgraphs/satnogs_sstv_pd120_demod.py @@ -0,0 +1,356 @@ +#!/usr/bin/env python2 +# -*- coding: utf-8 -*- +################################################## +# GNU Radio Python Flow Graph +# Title: SSTV PD120 Demodulation +# Author: Sebastian Schumb (sebastian@sebastains-site.de) +# Description: A PD120 SSTV demodulator +# Generated: Fri Apr 5 23:30:50 2019 +################################################## + +from gnuradio import analog +from gnuradio import eng_notation +from gnuradio import filter +from gnuradio import gr +from gnuradio.eng_option import eng_option +from gnuradio.filter import firdes +from optparse import OptionParser +import math +import osmosdr +import satnogs +import time + + +class satnogs_sstv_pd120_demod(gr.top_block): + + def __init__(self, antenna=satnogs.not_set_antenna, bb_gain=satnogs.not_set_rx_bb_gain, decoded_data_file_path='/tmp/.satnogs/data/data', dev_args=satnogs.not_set_dev_args, doppler_correction_per_sec=20, enable_iq_dump=0, file_path='test.ogg', if_gain=satnogs.not_set_rx_if_gain, iq_file_path='/tmp/iq.dat', lo_offset=100e3, ppm=0, rf_gain=satnogs.not_set_rx_rf_gain, rigctl_port=4532, rx_freq=100e6, rx_sdr_device='usrpb200', waterfall_file_path='/tmp/waterfall.dat'): + gr.top_block.__init__(self, "SSTV PD120 Demodulation") + + ################################################## + # Parameters + ################################################## + self.antenna = antenna + self.bb_gain = bb_gain + self.decoded_data_file_path = decoded_data_file_path + self.dev_args = dev_args + self.doppler_correction_per_sec = doppler_correction_per_sec + self.enable_iq_dump = enable_iq_dump + self.file_path = file_path + self.if_gain = if_gain + self.iq_file_path = iq_file_path + self.lo_offset = lo_offset + self.ppm = ppm + self.rf_gain = rf_gain + self.rigctl_port = rigctl_port + self.rx_freq = rx_freq + self.rx_sdr_device = rx_sdr_device + self.waterfall_file_path = waterfall_file_path + + ################################################## + # Variables + ################################################## + self.samp_rate_rx = samp_rate_rx = satnogs.hw_rx_settings[rx_sdr_device]['samp_rate'] + self.xlate_filter_taps = xlate_filter_taps = firdes.low_pass(1, samp_rate_rx, 125000, 25000, firdes.WIN_HAMMING, 6.76) + + self.taps = taps = firdes.low_pass(12.0, samp_rate_rx, 100e3, 60000, firdes.WIN_HAMMING, 6.76) + + self.max_modulation_freq = max_modulation_freq = 3000 + self.filter_rate = filter_rate = 250000 + self.deviation = deviation = 5000 + self.audio_samp_rate = audio_samp_rate = 48000 + + ################################################## + # Blocks + ################################################## + self.satnogs_waterfall_sink_0 = satnogs.waterfall_sink(audio_samp_rate, 0.0, 10, 1024, waterfall_file_path, 1) + self.satnogs_tcp_rigctl_msg_source_0 = satnogs.tcp_rigctl_msg_source("127.0.0.1", rigctl_port, False, 1000/doppler_correction_per_sec, 1500) + self.satnogs_sstv_pd120_sink_0 = satnogs.sstv_pd120_sink(decoded_data_file_path) + self.satnogs_ogg_encoder_0 = satnogs.ogg_encoder(file_path, audio_samp_rate, 1.0) + self.satnogs_iq_sink_0 = satnogs.iq_sink(32767, iq_file_path, False, enable_iq_dump) + self.satnogs_coarse_doppler_correction_cc_0 = satnogs.coarse_doppler_correction_cc(rx_freq, samp_rate_rx) + self.rational_resampler_xxx_0 = filter.rational_resampler_fff( + interpolation=5263, + decimation=12000, + taps=None, + fractional_bw=None, + ) + self.osmosdr_source_0 = osmosdr.source( args="numchan=" + str(1) + " " + satnogs.handle_rx_dev_args(rx_sdr_device, dev_args) ) + self.osmosdr_source_0.set_sample_rate(samp_rate_rx) + self.osmosdr_source_0.set_center_freq(rx_freq - lo_offset, 0) + self.osmosdr_source_0.set_freq_corr(ppm, 0) + self.osmosdr_source_0.set_dc_offset_mode(2, 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(satnogs.handle_rx_rf_gain(rx_sdr_device, rf_gain), 0) + self.osmosdr_source_0.set_if_gain(satnogs.handle_rx_if_gain(rx_sdr_device, if_gain), 0) + self.osmosdr_source_0.set_bb_gain(satnogs.handle_rx_bb_gain(rx_sdr_device, bb_gain), 0) + self.osmosdr_source_0.set_antenna(satnogs.handle_rx_antenna(rx_sdr_device, antenna), 0) + self.osmosdr_source_0.set_bandwidth(samp_rate_rx, 0) + + self.low_pass_filter_0_0 = filter.fir_filter_fff(1, firdes.low_pass( + 1, 12000, 1500, 1000, firdes.WIN_HAMMING, 6.76)) + self.low_pass_filter_0 = filter.fir_filter_ccf(1, firdes.low_pass( + 1, audio_samp_rate, deviation+max_modulation_freq, 3000, firdes.WIN_HAMMING, 6.76)) + self.freq_xlating_fir_filter_xxx_0_0 = filter.freq_xlating_fir_filter_ccc(4, (63, ), 1750, audio_samp_rate) + self.freq_xlating_fir_filter_xxx_0 = filter.freq_xlating_fir_filter_ccc(int(samp_rate_rx/filter_rate), (xlate_filter_taps), lo_offset, samp_rate_rx) + self.blks2_rational_resampler_xxx_1 = filter.rational_resampler_ccc( + interpolation=24, + decimation=125, + taps=None, + fractional_bw=None, + ) + self.analog_quadrature_demod_cf_0 = analog.quadrature_demod_cf((2*math.pi*deviation)/audio_samp_rate) + self.analog_nbfm_rx_0 = analog.nbfm_rx( + audio_rate=12000, + quad_rate=12000, + tau=75e-6, + max_dev=600, + ) + + + + ################################################## + # Connections + ################################################## + self.msg_connect((self.satnogs_tcp_rigctl_msg_source_0, 'freq'), (self.satnogs_coarse_doppler_correction_cc_0, 'freq')) + self.connect((self.analog_nbfm_rx_0, 0), (self.low_pass_filter_0_0, 0)) + self.connect((self.analog_quadrature_demod_cf_0, 0), (self.satnogs_ogg_encoder_0, 0)) + self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.low_pass_filter_0, 0)) + self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.satnogs_iq_sink_0, 0)) + self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.satnogs_waterfall_sink_0, 0)) + self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.blks2_rational_resampler_xxx_1, 0)) + self.connect((self.freq_xlating_fir_filter_xxx_0_0, 0), (self.analog_nbfm_rx_0, 0)) + self.connect((self.low_pass_filter_0, 0), (self.analog_quadrature_demod_cf_0, 0)) + self.connect((self.low_pass_filter_0, 0), (self.freq_xlating_fir_filter_xxx_0_0, 0)) + self.connect((self.low_pass_filter_0_0, 0), (self.rational_resampler_xxx_0, 0)) + self.connect((self.osmosdr_source_0, 0), (self.satnogs_coarse_doppler_correction_cc_0, 0)) + self.connect((self.rational_resampler_xxx_0, 0), (self.satnogs_sstv_pd120_sink_0, 0)) + self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.freq_xlating_fir_filter_xxx_0, 0)) + + def get_antenna(self): + return self.antenna + + def set_antenna(self, antenna): + self.antenna = antenna + self.osmosdr_source_0.set_antenna(satnogs.handle_rx_antenna(self.rx_sdr_device, self.antenna), 0) + + def get_bb_gain(self): + return self.bb_gain + + def set_bb_gain(self, bb_gain): + self.bb_gain = bb_gain + self.osmosdr_source_0.set_bb_gain(satnogs.handle_rx_bb_gain(self.rx_sdr_device, self.bb_gain), 0) + + def get_decoded_data_file_path(self): + return self.decoded_data_file_path + + def set_decoded_data_file_path(self, decoded_data_file_path): + self.decoded_data_file_path = decoded_data_file_path + + def get_dev_args(self): + return self.dev_args + + def set_dev_args(self, dev_args): + self.dev_args = dev_args + + def get_doppler_correction_per_sec(self): + return self.doppler_correction_per_sec + + def set_doppler_correction_per_sec(self, doppler_correction_per_sec): + self.doppler_correction_per_sec = doppler_correction_per_sec + + def get_enable_iq_dump(self): + return self.enable_iq_dump + + def set_enable_iq_dump(self, enable_iq_dump): + self.enable_iq_dump = enable_iq_dump + + def get_file_path(self): + return self.file_path + + def set_file_path(self, file_path): + self.file_path = file_path + + def get_if_gain(self): + return self.if_gain + + def set_if_gain(self, if_gain): + self.if_gain = if_gain + self.osmosdr_source_0.set_if_gain(satnogs.handle_rx_if_gain(self.rx_sdr_device, self.if_gain), 0) + + def get_iq_file_path(self): + return self.iq_file_path + + def set_iq_file_path(self, iq_file_path): + self.iq_file_path = iq_file_path + + def get_lo_offset(self): + return self.lo_offset + + def set_lo_offset(self, lo_offset): + self.lo_offset = lo_offset + self.osmosdr_source_0.set_center_freq(self.rx_freq - self.lo_offset, 0) + self.freq_xlating_fir_filter_xxx_0.set_center_freq(self.lo_offset) + + def get_ppm(self): + return self.ppm + + def set_ppm(self, ppm): + self.ppm = ppm + self.osmosdr_source_0.set_freq_corr(self.ppm, 0) + + def get_rf_gain(self): + return self.rf_gain + + def set_rf_gain(self, rf_gain): + self.rf_gain = rf_gain + self.osmosdr_source_0.set_gain(satnogs.handle_rx_rf_gain(self.rx_sdr_device, self.rf_gain), 0) + + def get_rigctl_port(self): + return self.rigctl_port + + def set_rigctl_port(self, rigctl_port): + self.rigctl_port = rigctl_port + + def get_rx_freq(self): + return self.rx_freq + + def set_rx_freq(self, rx_freq): + self.rx_freq = rx_freq + self.satnogs_coarse_doppler_correction_cc_0.set_new_freq_locked(self.rx_freq) + self.osmosdr_source_0.set_center_freq(self.rx_freq - self.lo_offset, 0) + + def get_rx_sdr_device(self): + return self.rx_sdr_device + + def set_rx_sdr_device(self, rx_sdr_device): + self.rx_sdr_device = rx_sdr_device + self.set_samp_rate_rx(satnogs.hw_rx_settings[self.rx_sdr_device]['samp_rate']) + self.osmosdr_source_0.set_gain(satnogs.handle_rx_rf_gain(self.rx_sdr_device, self.rf_gain), 0) + self.osmosdr_source_0.set_if_gain(satnogs.handle_rx_if_gain(self.rx_sdr_device, self.if_gain), 0) + self.osmosdr_source_0.set_bb_gain(satnogs.handle_rx_bb_gain(self.rx_sdr_device, self.bb_gain), 0) + self.osmosdr_source_0.set_antenna(satnogs.handle_rx_antenna(self.rx_sdr_device, self.antenna), 0) + + def get_waterfall_file_path(self): + return self.waterfall_file_path + + def set_waterfall_file_path(self, waterfall_file_path): + self.waterfall_file_path = waterfall_file_path + + def get_samp_rate_rx(self): + return self.samp_rate_rx + + def set_samp_rate_rx(self, samp_rate_rx): + self.samp_rate_rx = samp_rate_rx + self.set_xlate_filter_taps(firdes.low_pass(1, self.samp_rate_rx, 125000, 25000, firdes.WIN_HAMMING, 6.76)) + self.osmosdr_source_0.set_sample_rate(self.samp_rate_rx) + self.osmosdr_source_0.set_bandwidth(self.samp_rate_rx, 0) + + def get_xlate_filter_taps(self): + return self.xlate_filter_taps + + def set_xlate_filter_taps(self, xlate_filter_taps): + self.xlate_filter_taps = xlate_filter_taps + self.freq_xlating_fir_filter_xxx_0.set_taps((self.xlate_filter_taps)) + + def get_taps(self): + return self.taps + + def set_taps(self, taps): + self.taps = taps + + def get_max_modulation_freq(self): + return self.max_modulation_freq + + def set_max_modulation_freq(self, max_modulation_freq): + self.max_modulation_freq = max_modulation_freq + self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, self.deviation+self.max_modulation_freq, 3000, firdes.WIN_HAMMING, 6.76)) + + def get_filter_rate(self): + return self.filter_rate + + def set_filter_rate(self, filter_rate): + self.filter_rate = filter_rate + + def get_deviation(self): + return self.deviation + + def set_deviation(self, deviation): + self.deviation = deviation + self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, self.deviation+self.max_modulation_freq, 3000, firdes.WIN_HAMMING, 6.76)) + self.analog_quadrature_demod_cf_0.set_gain((2*math.pi*self.deviation)/self.audio_samp_rate) + + def get_audio_samp_rate(self): + return self.audio_samp_rate + + def set_audio_samp_rate(self, audio_samp_rate): + self.audio_samp_rate = audio_samp_rate + self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.audio_samp_rate, self.deviation+self.max_modulation_freq, 3000, firdes.WIN_HAMMING, 6.76)) + self.analog_quadrature_demod_cf_0.set_gain((2*math.pi*self.deviation)/self.audio_samp_rate) + + +def argument_parser(): + description = 'A PD120 SSTV demodulator' + parser = OptionParser(usage="%prog: [options]", option_class=eng_option, description=description) + parser.add_option( + "", "--antenna", dest="antenna", type="string", default=satnogs.not_set_antenna, + help="Set antenna [default=%default]") + parser.add_option( + "", "--bb-gain", dest="bb_gain", type="eng_float", default=eng_notation.num_to_str(satnogs.not_set_rx_bb_gain), + help="Set bb_gain [default=%default]") + parser.add_option( + "", "--decoded-data-file-path", dest="decoded_data_file_path", type="string", default='/tmp/.satnogs/data/data', + help="Set decoded_data_file_path [default=%default]") + parser.add_option( + "", "--dev-args", dest="dev_args", type="string", default=satnogs.not_set_dev_args, + help="Set dev_args [default=%default]") + parser.add_option( + "", "--doppler-correction-per-sec", dest="doppler_correction_per_sec", type="intx", default=20, + help="Set doppler_correction_per_sec [default=%default]") + parser.add_option( + "", "--enable-iq-dump", dest="enable_iq_dump", type="intx", default=0, + help="Set enable_iq_dump [default=%default]") + parser.add_option( + "", "--file-path", dest="file_path", type="string", default='test.ogg', + help="Set file_path [default=%default]") + parser.add_option( + "", "--if-gain", dest="if_gain", type="eng_float", default=eng_notation.num_to_str(satnogs.not_set_rx_if_gain), + help="Set if_gain [default=%default]") + parser.add_option( + "", "--iq-file-path", dest="iq_file_path", type="string", default='/tmp/iq.dat', + help="Set iq_file_path [default=%default]") + parser.add_option( + "", "--lo-offset", dest="lo_offset", type="eng_float", default=eng_notation.num_to_str(100e3), + help="Set lo_offset [default=%default]") + parser.add_option( + "", "--ppm", dest="ppm", type="intx", default=0, + help="Set ppm [default=%default]") + parser.add_option( + "", "--rf-gain", dest="rf_gain", type="eng_float", default=eng_notation.num_to_str(satnogs.not_set_rx_rf_gain), + help="Set rf_gain [default=%default]") + parser.add_option( + "", "--rigctl-port", dest="rigctl_port", type="intx", default=4532, + help="Set rigctl_port [default=%default]") + parser.add_option( + "", "--rx-freq", dest="rx_freq", type="eng_float", default=eng_notation.num_to_str(100e6), + help="Set rx_freq [default=%default]") + parser.add_option( + "", "--rx-sdr-device", dest="rx_sdr_device", type="string", default='usrpb200', + help="Set rx_sdr_device [default=%default]") + parser.add_option( + "", "--waterfall-file-path", dest="waterfall_file_path", type="string", default='/tmp/waterfall.dat', + help="Set waterfall_file_path [default=%default]") + return parser + + +def main(top_block_cls=satnogs_sstv_pd120_demod, options=None): + if options is None: + options, _ = argument_parser().parse_args() + + tb = top_block_cls(antenna=options.antenna, bb_gain=options.bb_gain, decoded_data_file_path=options.decoded_data_file_path, dev_args=options.dev_args, doppler_correction_per_sec=options.doppler_correction_per_sec, enable_iq_dump=options.enable_iq_dump, file_path=options.file_path, if_gain=options.if_gain, iq_file_path=options.iq_file_path, lo_offset=options.lo_offset, ppm=options.ppm, rf_gain=options.rf_gain, rigctl_port=options.rigctl_port, rx_freq=options.rx_freq, rx_sdr_device=options.rx_sdr_device, waterfall_file_path=options.waterfall_file_path) + tb.start() + tb.wait() + + +if __name__ == '__main__': + main() diff --git a/apps/flowgraphs/sstv_pd120_demod.grc b/apps/flowgraphs/sstv_pd120_demod.grc new file mode 100644 index 0000000..27e5998 --- /dev/null +++ b/apps/flowgraphs/sstv_pd120_demod.grc @@ -0,0 +1,3319 @@ + + + + Thu May 5 00:22:45 2016 + + options + + author + Sebastian Schumb (sebastian@sebastains-site.de) + + + window_size + 3000, 3000 + + + category + Custom + + + comment + + + + description + A PD120 SSTV demodulator + + + _enabled + True + + + _coordinate + (8, 8) + + + _rotation + 0 + + + generate_options + no_gui + + + hier_block_src_path + .: + + + id + satnogs_sstv_pd120_demod + + + max_nouts + 0 + + + qt_qss_theme + + + + realtime_scheduling + + + + run_command + {python} -u {filename} + + + run_options + run + + + run + True + + + sizing_mode + fixed + + + thread_safe_setters + + + + title + SSTV PD120 Demodulation + + + placement + (0,0) + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (606, 785) + + + _rotation + 0 + + + id + audio_samp_rate + + + value + 48000 + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (223, 793) + + + _rotation + 0 + + + id + deviation + + + value + 5000 + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (741, 785) + + + _rotation + 0 + + + id + filter_rate + + + value + 250000 + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (318, 793) + + + _rotation + 0 + + + id + max_modulation_freq + + + value + 3000 + + + + variable + + comment + SDR device +TX sampling rate + + + _enabled + True + + + _coordinate + (478, 745) + + + _rotation + 0 + + + id + samp_rate_rx + + + value + satnogs.hw_rx_settings[rx_sdr_device]['samp_rate'] + + + + variable_low_pass_filter_taps + + beta + 6.76 + + + comment + + + + cutoff_freq + 100e3 + + + _enabled + 1 + + + _coordinate + (48, 716) + + + _rotation + 0 + + + gain + 12.0 + + + id + taps + + + samp_rate + samp_rate_rx + + + width + 60000 + + + win + firdes.WIN_HAMMING + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (837, 785) + + + _rotation + 0 + + + id + xlate_filter_taps + + + value + firdes.low_pass(1, samp_rate_rx, 125000, 25000, firdes.WIN_HAMMING, 6.76) + + + + analog_nbfm_rx + + audio_rate + 12000 + + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (964, 562) + + + _rotation + 180 + + + id + analog_nbfm_rx_0 + + + max_dev + 600 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + quad_rate + 12000 + + + tau + 75e-6 + + + + analog_quadrature_demod_cf + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (1204, 474) + + + _rotation + 180 + + + gain + (2*math.pi*deviation)/audio_samp_rate + + + id + analog_quadrature_demod_cf_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + + parameter + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (422, 945) + + + _rotation + 0 + + + id + antenna + + + label + + + + short_id + + + + hide + none + + + type + string + + + value + satnogs.not_set_antenna + + + + parameter + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (334, 945) + + + _rotation + 0 + + + id + bb_gain + + + label + + + + short_id + + + + hide + none + + + type + eng_float + + + value + satnogs.not_set_rx_bb_gain + + + + rational_resampler_xxx + + alias + + + + comment + + + + affinity + + + + decim + 125 + + + _enabled + True + + + fbw + 0 + + + _coordinate + (837, 267) + + + _rotation + 0 + + + id + blks2_rational_resampler_xxx_1 + + + interp + 24 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + taps + [] + + + type + ccc + + + + parameter + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (741, 945) + + + _rotation + 0 + + + id + decoded_data_file_path + + + label + + + + short_id + + + + hide + none + + + type + string + + + value + /tmp/.satnogs/data/data + + + + parameter + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (47, 945) + + + _rotation + 0 + + + id + dev_args + + + label + + + + short_id + + + + hide + none + + + type + string + + + value + satnogs.not_set_dev_args + + + + parameter + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (47, 865) + + + _rotation + 0 + + + id + doppler_correction_per_sec + + + label + + + + short_id + + + + hide + none + + + type + intx + + + value + 20 + + + + parameter + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (510, 945) + + + _rotation + 0 + + + id + enable_iq_dump + + + label + + + + short_id + + + + hide + none + + + type + intx + + + value + 0 + + + + parameter + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (534, 865) + + + _rotation + 180 + + + id + file_path + + + label + + + + short_id + + + + hide + none + + + type + string + + + value + test.ogg + + + + freq_xlating_fir_filter_xxx + + alias + + + + center_freq + lo_offset + + + comment + + + + affinity + + + + decim + int(samp_rate_rx/filter_rate) + + + _enabled + 1 + + + _coordinate + (566, 267) + + + _rotation + 0 + + + id + freq_xlating_fir_filter_xxx_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + samp_rate + samp_rate_rx + + + taps + xlate_filter_taps + + + type + ccc + + + + freq_xlating_fir_filter_xxx + + alias + + + + center_freq + 1750 + + + comment + + + + affinity + + + + decim + 4 + + + _enabled + True + + + _coordinate + (1164, 562) + + + _rotation + 180 + + + id + freq_xlating_fir_filter_xxx_0_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + samp_rate + audio_samp_rate + + + taps + 63 + + + type + ccc + + + + parameter + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (247, 945) + + + _rotation + 0 + + + id + if_gain + + + label + + + + short_id + + + + hide + none + + + type + eng_float + + + value + satnogs.not_set_rx_if_gain + + + + parameter + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (630, 945) + + + _rotation + 0 + + + id + iq_file_path + + + label + + + + short_id + + + + hide + none + + + type + string + + + value + /tmp/iq.dat + + + + parameter + + alias + + + + comment + To avoid the SDR carrier at the DC +we shift the LO a little further + + + _enabled + True + + + _coordinate + (909, 865) + + + _rotation + 0 + + + id + lo_offset + + + label + + + + short_id + + + + hide + none + + + type + eng_float + + + value + 100e3 + + + + low_pass_filter + + beta + 6.76 + + + alias + + + + comment + Using the Carson bandwidth rule for filter width: +width = 2*(deviation + max_modulation_freq). +For the majority of FM transmissions we can expect +max_modulation_freq = 3000 + + + affinity + + + + cutoff_freq + deviation+max_modulation_freq + + + decim + 1 + + + _enabled + True + + + type + fir_filter_ccf + + + _coordinate + (1060, 243) + + + _rotation + 0 + + + gain + 1 + + + id + low_pass_filter_0 + + + interp + 1 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + samp_rate + audio_samp_rate + + + width + 3000 + + + win + firdes.WIN_HAMMING + + + + low_pass_filter + + beta + 6.76 + + + alias + + + + comment + + + + affinity + + + + cutoff_freq + 1500 + + + decim + 1 + + + _enabled + True + + + type + fir_filter_fff + + + _coordinate + (781, 538) + + + _rotation + 180 + + + gain + 1 + + + id + low_pass_filter_0_0 + + + interp + 1 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + samp_rate + 12000 + + + width + 1000 + + + win + firdes.WIN_HAMMING + + + + osmosdr_source + + alias + + + + ant0 + satnogs.handle_rx_antenna(rx_sdr_device, antenna) + + + bb_gain0 + satnogs.handle_rx_bb_gain(rx_sdr_device, bb_gain) + + + bw0 + samp_rate_rx + + + dc_offset_mode0 + 2 + + + corr0 + ppm + + + freq0 + rx_freq - lo_offset + + + gain_mode0 + False + + + if_gain0 + satnogs.handle_rx_if_gain(rx_sdr_device, if_gain) + + + iq_balance_mode0 + 0 + + + gain0 + satnogs.handle_rx_rf_gain(rx_sdr_device, rf_gain) + + + ant10 + + + + bb_gain10 + 20 + + + bw10 + 0 + + + dc_offset_mode10 + 0 + + + corr10 + 0 + + + freq10 + 100e6 + + + gain_mode10 + False + + + if_gain10 + 20 + + + iq_balance_mode10 + 0 + + + gain10 + 10 + + + ant11 + + + + bb_gain11 + 20 + + + bw11 + 0 + + + dc_offset_mode11 + 0 + + + corr11 + 0 + + + freq11 + 100e6 + + + gain_mode11 + False + + + if_gain11 + 20 + + + iq_balance_mode11 + 0 + + + gain11 + 10 + + + ant12 + + + + bb_gain12 + 20 + + + bw12 + 0 + + + dc_offset_mode12 + 0 + + + corr12 + 0 + + + freq12 + 100e6 + + + gain_mode12 + False + + + if_gain12 + 20 + + + iq_balance_mode12 + 0 + + + gain12 + 10 + + + ant13 + + + + bb_gain13 + 20 + + + bw13 + 0 + + + dc_offset_mode13 + 0 + + + corr13 + 0 + + + freq13 + 100e6 + + + gain_mode13 + False + + + if_gain13 + 20 + + + iq_balance_mode13 + 0 + + + gain13 + 10 + + + ant14 + + + + bb_gain14 + 20 + + + bw14 + 0 + + + dc_offset_mode14 + 0 + + + corr14 + 0 + + + freq14 + 100e6 + + + gain_mode14 + False + + + if_gain14 + 20 + + + iq_balance_mode14 + 0 + + + gain14 + 10 + + + ant15 + + + + bb_gain15 + 20 + + + bw15 + 0 + + + dc_offset_mode15 + 0 + + + corr15 + 0 + + + freq15 + 100e6 + + + gain_mode15 + False + + + if_gain15 + 20 + + + iq_balance_mode15 + 0 + + + gain15 + 10 + + + ant16 + + + + bb_gain16 + 20 + + + bw16 + 0 + + + dc_offset_mode16 + 0 + + + corr16 + 0 + + + freq16 + 100e6 + + + gain_mode16 + False + + + if_gain16 + 20 + + + iq_balance_mode16 + 0 + + + gain16 + 10 + + + ant17 + + + + bb_gain17 + 20 + + + bw17 + 0 + + + dc_offset_mode17 + 0 + + + corr17 + 0 + + + freq17 + 100e6 + + + gain_mode17 + False + + + if_gain17 + 20 + + + iq_balance_mode17 + 0 + + + gain17 + 10 + + + ant18 + + + + bb_gain18 + 20 + + + bw18 + 0 + + + dc_offset_mode18 + 0 + + + corr18 + 0 + + + freq18 + 100e6 + + + gain_mode18 + False + + + if_gain18 + 20 + + + iq_balance_mode18 + 0 + + + gain18 + 10 + + + ant19 + + + + bb_gain19 + 20 + + + bw19 + 0 + + + dc_offset_mode19 + 0 + + + corr19 + 0 + + + freq19 + 100e6 + + + gain_mode19 + False + + + if_gain19 + 20 + + + iq_balance_mode19 + 0 + + + gain19 + 10 + + + ant1 + + + + bb_gain1 + 20 + + + bw1 + 0 + + + dc_offset_mode1 + 0 + + + corr1 + 0 + + + freq1 + 100e6 + + + gain_mode1 + False + + + if_gain1 + 20 + + + iq_balance_mode1 + 0 + + + gain1 + 10 + + + ant20 + + + + bb_gain20 + 20 + + + bw20 + 0 + + + dc_offset_mode20 + 0 + + + corr20 + 0 + + + freq20 + 100e6 + + + gain_mode20 + False + + + if_gain20 + 20 + + + iq_balance_mode20 + 0 + + + gain20 + 10 + + + ant21 + + + + bb_gain21 + 20 + + + bw21 + 0 + + + dc_offset_mode21 + 0 + + + corr21 + 0 + + + freq21 + 100e6 + + + gain_mode21 + False + + + if_gain21 + 20 + + + iq_balance_mode21 + 0 + + + gain21 + 10 + + + ant22 + + + + bb_gain22 + 20 + + + bw22 + 0 + + + dc_offset_mode22 + 0 + + + corr22 + 0 + + + freq22 + 100e6 + + + gain_mode22 + False + + + if_gain22 + 20 + + + iq_balance_mode22 + 0 + + + gain22 + 10 + + + ant23 + + + + bb_gain23 + 20 + + + bw23 + 0 + + + dc_offset_mode23 + 0 + + + corr23 + 0 + + + freq23 + 100e6 + + + gain_mode23 + False + + + if_gain23 + 20 + + + iq_balance_mode23 + 0 + + + gain23 + 10 + + + ant24 + + + + bb_gain24 + 20 + + + bw24 + 0 + + + dc_offset_mode24 + 0 + + + corr24 + 0 + + + freq24 + 100e6 + + + gain_mode24 + False + + + if_gain24 + 20 + + + iq_balance_mode24 + 0 + + + gain24 + 10 + + + ant25 + + + + bb_gain25 + 20 + + + bw25 + 0 + + + dc_offset_mode25 + 0 + + + corr25 + 0 + + + freq25 + 100e6 + + + gain_mode25 + False + + + if_gain25 + 20 + + + iq_balance_mode25 + 0 + + + gain25 + 10 + + + ant26 + + + + bb_gain26 + 20 + + + bw26 + 0 + + + dc_offset_mode26 + 0 + + + corr26 + 0 + + + freq26 + 100e6 + + + gain_mode26 + False + + + if_gain26 + 20 + + + iq_balance_mode26 + 0 + + + gain26 + 10 + + + ant27 + + + + bb_gain27 + 20 + + + bw27 + 0 + + + dc_offset_mode27 + 0 + + + corr27 + 0 + + + freq27 + 100e6 + + + gain_mode27 + False + + + if_gain27 + 20 + + + iq_balance_mode27 + 0 + + + gain27 + 10 + + + ant28 + + + + bb_gain28 + 20 + + + bw28 + 0 + + + dc_offset_mode28 + 0 + + + corr28 + 0 + + + freq28 + 100e6 + + + gain_mode28 + False + + + if_gain28 + 20 + + + iq_balance_mode28 + 0 + + + gain28 + 10 + + + ant29 + + + + bb_gain29 + 20 + + + bw29 + 0 + + + dc_offset_mode29 + 0 + + + corr29 + 0 + + + freq29 + 100e6 + + + gain_mode29 + False + + + if_gain29 + 20 + + + iq_balance_mode29 + 0 + + + gain29 + 10 + + + ant2 + + + + bb_gain2 + 20 + + + bw2 + 0 + + + dc_offset_mode2 + 0 + + + corr2 + 0 + + + freq2 + 100e6 + + + gain_mode2 + False + + + if_gain2 + 20 + + + iq_balance_mode2 + 0 + + + gain2 + 10 + + + ant30 + + + + bb_gain30 + 20 + + + bw30 + 0 + + + dc_offset_mode30 + 0 + + + corr30 + 0 + + + freq30 + 100e6 + + + gain_mode30 + False + + + if_gain30 + 20 + + + iq_balance_mode30 + 0 + + + gain30 + 10 + + + ant31 + + + + bb_gain31 + 20 + + + bw31 + 0 + + + dc_offset_mode31 + 0 + + + corr31 + 0 + + + freq31 + 100e6 + + + gain_mode31 + False + + + if_gain31 + 20 + + + iq_balance_mode31 + 0 + + + gain31 + 10 + + + ant3 + + + + bb_gain3 + 20 + + + bw3 + 0 + + + dc_offset_mode3 + 0 + + + corr3 + 0 + + + freq3 + 100e6 + + + gain_mode3 + False + + + if_gain3 + 20 + + + iq_balance_mode3 + 0 + + + gain3 + 10 + + + ant4 + + + + bb_gain4 + 20 + + + bw4 + 0 + + + dc_offset_mode4 + 0 + + + corr4 + 0 + + + freq4 + 100e6 + + + gain_mode4 + False + + + if_gain4 + 20 + + + iq_balance_mode4 + 0 + + + gain4 + 10 + + + ant5 + + + + bb_gain5 + 20 + + + bw5 + 0 + + + dc_offset_mode5 + 0 + + + corr5 + 0 + + + freq5 + 100e6 + + + gain_mode5 + False + + + if_gain5 + 20 + + + iq_balance_mode5 + 0 + + + gain5 + 10 + + + ant6 + + + + bb_gain6 + 20 + + + bw6 + 0 + + + dc_offset_mode6 + 0 + + + corr6 + 0 + + + freq6 + 100e6 + + + gain_mode6 + False + + + if_gain6 + 20 + + + iq_balance_mode6 + 0 + + + gain6 + 10 + + + ant7 + + + + bb_gain7 + 20 + + + bw7 + 0 + + + dc_offset_mode7 + 0 + + + corr7 + 0 + + + freq7 + 100e6 + + + gain_mode7 + False + + + if_gain7 + 20 + + + iq_balance_mode7 + 0 + + + gain7 + 10 + + + ant8 + + + + bb_gain8 + 20 + + + bw8 + 0 + + + dc_offset_mode8 + 0 + + + corr8 + 0 + + + freq8 + 100e6 + + + gain_mode8 + False + + + if_gain8 + 20 + + + iq_balance_mode8 + 0 + + + gain8 + 10 + + + ant9 + + + + bb_gain9 + 20 + + + bw9 + 0 + + + dc_offset_mode9 + 0 + + + corr9 + 0 + + + freq9 + 100e6 + + + gain_mode9 + False + + + if_gain9 + 20 + + + iq_balance_mode9 + 0 + + + gain9 + 10 + + + comment + + + + affinity + + + + args + satnogs.handle_rx_dev_args(rx_sdr_device, dev_args) + + + _enabled + 1 + + + _coordinate + (16, 376) + + + _rotation + 0 + + + id + osmosdr_source_0 + + + maxoutbuf + 0 + + + clock_source0 + + + + time_source0 + + + + clock_source1 + + + + time_source1 + + + + clock_source2 + + + + time_source2 + + + + clock_source3 + + + + time_source3 + + + + clock_source4 + + + + time_source4 + + + + clock_source5 + + + + time_source5 + + + + clock_source6 + + + + time_source6 + + + + clock_source7 + + + + time_source7 + + + + minoutbuf + 0 + + + nchan + 1 + + + num_mboards + 1 + + + type + fc32 + + + sample_rate + samp_rate_rx + + + sync + + + + + parameter + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (805, 865) + + + _rotation + 0 + + + id + ppm + + + label + + + + short_id + + + + hide + none + + + type + intx + + + value + 0 + + + + rational_resampler_xxx + + alias + + + + comment + + + + affinity + + + + decim + 12000 + + + _enabled + True + + + fbw + 0 + + + _coordinate + (590, 562) + + + _rotation + 180 + + + id + rational_resampler_xxx_0 + + + interp + 5263 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + taps + + + + type + fff + + + + parameter + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (151, 945) + + + _rotation + 0 + + + id + rf_gain + + + label + + + + short_id + + + + hide + none + + + type + eng_float + + + value + satnogs.not_set_rx_rf_gain + + + + parameter + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (334, 865) + + + _rotation + 0 + + + id + rigctl_port + + + label + + + + short_id + + + + hide + none + + + type + intx + + + value + 4532 + + + + parameter + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (438, 865) + + + _rotation + 0 + + + id + rx_freq + + + label + + + + short_id + + + + hide + none + + + type + eng_float + + + value + 100e6 + + + + parameter + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (215, 865) + + + _rotation + 0 + + + id + rx_sdr_device + + + label + + + + short_id + + + + hide + none + + + type + string + + + value + usrpb200 + + + + satnogs_coarse_doppler_correction_cc + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (318, 263) + + + _rotation + 0 + + + id + satnogs_coarse_doppler_correction_cc_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + sampling_rate + samp_rate_rx + + + target_freq + rx_freq + + + + satnogs_iq_sink + + append + False + + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + filename + iq_file_path + + + _coordinate + (1060, 155) + + + _rotation + 0 + + + id + satnogs_iq_sink_0 + + + scale + 32767 + + + status + enable_iq_dump + + + + satnogs_ogg_encoder + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + filename + file_path + + + _coordinate + (1004, 458) + + + _rotation + 180 + + + id + satnogs_ogg_encoder_0 + + + quality + 1.0 + + + samp_rate + audio_samp_rate + + + + satnogs_sstv_pd120_sink + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (342, 586) + + + _rotation + 180 + + + id + satnogs_sstv_pd120_sink_0 + + + filename_png + decoded_data_file_path + + + + satnogs_tcp_rigctl_msg_source + + alias + + + + comment + + + + affinity + + + + _enabled + 1 + + + _coordinate + (16, 204) + + + _rotation + 0 + + + id + satnogs_tcp_rigctl_msg_source_0 + + + addr + "127.0.0.1" + + + mtu + 1500 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + mode + False + + + port + rigctl_port + + + interval + 1000/doppler_correction_per_sec + + + + satnogs_waterfall_sink + + alias + + + + center_freq + 0.0 + + + comment + + + + affinity + + + + _enabled + True + + + fft_size + 1024 + + + filename + waterfall_file_path + + + _coordinate + (1060, 3) + + + _rotation + 0 + + + id + satnogs_waterfall_sink_0 + + + mode + 1 + + + pps + 10 + + + samp_rate + audio_samp_rate + + + + parameter + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (645, 865) + + + _rotation + 0 + + + id + waterfall_file_path + + + label + + + + short_id + + + + hide + none + + + type + string + + + value + /tmp/waterfall.dat + + + + analog_nbfm_rx_0 + low_pass_filter_0_0 + 0 + 0 + + + analog_quadrature_demod_cf_0 + satnogs_ogg_encoder_0 + 0 + 0 + + + blks2_rational_resampler_xxx_1 + low_pass_filter_0 + 0 + 0 + + + blks2_rational_resampler_xxx_1 + satnogs_iq_sink_0 + 0 + 0 + + + blks2_rational_resampler_xxx_1 + satnogs_waterfall_sink_0 + 0 + 0 + + + freq_xlating_fir_filter_xxx_0 + blks2_rational_resampler_xxx_1 + 0 + 0 + + + freq_xlating_fir_filter_xxx_0_0 + analog_nbfm_rx_0 + 0 + 0 + + + low_pass_filter_0 + analog_quadrature_demod_cf_0 + 0 + 0 + + + low_pass_filter_0 + freq_xlating_fir_filter_xxx_0_0 + 0 + 0 + + + low_pass_filter_0_0 + rational_resampler_xxx_0 + 0 + 0 + + + osmosdr_source_0 + satnogs_coarse_doppler_correction_cc_0 + 0 + 0 + + + rational_resampler_xxx_0 + satnogs_sstv_pd120_sink_0 + 0 + 0 + + + satnogs_coarse_doppler_correction_cc_0 + freq_xlating_fir_filter_xxx_0 + 0 + 0 + + + satnogs_tcp_rigctl_msg_source_0 + satnogs_coarse_doppler_correction_cc_0 + freq + freq + + From 274f5027d48ad57690fa7c08e706fc553abc8182 Mon Sep 17 00:00:00 2001 From: LongHairedHacker Date: Wed, 5 Jun 2019 19:02:21 +0200 Subject: [PATCH 24/24] Fixed missing FM decoding stage --- apps/flowgraphs/satnogs_sstv_pd120_demod.py | 7 +- apps/flowgraphs/sstv_pd120_demod.grc | 81 ++++++++++++++++++--- 2 files changed, 74 insertions(+), 14 deletions(-) diff --git a/apps/flowgraphs/satnogs_sstv_pd120_demod.py b/apps/flowgraphs/satnogs_sstv_pd120_demod.py index 6315b41..30c17c0 100755 --- a/apps/flowgraphs/satnogs_sstv_pd120_demod.py +++ b/apps/flowgraphs/satnogs_sstv_pd120_demod.py @@ -5,9 +5,10 @@ # Title: SSTV PD120 Demodulation # Author: Sebastian Schumb (sebastian@sebastains-site.de) # Description: A PD120 SSTV demodulator -# Generated: Fri Apr 5 23:30:50 2019 +# GNU Radio version: 3.7.13.5 ################################################## + from gnuradio import analog from gnuradio import eng_notation from gnuradio import filter @@ -91,6 +92,7 @@ class satnogs_sstv_pd120_demod(gr.top_block): 1, 12000, 1500, 1000, firdes.WIN_HAMMING, 6.76)) self.low_pass_filter_0 = filter.fir_filter_ccf(1, firdes.low_pass( 1, audio_samp_rate, deviation+max_modulation_freq, 3000, firdes.WIN_HAMMING, 6.76)) + self.hilbert_fc_0 = filter.hilbert_fc(65, firdes.WIN_HAMMING, 6.76) self.freq_xlating_fir_filter_xxx_0_0 = filter.freq_xlating_fir_filter_ccc(4, (63, ), 1750, audio_samp_rate) self.freq_xlating_fir_filter_xxx_0 = filter.freq_xlating_fir_filter_ccc(int(samp_rate_rx/filter_rate), (xlate_filter_taps), lo_offset, samp_rate_rx) self.blks2_rational_resampler_xxx_1 = filter.rational_resampler_ccc( @@ -114,14 +116,15 @@ class satnogs_sstv_pd120_demod(gr.top_block): ################################################## self.msg_connect((self.satnogs_tcp_rigctl_msg_source_0, 'freq'), (self.satnogs_coarse_doppler_correction_cc_0, 'freq')) self.connect((self.analog_nbfm_rx_0, 0), (self.low_pass_filter_0_0, 0)) + self.connect((self.analog_quadrature_demod_cf_0, 0), (self.hilbert_fc_0, 0)) self.connect((self.analog_quadrature_demod_cf_0, 0), (self.satnogs_ogg_encoder_0, 0)) self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.low_pass_filter_0, 0)) self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.satnogs_iq_sink_0, 0)) self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.satnogs_waterfall_sink_0, 0)) self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.blks2_rational_resampler_xxx_1, 0)) self.connect((self.freq_xlating_fir_filter_xxx_0_0, 0), (self.analog_nbfm_rx_0, 0)) + self.connect((self.hilbert_fc_0, 0), (self.freq_xlating_fir_filter_xxx_0_0, 0)) self.connect((self.low_pass_filter_0, 0), (self.analog_quadrature_demod_cf_0, 0)) - self.connect((self.low_pass_filter_0, 0), (self.freq_xlating_fir_filter_xxx_0_0, 0)) self.connect((self.low_pass_filter_0_0, 0), (self.rational_resampler_xxx_0, 0)) self.connect((self.osmosdr_source_0, 0), (self.satnogs_coarse_doppler_correction_cc_0, 0)) self.connect((self.rational_resampler_xxx_0, 0), (self.satnogs_sstv_pd120_sink_0, 0)) diff --git a/apps/flowgraphs/sstv_pd120_demod.grc b/apps/flowgraphs/sstv_pd120_demod.grc index 27e5998..8228e84 100644 --- a/apps/flowgraphs/sstv_pd120_demod.grc +++ b/apps/flowgraphs/sstv_pd120_demod.grc @@ -323,7 +323,7 @@ TX sampling rate _coordinate - (964, 562) + (877, 562) _rotation @@ -374,11 +374,11 @@ TX sampling rate _coordinate - (1204, 474) + (1252, 291) _rotation - 180 + 0 gain @@ -872,7 +872,7 @@ TX sampling rate _coordinate - (1164, 562) + (1076, 562) _rotation @@ -903,6 +903,57 @@ TX sampling rate ccc + + hilbert_fc + + beta + 6.76 + + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (1323, 602) + + + _rotation + 180 + + + id + hilbert_fc_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + num_taps + 65 + + + win + firdes.WIN_HAMMING + + parameter @@ -1159,7 +1210,7 @@ max_modulation_freq = 3000 _coordinate - (781, 538) + (693, 538) _rotation @@ -2680,7 +2731,7 @@ max_modulation_freq = 3000 _coordinate - (590, 562) + (494, 562) _rotation @@ -3017,11 +3068,11 @@ max_modulation_freq = 3000 _coordinate - (1004, 458) + (1531, 275) _rotation - 180 + 0 id @@ -3056,7 +3107,7 @@ max_modulation_freq = 3000 _coordinate - (342, 586) + (263, 586) _rotation @@ -3238,6 +3289,12 @@ max_modulation_freq = 3000 0 0 + + analog_quadrature_demod_cf_0 + hilbert_fc_0 + 0 + 0 + analog_quadrature_demod_cf_0 satnogs_ogg_encoder_0 @@ -3275,14 +3332,14 @@ max_modulation_freq = 3000 0 - low_pass_filter_0 - analog_quadrature_demod_cf_0 + hilbert_fc_0 + freq_xlating_fir_filter_xxx_0_0 0 0 low_pass_filter_0 - freq_xlating_fir_filter_xxx_0_0 + analog_quadrature_demod_cf_0 0 0