Improve the generic FM demodulator

The FM demodulator now supports a variaty of hardware setups and saves
the WAV file for further processing. A set of command line arguments can
control most of the flowgraph internals, such as the wav file name and
storage path e.t.c.

TODO: Check the settings for all the available hardware
This commit is contained in:
Manolis Surligas 2016-10-12 21:22:48 +03:00 committed by Manolis Surligas
parent 33a27566c8
commit ce8d54eb40
8 changed files with 597 additions and 294 deletions

View File

@ -22,5 +22,6 @@ include(GrPython)
GR_PYTHON_INSTALL(
PROGRAMS
flowgraphs/upsat_transceiver_cli.py
flowgraphs/satnogs_fm_demod.py
DESTINATION bin
)

View File

@ -1,12 +1,12 @@
<?xml version='1.0' encoding='utf-8'?>
<?grc format='1' created='3.7.9'?>
<?grc format='1' created='3.7.10'?>
<flow_graph>
<timestamp>Thu May 5 00:22:45 2016</timestamp>
<block>
<key>options</key>
<param>
<key>author</key>
<value></value>
<value>Manolis Surligas (surligas@gmail.com)</value>
</param>
<param>
<key>window_size</key>
@ -22,7 +22,7 @@
</param>
<param>
<key>description</key>
<value></value>
<value>A generic FM demodulation block</value>
</param>
<param>
<key>_enabled</key>
@ -46,7 +46,7 @@
</param>
<param>
<key>id</key>
<value>fm_demod</value>
<value>satnogs_fm_demod</value>
</param>
<param>
<key>max_nouts</key>
@ -78,7 +78,7 @@
</param>
<param>
<key>title</key>
<value></value>
<value>FM Generic Demodulation</value>
</param>
</block>
<block>
@ -93,7 +93,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(480, 21)</value>
<value>(568, 508)</value>
</param>
<param>
<key>_rotation</key>
@ -109,14 +109,12 @@
</param>
</block>
<block>
<key>variable_qtgui_range</key>
<key>variable</key>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>value</key>
<value>0.9</value>
<value>Decimation factor
for the RX after the
SDR received samples</value>
</param>
<param>
<key>_enabled</key>
@ -124,11 +122,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(1048, 249)</value>
</param>
<param>
<key>gui_hint</key>
<value></value>
<value>(336, 612)</value>
</param>
<param>
<key>_rotation</key>
@ -139,36 +133,8 @@
<value>audio_gain</value>
</param>
<param>
<key>label</key>
<value>Audio Gain</value>
</param>
<param>
<key>min_len</key>
<value>200</value>
</param>
<param>
<key>orient</key>
<value>Qt.Horizontal</value>
</param>
<param>
<key>start</key>
<value>0</value>
</param>
<param>
<key>step</key>
<value>0.01</value>
</param>
<param>
<key>stop</key>
<value>8</value>
</param>
<param>
<key>rangeType</key>
<value>float</value>
</param>
<param>
<key>widget</key>
<value>counter_slider</value>
<key>value</key>
<value>satnogs.fm_demod_settings[rx_sdr_device]['audio_gain']</value>
</param>
</block>
<block>
@ -183,7 +149,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(480, 93)</value>
<value>(568, 580)</value>
</param>
<param>
<key>_rotation</key>
@ -212,7 +178,7 @@ SDR received samples</value>
</param>
<param>
<key>_coordinate</key>
<value>(232, 21)</value>
<value>(192, 612)</value>
</param>
<param>
<key>_rotation</key>
@ -224,161 +190,7 @@ SDR received samples</value>
</param>
<param>
<key>value</key>
<value>10</value>
</param>
</block>
<block>
<key>variable_qtgui_range</key>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>value</key>
<value>100e6</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(1048, 24)</value>
</param>
<param>
<key>gui_hint</key>
<value></value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>freq</value>
</param>
<param>
<key>label</key>
<value>RX Frequency</value>
</param>
<param>
<key>min_len</key>
<value>200</value>
</param>
<param>
<key>orient</key>
<value>Qt.Horizontal</value>
</param>
<param>
<key>start</key>
<value>92e6</value>
</param>
<param>
<key>step</key>
<value>100e3</value>
</param>
<param>
<key>stop</key>
<value>105e6</value>
</param>
<param>
<key>rangeType</key>
<value>float</value>
</param>
<param>
<key>widget</key>
<value>counter_slider</value>
</param>
</block>
<block>
<key>variable_qtgui_range</key>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>value</key>
<value>10</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(1048, 137)</value>
</param>
<param>
<key>gui_hint</key>
<value></value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>gain</value>
</param>
<param>
<key>label</key>
<value>RX RF Gain</value>
</param>
<param>
<key>min_len</key>
<value>200</value>
</param>
<param>
<key>orient</key>
<value>Qt.Horizontal</value>
</param>
<param>
<key>start</key>
<value>0</value>
</param>
<param>
<key>step</key>
<value>0.5</value>
</param>
<param>
<key>stop</key>
<value>40</value>
</param>
<param>
<key>rangeType</key>
<value>float</value>
</param>
<param>
<key>widget</key>
<value>counter_slider</value>
</param>
</block>
<block>
<key>variable</key>
<param>
<key>comment</key>
<value>To avoid the SDR carrier at the DC
we shift the LO a little further</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(832, 18)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>lo_offset</value>
</param>
<param>
<key>value</key>
<value>100e3</value>
<value>satnogs.fm_demod_settings[rx_sdr_device]['decimation_rx']</value>
</param>
</block>
<block>
@ -393,7 +205,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(360, 21)</value>
<value>(432, 476)</value>
</param>
<param>
<key>_rotation</key>
@ -412,7 +224,8 @@ we shift the LO a little further</value>
<key>variable</key>
<param>
<key>comment</key>
<value></value>
<value>SDR device
TX sampling rate</value>
</param>
<param>
<key>_enabled</key>
@ -420,7 +233,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(8, 160)</value>
<value>(192, 484)</value>
</param>
<param>
<key>_rotation</key>
@ -432,7 +245,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>value</key>
<value>10e6</value>
<value>satnogs.hw_rx_settings[rx_sdr_device]['samp_rate']</value>
</param>
</block>
<block>
@ -455,7 +268,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(664, 18)</value>
<value>(560, 648)</value>
</param>
<param>
<key>_rotation</key>
@ -502,7 +315,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
<value>0</value>
</param>
<param>
<key>freq</key>
@ -510,7 +323,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(296, 192)</value>
<value>(312, 24)</value>
</param>
<param>
<key>_rotation</key>
@ -569,7 +382,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(712, 501)</value>
<value>(736, 292)</value>
</param>
<param>
<key>_rotation</key>
@ -592,53 +405,6 @@ we shift the LO a little further</value>
<value>quadrature_rate</value>
</param>
</block>
<block>
<key>audio_sink</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>device_name</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
</param>
<param>
<key>_coordinate</key>
<value>(776, 668)</value>
</param>
<param>
<key>_rotation</key>
<value>180</value>
</param>
<param>
<key>id</key>
<value>audio_sink_0</value>
</param>
<param>
<key>num_inputs</key>
<value>1</value>
</param>
<param>
<key>ok_to_block</key>
<value>True</value>
</param>
<param>
<key>samp_rate</key>
<value>audio_samp_rate</value>
</param>
</block>
<block>
<key>blocks_multiply_const_vxx</key>
<param>
@ -663,7 +429,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(968, 668)</value>
<value>(976, 444)</value>
</param>
<param>
<key>_rotation</key>
@ -706,11 +472,11 @@ we shift the LO a little further</value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(568, 264)</value>
<value>(568, 64)</value>
</param>
<param>
<key>_rotation</key>
@ -741,6 +507,96 @@ we shift the LO a little further</value>
<value>1</value>
</param>
</block>
<block>
<key>blocks_wavfile_sink</key>
<param>
<key>bits_per_sample</key>
<value>16</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>file</key>
<value>file_path</value>
</param>
<param>
<key>_coordinate</key>
<value>(800, 428)</value>
</param>
<param>
<key>_rotation</key>
<value>180</value>
</param>
<param>
<key>id</key>
<value>blocks_wavfile_sink_0</value>
</param>
<param>
<key>nchan</key>
<value>1</value>
</param>
<param>
<key>samp_rate</key>
<value>audio_samp_rate</value>
</param>
</block>
<block>
<key>parameter</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(64, 620)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>file_path</value>
</param>
<param>
<key>label</key>
<value></value>
</param>
<param>
<key>short_id</key>
<value></value>
</param>
<param>
<key>type</key>
<value>string</value>
</param>
<param>
<key>value</key>
<value>test.wav</value>
</param>
</block>
<block>
<key>freq_xlating_fir_filter_xxx</key>
<param>
@ -769,7 +625,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(496, 487)</value>
<value>(520, 280)</value>
</param>
<param>
<key>_rotation</key>
@ -800,6 +656,50 @@ we shift the LO a little further</value>
<value>ccc</value>
</param>
</block>
<block>
<key>parameter</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value>To avoid the SDR carrier at the DC
we shift the LO a little further</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(328, 476)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>lo_offset</value>
</param>
<param>
<key>label</key>
<value></value>
</param>
<param>
<key>short_id</key>
<value></value>
</param>
<param>
<key>type</key>
<value>eng_float</value>
</param>
<param>
<key>value</key>
<value>100e3</value>
</param>
</block>
<block>
<key>osmosdr_source</key>
<param>
@ -808,11 +708,11 @@ we shift the LO a little further</value>
</param>
<param>
<key>ant0</key>
<value></value>
<value>satnogs.hw_rx_settings[rx_sdr_device]['antenna']</value>
</param>
<param>
<key>bb_gain0</key>
<value>20</value>
<value>satnogs.hw_rx_settings[rx_sdr_device]['bb_gain']</value>
</param>
<param>
<key>bw0</key>
@ -828,7 +728,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>freq0</key>
<value>freq - lo_offset</value>
<value>rx_freq - lo_offset</value>
</param>
<param>
<key>gain_mode0</key>
@ -836,7 +736,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>if_gain0</key>
<value>20</value>
<value>satnogs.hw_rx_settings[rx_sdr_device]['if_gain']</value>
</param>
<param>
<key>iq_balance_mode0</key>
@ -844,7 +744,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>gain0</key>
<value>gain</value>
<value>satnogs.hw_rx_settings[rx_sdr_device]['rf_gain']</value>
</param>
<param>
<key>ant10</key>
@ -2096,7 +1996,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>args</key>
<value></value>
<value>satnogs.hw_rx_settings[rx_sdr_device]['dev_arg']</value>
</param>
<param>
<key>_enabled</key>
@ -2104,7 +2004,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(104, 229)</value>
<value>(24, 256)</value>
</param>
<param>
<key>_rotation</key>
@ -2227,7 +2127,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(904, 487)</value>
<value>(944, 288)</value>
</param>
<param>
<key>_rotation</key>
@ -2280,6 +2180,10 @@ we shift the LO a little further</value>
<key>average</key>
<value>1.0</value>
</param>
<param>
<key>axislabels</key>
<value>True</value>
</param>
<param>
<key>bw</key>
<value>samp_rate_rx</value>
@ -2306,7 +2210,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
<value>0</value>
</param>
<param>
<key>fftsize</key>
@ -2314,7 +2218,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(896, 262)</value>
<value>(792, 28)</value>
</param>
<param>
<key>gui_hint</key>
@ -2548,6 +2452,10 @@ we shift the LO a little further</value>
<key>wintype</key>
<value>firdes.WIN_BLACKMAN_hARRIS</value>
</param>
<param>
<key>label</key>
<value>Relative Gain</value>
</param>
<param>
<key>ymax</key>
<value>10</value>
@ -2556,6 +2464,96 @@ we shift the LO a little further</value>
<key>ymin</key>
<value>-140</value>
</param>
<param>
<key>units</key>
<value>dB</value>
</param>
</block>
<block>
<key>parameter</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(64, 724)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>rx_freq</value>
</param>
<param>
<key>label</key>
<value></value>
</param>
<param>
<key>short_id</key>
<value></value>
</param>
<param>
<key>type</key>
<value>eng_float</value>
</param>
<param>
<key>value</key>
<value>100e6</value>
</param>
</block>
<block>
<key>parameter</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(64, 484)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>rx_sdr_device</value>
</param>
<param>
<key>label</key>
<value></value>
</param>
<param>
<key>short_id</key>
<value></value>
</param>
<param>
<key>type</key>
<value>string</value>
</param>
<param>
<key>value</key>
<value>usrpb200</value>
</param>
</block>
<block>
<key>satnogs_doppler_correction_cc</key>
@ -2581,7 +2579,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(280, 464)</value>
<value>(304, 256)</value>
</param>
<param>
<key>_rotation</key>
@ -2605,7 +2603,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>target_freq</key>
<value>freq</value>
<value>rx_freq</value>
</param>
</block>
<block>
@ -2628,7 +2626,7 @@ we shift the LO a little further</value>
</param>
<param>
<key>_coordinate</key>
<value>(24, 446)</value>
<value>(24, 164)</value>
</param>
<param>
<key>_rotation</key>
@ -2673,7 +2671,7 @@ we shift the LO a little further</value>
</connection>
<connection>
<source_block_id>blocks_multiply_const_vxx_0</source_block_id>
<sink_block_id>audio_sink_0</sink_block_id>
<sink_block_id>blocks_wavfile_sink_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>

