kopia lustrzana https://github.com/projecthorus/wenet
Updates to web interface, added headless RX script.
rodzic
0be700901d
commit
f0f5af4281
|
|
@ -318,7 +318,7 @@ def orientation_telemetry_decoder(packet):
|
|||
|
||||
# We need the packet as a string - convert to a string in case we were passed a list of bytes,
|
||||
# which occurs when we are decoding a packet that has arrived via a UDP-broadcast JSON blob.
|
||||
packet = byts(bytearray(packet))
|
||||
packet = bytes(bytearray(packet))
|
||||
|
||||
# Some basic sanity checking of the packet before we attempt to decode.
|
||||
if len(packet) < WENET_PACKET_LENGTHS.ORIENTATION_TELEMETRY:
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ parser = argparse.ArgumentParser()
|
|||
parser.add_argument("--hex", action="store_true", help="Take Hex strings as input instead of raw data.")
|
||||
parser.add_argument("--partialupdate", default=0, help="Push partial updates every N packets to GUI.")
|
||||
parser.add_argument("-v", "--verbose", action='store_true', default=False, help="Verbose output")
|
||||
parser.add_argument("--headless", action='store_true', default=False, help="Headless mode - broadcasts additional data via UDP.")
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
|
|
@ -55,7 +56,7 @@ def trigger_gui_update(filename, text = "None"):
|
|||
|
||||
# Telemetry packets are send via UDP broadcast in case there is other software on the local
|
||||
# network that wants them.
|
||||
def broadcast_telemetry_packet(data):
|
||||
def broadcast_telemetry_packet(data, headless=False):
|
||||
telemetry_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
|
||||
# Set up the telemetry socket so it can be re-used.
|
||||
telemetry_socket.setsockopt(socket.SOL_SOCKET,socket.SO_BROADCAST,1)
|
||||
|
|
@ -79,6 +80,13 @@ def broadcast_telemetry_packet(data):
|
|||
telemetry_socket.close()
|
||||
|
||||
|
||||
if headless:
|
||||
# In headless mode, we also send the above data via the image port.
|
||||
gui_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
|
||||
gui_socket.sendto(json.dumps(data).encode('ascii'),("127.0.0.1",WENET_IMAGE_UDP_PORT))
|
||||
gui_socket.close()
|
||||
|
||||
|
||||
# State variables
|
||||
current_image = -1
|
||||
current_callsign = ""
|
||||
|
|
@ -113,7 +121,7 @@ while True:
|
|||
if packet_type == WENET_PACKET_TYPES.IDLE:
|
||||
continue
|
||||
elif packet_type == WENET_PACKET_TYPES.TEXT_MESSAGE:
|
||||
broadcast_telemetry_packet(data)
|
||||
broadcast_telemetry_packet(data, args.headless)
|
||||
logging.info(packet_to_string(data))
|
||||
|
||||
elif packet_type == WENET_PACKET_TYPES.SEC_PAYLOAD_TELEMETRY:
|
||||
|
|
@ -121,7 +129,7 @@ while True:
|
|||
logging.info(packet_to_string(data))
|
||||
|
||||
elif packet_type == WENET_PACKET_TYPES.GPS_TELEMETRY:
|
||||
broadcast_telemetry_packet(data)
|
||||
broadcast_telemetry_packet(data, args.headless)
|
||||
logging.info(packet_to_string(data))
|
||||
|
||||
elif packet_type == WENET_PACKET_TYPES.ORIENTATION_TELEMETRY:
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ except ImportError:
|
|||
# Python 3
|
||||
from queue import Queue
|
||||
|
||||
WENET_IMAGE_UDP_PORT = 7890
|
||||
from WenetPackets import WENET_IMAGE_UDP_PORT
|
||||
|
||||
|
||||
class SSDVUploader(object):
|
||||
|
|
|
|||
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Globals
|
||||
*/
|
||||
|
||||
/* Links */
|
||||
a,
|
||||
a:focus,
|
||||
a:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Base structure
|
||||
*/
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
background-color: #333;
|
||||
}
|
||||
|
||||
body {
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-box;
|
||||
display: flex;
|
||||
-ms-flex-pack: center;
|
||||
-webkit-box-pack: center;
|
||||
justify-content: center;
|
||||
color: #fff;
|
||||
text-shadow: 0 .05rem .1rem rgba(0, 0, 0, .5);
|
||||
box-shadow: inset 0 0 5rem rgba(0, 0, 0, .5);
|
||||
}
|
||||
|
||||
.cover-container {
|
||||
max-width: 42em;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Header
|
||||
*/
|
||||
|
||||
.masthead-brand {
|
||||
margin-bottom: 1;
|
||||
}
|
||||
|
||||
|
||||
.wenet-image {
|
||||
max-width: 100%;
|
||||
max-height: auto;
|
||||
}
|
||||
|
||||
|
||||
.snr-display {
|
||||
padding: .25rem 0;
|
||||
font-weight: 700;
|
||||
color: rgba(255, 255, 255, .8);
|
||||
background-color: transparent;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.gps-display {
|
||||
padding: .25rem 0;
|
||||
font-weight: 600;
|
||||
color: rgba(255, 255, 255, .8);
|
||||
background-color: transparent;
|
||||
float: right;
|
||||
}
|
||||
|
||||
@media (min-width: 48em) {
|
||||
.masthead-brand {
|
||||
float: left;
|
||||
}
|
||||
.nav-masthead {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Footer
|
||||
*/
|
||||
.mastfoot {
|
||||
color: rgba(255, 255, 255, .5);
|
||||
}
|
||||
Plik binarny nie jest wyświetlany.
|
Po Szerokość: | Wysokość: | Rozmiar: 114 KiB |
|
|
@ -0,0 +1,123 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=yes">
|
||||
<title>Wenet Web Interface</title>
|
||||
|
||||
<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet">
|
||||
<link href="{{ url_for('static', filename='css/wenet.css') }}" rel="stylesheet">
|
||||
<script src="{{ url_for('static', filename='js/jquery-3.3.1.min.js')}}"></script>
|
||||
<script src="{{ url_for('static', filename='js/socket.io-1.4.5.js') }}"></script>
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
|
||||
|
||||
$(document).ready(function() {
|
||||
// Use the 'update_status' namespace for all of our traffic
|
||||
namespace = '/update_status';
|
||||
|
||||
// Connect to the Socket.IO server.
|
||||
// The connection URL has the following format:
|
||||
// http[s]://<domain>:<port>[/<namespace>]
|
||||
var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + namespace);
|
||||
|
||||
|
||||
// Handle an image update.
|
||||
socket.on('image_update', function(msg) {
|
||||
var myImageElement = document.getElementById('wenet_image');
|
||||
myImageElement.src = 'latest.jpg?rand=' + Math.random();
|
||||
|
||||
var _new_desc = msg.text;
|
||||
$('#image_data').html(_new_desc);
|
||||
});
|
||||
|
||||
socket.on('uploader_update', function(msg) {
|
||||
|
||||
var _new_desc = "Uploader Status: " + msg.queued + " Queued, " + msg.uploaded + " Uploaded, " + msg.discarded + " Discarded";
|
||||
$('#uploader_data').html(_new_desc);
|
||||
});
|
||||
|
||||
|
||||
socket.on('modem_stats', function(msg) {
|
||||
|
||||
var snr = msg.snr.toFixed(1);
|
||||
var ppm = msg.ppm.toFixed(1);
|
||||
|
||||
var _new_desc = "SNR: " + snr + " dB"
|
||||
$('#snr-data').html(_new_desc);
|
||||
});
|
||||
|
||||
socket.on('gps_update', function(msg) {
|
||||
|
||||
if (msg.numSV < 3){
|
||||
$('#gps-data').html("No GPS Lock");
|
||||
} else {
|
||||
|
||||
var lat = msg.latitude.toFixed(5);
|
||||
var lon = msg.longitude.toFixed(5);
|
||||
var alt = msg.altitude.toFixed(0);
|
||||
var ascent = msg.ascent_rate.toFixed(1);
|
||||
|
||||
var _new_desc = lat + ", " + lon + " " + alt + "m " + ascent + " m/s"
|
||||
$('#gps-data').html(_new_desc);
|
||||
}
|
||||
});
|
||||
|
||||
var text_messages = [];
|
||||
|
||||
socket.on('text_update', function(msg) {
|
||||
var _text = "Msg #" + msg.id + ": " + msg.text;
|
||||
text_messages.push(_text);
|
||||
if(text_messages.length > 6){
|
||||
text_messages.shift();
|
||||
}
|
||||
|
||||
var _log_output = "";
|
||||
text_messages.forEach( function(value, index, array){
|
||||
_log_output = _log_output + value + "<br>";
|
||||
});
|
||||
|
||||
$('#log_data').html(_log_output);
|
||||
});
|
||||
|
||||
// Tell the server we are connected and ready for data.
|
||||
socket.on('connect', function() {
|
||||
socket.emit('client_connected', {data: 'I\'m connected!'});
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
<h3 class="masthead-brand">Wenet Dashboard</h3>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<h5 class="gps-display" id="gps-data"></h5>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<h4 class="snr-display" id="snr-data">SNR: 0 dB</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<img src="{{ url_for('static', filename='horus.png') }}" id="wenet_image" class="center-block wenet-image"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class='col-6'>
|
||||
<div id="image_data">No image data received yet.</div>
|
||||
</div>
|
||||
<div class='col-6'>
|
||||
<div id="uploader_data">No uploader status data received yet.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class='col-12'>
|
||||
<div id="log_data">No log messages received yet.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Wenet Web Interface</title>
|
||||
|
||||
<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet">
|
||||
<script src="{{ url_for('static', filename='js/jquery-3.3.1.min.js')}}"></script>
|
||||
<script src="{{ url_for('static', filename='js/socket.io-1.4.5.js') }}"></script>
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
|
||||
|
||||
$(document).ready(function() {
|
||||
// Use the 'update_status' namespace for all of our traffic
|
||||
namespace = '/update_status';
|
||||
|
||||
// Connect to the Socket.IO server.
|
||||
// The connection URL has the following format:
|
||||
// http[s]://<domain>:<port>[/<namespace>]
|
||||
var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + namespace);
|
||||
|
||||
|
||||
// Handle an image update.
|
||||
socket.on('image_update', function(msg) {
|
||||
var myImageElement = document.getElementById('wenet_image');
|
||||
myImageElement.src = 'latest.jpg?rand=' + Math.random();
|
||||
|
||||
var _new_desc = msg.text;
|
||||
$('#image_data').html(_new_desc);
|
||||
});
|
||||
|
||||
socket.on('uploader_update', function(msg) {
|
||||
|
||||
var _new_desc = "Uploader Status: " + msg.queued + " Queued, " + msg.uploaded + " Uploaded, " + msg.discarded + " Discarded";
|
||||
$('#uploader_data').html(_new_desc);
|
||||
});
|
||||
|
||||
|
||||
// Tell the server we are connected and ready for data.
|
||||
socket.on('connect', function() {
|
||||
socket.emit('client_connected', {data: 'I\'m connected!'});
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<img src="latest.jpg" id="wenet_image" class="center-block img-responsive"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class='col-12'>
|
||||
<div id="image_data">No image data received yet.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class='col-12'>
|
||||
<div id="uploader_data">No uploader status data received yet.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -25,7 +25,7 @@ import datetime
|
|||
from threading import Thread, Lock
|
||||
from io import BytesIO
|
||||
|
||||
WENET_IMAGE_UDP_PORT = 7890
|
||||
from WenetPackets import *
|
||||
|
||||
# Define Flask Application, and allow automatic reloading of templates for dev
|
||||
app = flask.Flask(__name__)
|
||||
|
|
@ -102,6 +102,27 @@ def update_image(filename, description):
|
|||
logging.error("Error loading new image %s - %s" % (filename, str(e)))
|
||||
|
||||
|
||||
def handle_telemetry(packet):
|
||||
""" Handle GPS and Text message packets from the wenet receiver """
|
||||
|
||||
# Decode GPS and IMU packets, and pass onto their respective GUI update functions.
|
||||
packet_type = decode_packet_type(packet)
|
||||
|
||||
if packet_type == WENET_PACKET_TYPES.GPS_TELEMETRY:
|
||||
# GPS data from the payload
|
||||
gps_data = gps_telemetry_decoder(packet)
|
||||
if gps_data['error'] == 'None':
|
||||
flask_emit_event('gps_update', data=gps_data)
|
||||
|
||||
elif packet_type == WENET_PACKET_TYPES.TEXT_MESSAGE:
|
||||
# A text message from the payload.
|
||||
text_data = decode_text_message(packet)
|
||||
if text_data['error'] == 'None':
|
||||
flask_emit_event('text_update', data=text_data)
|
||||
else:
|
||||
# Discard any other packet type.
|
||||
pass
|
||||
|
||||
|
||||
def process_udp(packet):
|
||||
|
||||
|
|
@ -115,6 +136,16 @@ def process_udp(packet):
|
|||
# Information from the uploader process.
|
||||
flask_emit_event('uploader_update', data=packet_dict)
|
||||
|
||||
elif 'snr' in packet_dict:
|
||||
# Modem statistics packet
|
||||
flask_emit_event('modem_stats', data=packet_dict)
|
||||
|
||||
elif 'type' in packet_dict:
|
||||
# Generic telemetry packet from the wenet RX.
|
||||
# This could be GPS telemetry, text data, or something else..
|
||||
if packet_dict['type'] == 'WENET':
|
||||
handle_telemetry(packet_dict['packet'])
|
||||
|
||||
|
||||
|
||||
udp_listener_running = False
|
||||
|
|
@ -154,10 +185,16 @@ if __name__ == "__main__":
|
|||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("-l", "--listen_port",default=5003,help="Port to run Web Server on. (Default: 5003)")
|
||||
parser.add_argument("-v", "--verbose", action='store_true', help="Enable debug output.")
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
logging.basicConfig(format='%(asctime)s %(levelname)s: %(message)s', level=logging.DEBUG)
|
||||
if args.verbose:
|
||||
log_level = logging.DEBUG
|
||||
else:
|
||||
log_level = logging.ERROR
|
||||
|
||||
logging.basicConfig(format='%(asctime)s %(levelname)s: %(message)s', level=log_level)
|
||||
|
||||
|
||||
t = Thread(target=udp_rx_thread)
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Wenet RX-side Initialisation Script - HEADLESS VERSION
|
||||
# 2019 Mark Jessop <vk5qi@rfhead.net>
|
||||
#
|
||||
# This code mostly assumes an RTLSDR will be used for RX.
|
||||
# For the lower rate variants (4800/9600), GQRX could be used.
|
||||
#
|
||||
# This version of the startup script is intended to be run on a headless
|
||||
# Raspberry Pi 3B+ or newer.
|
||||
# A display of imagery and telemetry can be accessed at http://<pi_ip>:5003/
|
||||
#
|
||||
|
||||
|
||||
# Set CHANGEME to your callsign.
|
||||
MYCALL=CHANGEME
|
||||
|
||||
# Wenet Transmission Centre Frequency:
|
||||
|
||||
# Default Wenet Frequency, as used on most Project Horus flights.
|
||||
RXFREQ=441200000
|
||||
# Secondary downlink frequency, used on dual-launch flights
|
||||
#RXFREQ=443500000
|
||||
|
||||
# Receiver Gain. Set this to 0 to use automatic gain control, otherwise if running a
|
||||
# preamplifier, you may want to experiment with different gain settings to optimize
|
||||
# your receiver setup.
|
||||
# You can find what gain range is valid for your RTLSDR by running: rtl_test
|
||||
GAIN=0
|
||||
|
||||
# Bias Tee Enable (1) or Disable (0)
|
||||
BIAS=0
|
||||
# Note that this will need the rtl_biast utility available, which means
|
||||
# building the rtl-sdr utils from this repo: https://github.com/rtlsdrblog/rtl-sdr
|
||||
|
||||
|
||||
# Change the following path as appropriate.
|
||||
# If running this from a .desktop file, you may need to set an absolute path here
|
||||
# i.e. /home/username/wenet/rx/
|
||||
cd ~/wenet/rx/
|
||||
|
||||
|
||||
|
||||
# Receive Flow Type:
|
||||
# IQ = Pass complex samples into the fsk demodulator. (Default)
|
||||
# This is suitable for use with RTLSDRs that do not have DC bias issues.
|
||||
# Examples: RTLSDR-Blog v3 Dongles, most Nooelec dongles. (anything with a R820T or R820T2 tuner)
|
||||
#
|
||||
# SSB = Demodulate the IQ from the SDR as a very wide (400 kHz) USB signal, and
|
||||
# pass that into the fsk demodulator.
|
||||
# This is useful when the RTLSDR has a DC bias that may affect demodulation.
|
||||
# i.e. RTLSDRs with Elonics E4000 or FitiPower FC0013 tuners.
|
||||
# Note: This requires that the csdr utility be installed: https://github.com/simonyiszk/csdr.git
|
||||
#
|
||||
# GQRX = Take USB audio from GQRX, via a UDP stream on port 7355.
|
||||
# This assumes that GQRX has been set into 'wide' (24 kHz BW) USB mode, and is
|
||||
# streaming samples to UDP:localhost:7355.
|
||||
# Note 1: This mode will only work for low baud rates (~4800-9600 baud),
|
||||
# that can fit within a ~20 kHz passband. The baud rate must also be an integer divisor of 48 khz.
|
||||
# Note 2: When in this mode, all the frequency/gain/bias commands above will be ignored, as GQRX
|
||||
# has control over the SDR.
|
||||
RX_FLOW=IQ
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Modem Settings - Don't adjust these unless you really need to!
|
||||
#
|
||||
BAUD_RATE=115177 # Baud rate, in symbols/second.
|
||||
OVERSAMPLING=8 # FSK Demod Oversampling rate. Not used in GQRX mode.
|
||||
# Known-Working Modem Settings:
|
||||
# 115177 baud (Pi Zero W @ '115200' baud), 8x oversampling.
|
||||
# 9600 baud, 100x oversampling.
|
||||
# 4800 baud, 200x oversampling.
|
||||
#BAUD_RATE=4800
|
||||
#OVERSAMPLING=200
|
||||
|
||||
|
||||
#
|
||||
# Main Script Start... Don't edit anything below this unless you know what you're doing!
|
||||
#
|
||||
|
||||
# Do some checks if we are in GQRX mode.
|
||||
if [ "$RX_FLOW" = "GQRX" ]; then
|
||||
if (($BAUD_RATE > 10000)); then
|
||||
echo "Baud rate too high for GQRX mode."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Start up the SSDV Uploader script and push it into the background.
|
||||
python ssdvuploader.py $MYCALL &
|
||||
SSDV_UPLOAD_PID=$!
|
||||
|
||||
# Start the Web Interface Server
|
||||
python wenetserver.py &
|
||||
WEB_VIEWER_PID=$!
|
||||
|
||||
|
||||
|
||||
# Do some checks if we are in GQRX mode.
|
||||
if [ "$RX_FLOW" != "GQRX" ]; then
|
||||
|
||||
# Calculate the SDR sample rate required.
|
||||
SDR_RATE=$(($BAUD_RATE * $OVERSAMPLING))
|
||||
# Calculate the SDR centre frequency.
|
||||
# The fsk_demod acquisition window is from Rs/2 to Fs/2 - Rs.
|
||||
# Given Fs is Rs * Os (Os = oversampling), we can calculate the required tuning offset with the equation:
|
||||
# Offset = Fcenter - Rs*(Os/4 - 0.25)
|
||||
RX_SSB_FREQ=$(echo "$RXFREQ - $BAUD_RATE * ($OVERSAMPLING/4 - 0.25)" | bc)
|
||||
|
||||
echo "Using SDR Sample Rate: $SDR_RATE Hz"
|
||||
echo "Using SDR Centre Frequency: $RX_SSB_FREQ Hz"
|
||||
|
||||
if [ "$BIAS" = "1" ]; then
|
||||
echo "Enabling Bias Tee"
|
||||
rtl_biast -b 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Start up the receive chain.
|
||||
if [ "$RX_FLOW" = "IQ" ]; then
|
||||
# If we have a RTLSDR that receives using a low-IF, then we have no DC spike issues,
|
||||
# and can feed complex samples straight into the fsk demodulator.
|
||||
echo "Using Complex Samples."
|
||||
|
||||
rtl_sdr -s $SDR_RATE -f $RX_SSB_FREQ -g $GAIN - | \
|
||||
./fsk_demod --cu8 -s --stats=100 2 $SDR_RATE $BAUD_RATE - - 2> >(python fskstatsudp.py --rate 1) | \
|
||||
./drs232_ldpc - - -vv 2> /dev/null | \
|
||||
python rx_ssdv.py --partialupdate 16 --headless
|
||||
elif [ "$RX_FLOW" = "GQRX" ]; then
|
||||
# GQRX Mode - take 48kHz real samples from GQRX via UDP.
|
||||
# TODO: Check the following netcat command works OK under all OSes...
|
||||
# different netcat versions seem to have different command-line options.
|
||||
# Might need to try: nc -l -u -p 7355 localhost
|
||||
echo "Receiving samples from GQRX on UDP:localhost:7355"
|
||||
nc -l -u localhost 7355 | \
|
||||
./fsk_demod -s --stats=100 -b 1 -u 23500 2 48000 $BAUD_RATE - - 2> >(python fskstatsudp.py --rate 1) | \
|
||||
./drs232_ldpc - - -vv 2> /dev/null | \
|
||||
python rx_ssdv.py --partialupdate 4 --headless
|
||||
else
|
||||
# If using a RTLSDR that has a DC spike (i.e. either has a FitiPower FC0012 or Elonics E4000 Tuner),
|
||||
# we receive below the centre frequency, and perform USB demodulation.
|
||||
echo "Using Real Samples and USB demodulation."
|
||||
|
||||
rtl_sdr -s $SDR_RATE -f $RX_SSB_FREQ -g $GAIN - | csdr convert_u8_f | \
|
||||
csdr bandpass_fir_fft_cc 0.05 0.45 0.05 | csdr realpart_cf | \
|
||||
csdr gain_ff 0.5 | csdr convert_f_s16 | \
|
||||
./fsk_demod -s --stats=100 2 $SDR_RATE $BAUD_RATE - - 2> >(python fskstatsudp.py --rate 1) | \
|
||||
./drs232_ldpc - - -vv 2> /dev/null | \
|
||||
python rx_ssdv.py --partialupdate 16 --headless
|
||||
|
||||
fi
|
||||
|
||||
|
||||
# Kill off the SSDV Uploader and the GUIs
|
||||
kill $SSDV_UPLOAD_PID
|
||||
kill $WEB_VIEWER_PID
|
||||
Ładowanie…
Reference in New Issue