View File

@ -0,0 +1,258 @@
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
##################################################
# GNU Radio Python Flow Graph
# Title: FM Generic Demodulation
# Author: Manolis Surligas (surligas@gmail.com)
# Description: A generic FM demodulation block
# Generated: Wed Oct 12 21:16:27 2016
##################################################
if __name__ == '__main__':
import ctypes
import sys
if sys.platform.startswith('linux'):
try:
x11 = ctypes.cdll.LoadLibrary('libX11.so')
x11.XInitThreads()
except:
print "Warning: failed to XInitThreads()"
from PyQt4 import Qt
from gnuradio import analog
from gnuradio import blocks
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 gnuradio.filter import pfb
from optparse import OptionParser
import osmosdr
import satnogs
import sys
import time
class satnogs_fm_demod(gr.top_block, Qt.QWidget):
def __init__(self, file_path="test.wav", lo_offset=100e3, rx_freq=100e6, rx_sdr_device="usrpb200"):
gr.top_block.__init__(self, "FM Generic Demodulation")
Qt.QWidget.__init__(self)
self.setWindowTitle("FM Generic Demodulation")
try:
self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc'))
except:
pass
self.top_scroll_layout = Qt.QVBoxLayout()
self.setLayout(self.top_scroll_layout)
self.top_scroll = Qt.QScrollArea()
self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame)
self.top_scroll_layout.addWidget(self.top_scroll)
self.top_scroll.setWidgetResizable(True)
self.top_widget = Qt.QWidget()
self.top_scroll.setWidget(self.top_widget)
self.top_layout = Qt.QVBoxLayout(self.top_widget)
self.top_grid_layout = Qt.QGridLayout()
self.top_layout.addLayout(self.top_grid_layout)
self.settings = Qt.QSettings("GNU Radio", "satnogs_fm_demod")
self.restoreGeometry(self.settings.value("geometry").toByteArray())
##################################################
# Parameters
##################################################
self.file_path = file_path
self.lo_offset = lo_offset
self.rx_freq = rx_freq
self.rx_sdr_device = rx_sdr_device
##################################################
# Variables
##################################################
self.samp_rate_rx = samp_rate_rx = satnogs.hw_rx_settings[rx_sdr_device]['samp_rate']
self.decimation_rx = decimation_rx = satnogs.fm_demod_settings[rx_sdr_device]['decimation_rx']
self.taps = taps = firdes.low_pass(12.0, samp_rate_rx, 100e3, 60000, firdes.WIN_HAMMING, 6.76)
self.quadrature_rate = quadrature_rate = samp_rate_rx / decimation_rx
self.audio_samp_rate = audio_samp_rate = 44100
self.audio_gain = audio_gain = satnogs.fm_demod_settings[rx_sdr_device]['audio_gain']
self.audio_decimation = audio_decimation = 2
##################################################
# Blocks
##################################################
self.satnogs_tcp_rigctl_msg_source_0 = satnogs.tcp_rigctl_msg_source("127.0.0.1", 4532, 1500)
self.satnogs_doppler_correction_cc_0 = satnogs.doppler_correction_cc(rx_freq, samp_rate_rx, 1000)
self.pfb_arb_resampler_xxx_0 = pfb.arb_resampler_fff(
audio_samp_rate / (quadrature_rate * 1.0 / audio_decimation),
taps=(firdes.low_pass_2(32, 32, 0.8, 0.1, 100)),
flt_size=32)
self.pfb_arb_resampler_xxx_0.declare_sample_delay(0)
self.osmosdr_source_0 = osmosdr.source( args="numchan=" + str(1) + " " + satnogs.hw_rx_settings[rx_sdr_device]['dev_arg'] )
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(0, 0)
self.osmosdr_source_0.set_dc_offset_mode(0, 0)
self.osmosdr_source_0.set_iq_balance_mode(0, 0)
self.osmosdr_source_0.set_gain_mode(False, 0)
self.osmosdr_source_0.set_gain(satnogs.hw_rx_settings[rx_sdr_device]['rf_gain'], 0)
self.osmosdr_source_0.set_if_gain(satnogs.hw_rx_settings[rx_sdr_device]['if_gain'], 0)
self.osmosdr_source_0.set_bb_gain(satnogs.hw_rx_settings[rx_sdr_device]['bb_gain'], 0)
self.osmosdr_source_0.set_antenna(satnogs.hw_rx_settings[rx_sdr_device]['antenna'], 0)
self.osmosdr_source_0.set_bandwidth(samp_rate_rx, 0)
self.freq_xlating_fir_filter_xxx_0 = filter.freq_xlating_fir_filter_ccc(decimation_rx, (taps), lo_offset, samp_rate_rx)
self.blocks_wavfile_sink_0 = blocks.wavfile_sink(file_path, 1, audio_samp_rate, 16)
self.blocks_multiply_const_vxx_0 = blocks.multiply_const_vff((audio_gain, ))
self.analog_wfm_rcv_0 = analog.wfm_rcv(
quad_rate=quadrature_rate,
audio_decimation=audio_decimation,
)
##################################################
# Connections
##################################################
self.msg_connect((self.satnogs_tcp_rigctl_msg_source_0, 'freq'), (self.satnogs_doppler_correction_cc_0, 'freq'))
self.connect((self.analog_wfm_rcv_0, 0), (self.pfb_arb_resampler_xxx_0, 0))
self.connect((self.blocks_multiply_const_vxx_0, 0), (self.blocks_wavfile_sink_0, 0))
self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.analog_wfm_rcv_0, 0))
self.connect((self.osmosdr_source_0, 0), (self.satnogs_doppler_correction_cc_0, 0))
self.connect((self.pfb_arb_resampler_xxx_0, 0), (self.blocks_multiply_const_vxx_0, 0))
self.connect((self.satnogs_doppler_correction_cc_0, 0), (self.freq_xlating_fir_filter_xxx_0, 0))
def closeEvent(self, event):
self.settings = Qt.QSettings("GNU Radio", "satnogs_fm_demod")
self.settings.setValue("geometry", self.saveGeometry())
event.accept()
def get_file_path(self):
return self.file_path
def set_file_path(self, file_path):
self.file_path = file_path
self.blocks_wavfile_sink_0.open(self.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_rx_freq(self):
return self.rx_freq
def set_rx_freq(self, rx_freq):
self.rx_freq = 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.set_decimation_rx(satnogs.fm_demod_settings[self.rx_sdr_device]['decimation_rx'])
self.set_audio_gain(satnogs.fm_demod_settings[self.rx_sdr_device]['audio_gain'])
self.osmosdr_source_0.set_gain(satnogs.hw_rx_settings[self.rx_sdr_device]['rf_gain'], 0)
self.osmosdr_source_0.set_if_gain(satnogs.hw_rx_settings[self.rx_sdr_device]['if_gain'], 0)
self.osmosdr_source_0.set_bb_gain(satnogs.hw_rx_settings[self.rx_sdr_device]['bb_gain'], 0)
self.osmosdr_source_0.set_antenna(satnogs.hw_rx_settings[self.rx_sdr_device]['antenna'], 0)
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_quadrature_rate(self.samp_rate_rx / self.decimation_rx)
self.osmosdr_source_0.set_sample_rate(self.samp_rate_rx)
self.osmosdr_source_0.set_bandwidth(self.samp_rate_rx, 0)
def get_decimation_rx(self):
return self.decimation_rx
def set_decimation_rx(self, decimation_rx):
self.decimation_rx = decimation_rx
self.set_quadrature_rate(self.samp_rate_rx / self.decimation_rx)
def get_taps(self):
return self.taps
def set_taps(self, taps):
self.taps = taps
self.freq_xlating_fir_filter_xxx_0.set_taps((self.taps))
def get_quadrature_rate(self):
return self.quadrature_rate
def set_quadrature_rate(self, quadrature_rate):
self.quadrature_rate = quadrature_rate
self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate / (self.quadrature_rate * 1.0 / self.audio_decimation))
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.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate / (self.quadrature_rate * 1.0 / self.audio_decimation))
def get_audio_gain(self):
return self.audio_gain
def set_audio_gain(self, audio_gain):
self.audio_gain = audio_gain
self.blocks_multiply_const_vxx_0.set_k((self.audio_gain, ))
def get_audio_decimation(self):
return self.audio_decimation
def set_audio_decimation(self, audio_decimation):
self.audio_decimation = audio_decimation
self.pfb_arb_resampler_xxx_0.set_rate(self.audio_samp_rate / (self.quadrature_rate * 1.0 / self.audio_decimation))
def argument_parser():
description = 'A generic FM demodulation block'
parser = OptionParser(usage="%prog: [options]", option_class=eng_option, description=description)
parser.add_option(
"", "--file-path", dest="file_path", type="string", default="test.wav",
help="Set 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(
"", "--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]")
return parser
def main(top_block_cls=satnogs_fm_demod, options=None):
if options is None:
options, _ = argument_parser().parse_args()
from distutils.version import StrictVersion
if StrictVersion(Qt.qVersion()) >= StrictVersion("4.5.0"):
style = gr.prefs().get_string('qtgui', 'style', 'raster')
Qt.QApplication.setGraphicsSystem(style)
qapp = Qt.QApplication(sys.argv)
tb = top_block_cls(file_path=options.file_path, lo_offset=options.lo_offset, rx_freq=options.rx_freq, rx_sdr_device=options.rx_sdr_device)
tb.start()
tb.show()
def quitting():
tb.stop()
tb.wait()
qapp.connect(qapp, Qt.SIGNAL("aboutToQuit()"), quitting)
qapp.exec_()
if __name__ == '__main__':
main()

View File

@ -1,5 +1,5 @@
<?xml version='1.0' encoding='utf-8'?>
<?grc format='1' created='3.7.9'?>
<?grc format='1' created='3.7.10'?>
<flow_graph>
<timestamp>Fri Jul 1 17:53:00 2016</timestamp>
<block>
@ -78,7 +78,7 @@
</param>
<param>
<key>title</key>
<value></value>
<value>UPSat Tranceiver</value>
</param>
</block>
<block>
@ -3676,6 +3676,10 @@ we shift the LO a little further</value>
<key>average</key>
<value>1.0</value>
</param>
<param>
<key>axislabels</key>
<value>True</value>
</param>
<param>
<key>bw</key>
<value>samp_rate_rx/decimation_rx</value>
@ -3944,6 +3948,10 @@ we shift the LO a little further</value>
<key>wintype</key>
<value>firdes.WIN_BLACKMAN_hARRIS</value>
</param>
<param>
<key>label</key>
<value>Relative Gain</value>
</param>
<param>
<key>ymax</key>
<value>0</value>
@ -3952,6 +3960,10 @@ we shift the LO a little further</value>
<key>ymin</key>
<value>-140</value>
</param>
<param>
<key>units</key>
<value>dB</value>
</param>
</block>
<block>
<key>parameter</key>

View File

@ -2,10 +2,10 @@
# -*- coding: utf-8 -*-
##################################################
# GNU Radio Python Flow Graph
# Title: Upsat Transceiver Cli
# Title: UPSat Tranceiver
# Author: Manolis Surligas (surligas@gmail.com)
# Description: SATNOGS transceiver for UPSAT satellite
# Generated: Sun Aug 14 22:13:27 2016
# Generated: Wed Oct 12 20:16:02 2016
##################################################
from gnuradio import analog
@ -28,7 +28,7 @@ import time
class upsat_transceiver_cli(gr.top_block):
def __init__(self, bind_addr="0.0.0.0", dest_addr="127.0.0.1", lo_offset=100e3, recv_port=16886, rx_sdr_device="usrpb200", send_port=5022, tx_sdr_device="usrpb200", wod_port=5023):
gr.top_block.__init__(self, "Upsat Transceiver Cli")
gr.top_block.__init__(self, "UPSat Tranceiver")
##################################################
# Parameters
@ -150,10 +150,10 @@ class upsat_transceiver_cli(gr.top_block):
def set_lo_offset(self, lo_offset):
self.lo_offset = lo_offset
self.analog_sig_source_x_0.set_frequency(self.lo_offset )
self.freq_xlating_fir_filter_xxx_0.set_center_freq(self.lo_offset)
self.osmosdr_sink_0.set_center_freq(self.tx_frequency - self.lo_offset, 0)
self.osmosdr_source_0.set_center_freq(self.rx_frequency - self.lo_offset, 0)
self.osmosdr_sink_0.set_center_freq(self.tx_frequency - self.lo_offset, 0)
self.freq_xlating_fir_filter_xxx_0.set_center_freq(self.lo_offset)
self.analog_sig_source_x_0.set_frequency(self.lo_offset )
def get_recv_port(self):
return self.recv_port
@ -166,8 +166,8 @@ class upsat_transceiver_cli(gr.top_block):
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.set_samp_rate_tx(satnogs.hw_tx_settings[self.rx_sdr_device]['samp_rate'])
self.set_samp_rate_rx(satnogs.hw_rx_settings[self.rx_sdr_device]['samp_rate'])
self.osmosdr_source_0.set_gain(satnogs.hw_rx_settings[self.rx_sdr_device]['rf_gain'], 0)
self.osmosdr_source_0.set_if_gain(satnogs.hw_rx_settings[self.rx_sdr_device]['if_gain'], 0)
self.osmosdr_source_0.set_bb_gain(satnogs.hw_rx_settings[self.rx_sdr_device]['bb_gain'], 0)
@ -200,10 +200,10 @@ class upsat_transceiver_cli(gr.top_block):
def set_samples_per_symbol_tx(self, samples_per_symbol_tx):
self.samples_per_symbol_tx = samples_per_symbol_tx
self.set_gaussian_taps(filter.firdes.gaussian(1.0, self.samples_per_symbol_tx, 1.0, 4*self.samples_per_symbol_tx))
self.set_sq_wave((1.0, ) * self.samples_per_symbol_tx)
self.analog_frequency_modulator_fc_0.set_sensitivity((math.pi*self.modulation_index_uplink) / self.samples_per_symbol_tx)
self.pfb_arb_resampler_xxx_0.set_rate(self.samp_rate_tx / (self.baud_rate_uplink * self.samples_per_symbol_tx))
self.set_gaussian_taps(filter.firdes.gaussian(1.0, self.samples_per_symbol_tx, 1.0, 4*self.samples_per_symbol_tx))
self.analog_frequency_modulator_fc_0.set_sensitivity((math.pi*self.modulation_index_uplink) / self.samples_per_symbol_tx)
def get_sq_wave(self):
return self.sq_wave
@ -233,8 +233,8 @@ class upsat_transceiver_cli(gr.top_block):
def set_deviation(self, deviation):
self.deviation = deviation
self.set_modulation_index_downlink(self.deviation / (self.baud_rate_downlink / 2.0))
self.set_modulation_index_uplink(self.deviation / (self.baud_rate_uplink / 2.0))
self.set_modulation_index_downlink(self.deviation / (self.baud_rate_downlink / 2.0))
def get_decimation_rx(self):
return self.decimation_rx
@ -257,8 +257,8 @@ class upsat_transceiver_cli(gr.top_block):
def set_baud_rate_downlink(self, baud_rate_downlink):
self.baud_rate_downlink = baud_rate_downlink
self.set_modulation_index_downlink(self.deviation / (self.baud_rate_downlink / 2.0))
self.analog_quadrature_demod_cf_0_0.set_gain(((self.first_stage_samp_rate_rx) / self.baud_rate_downlink)/(math.pi*self.modulation_index_downlink))
self.digital_clock_recovery_mm_xx_0.set_omega(self.first_stage_samp_rate_rx/self.baud_rate_downlink)
self.analog_quadrature_demod_cf_0_0.set_gain(((self.first_stage_samp_rate_rx) / self.baud_rate_downlink)/(math.pi*self.modulation_index_downlink))
def get_tx_frequency(self):
return self.tx_frequency
@ -279,10 +279,10 @@ class upsat_transceiver_cli(gr.top_block):
def set_samp_rate_tx(self, samp_rate_tx):
self.samp_rate_tx = samp_rate_tx
self.analog_sig_source_x_0.set_sampling_freq(self.samp_rate_tx)
self.pfb_arb_resampler_xxx_0.set_rate(self.samp_rate_tx / (self.baud_rate_uplink * self.samples_per_symbol_tx))
self.osmosdr_sink_0.set_sample_rate(self.samp_rate_tx)
self.osmosdr_sink_0.set_bandwidth(self.samp_rate_tx, 0)
self.pfb_arb_resampler_xxx_0.set_rate(self.samp_rate_tx / (self.baud_rate_uplink * self.samples_per_symbol_tx))
self.analog_sig_source_x_0.set_sampling_freq(self.samp_rate_tx)
def get_rx_frequency(self):
return self.rx_frequency
@ -317,12 +317,13 @@ class upsat_transceiver_cli(gr.top_block):
def set_first_stage_samp_rate_rx(self, first_stage_samp_rate_rx):
self.first_stage_samp_rate_rx = first_stage_samp_rate_rx
self.analog_quadrature_demod_cf_0_0.set_gain(((self.first_stage_samp_rate_rx) / self.baud_rate_downlink)/(math.pi*self.modulation_index_downlink))
self.digital_clock_recovery_mm_xx_0.set_omega(self.first_stage_samp_rate_rx/self.baud_rate_downlink)
self.analog_quadrature_demod_cf_0_0.set_gain(((self.first_stage_samp_rate_rx) / self.baud_rate_downlink)/(math.pi*self.modulation_index_downlink))
def argument_parser():
parser = OptionParser(option_class=eng_option, usage="%prog: [options]")
description = 'SATNOGS transceiver for UPSAT satellite'
parser = OptionParser(usage="%prog: [options]", option_class=eng_option, description=description)
parser.add_option(
"", "--bind-addr", dest="bind_addr", type="string", default="0.0.0.0",
help="Set bind_addr [default=%default]")

View File

@ -31,6 +31,7 @@ endif()
GR_PYTHON_INSTALL(
FILES
__init__.py
dsp_settings.py
hw_settings.py
satnogs_upsat_transmitter.py
DESTINATION ${GR_PYTHON_DIR}/satnogs

View File

@ -27,6 +27,7 @@ description here (python/__init__.py).
try:
# this might fail if the module is python-only
from satnogs_swig import *
from dsp_settings import *
from hw_settings import *
from satnogs_upsat_transmitter import *
except ImportError:

31
python/dsp_settings.py Normal file
View File

@ -0,0 +1,31 @@
#! /usr/bin/python
#
# gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
#
# Copyright (C) 2016, Libre Space Foundation <http://librespacefoundation.org/>
#
# 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 <http://www.gnu.org/licenses/>
#
#===============================================================================
# This file provides a variaty of settings for the flowgraphs
# based on the hardware SDR device that they are using
#===============================================================================
fm_demod_settings = {'usrpb200' : {'decimation_rx' : 5, 'audio_gain' : 0.9},
'usrp2' : {'decimation_rx' : 5, 'audio_gain' : 0.9},
'airspy' : {'decimation_rx' : 10, 'audio_gain' : 0.9},
'hackrf' : {'decimation_rx' : 5, 'audio_gain' : 0.9},
'rtlsdr' : {'decimation_rx' : 5, 'audio_gain' : 0.9}
}