Changes to support taking samples from GQRX.

pull/2/head
Mark Jessop 2019-02-23 16:47:46 +10:30
rodzic 46a0e6583e
commit 039dbc2508
4 zmienionych plików z 140 dodań i 20 usunięć

Wyświetl plik

@ -11,6 +11,7 @@ The transmit side is designed to run on a Raspberry Pi, and the UART (/dev/ttyAM
* v0.4 - SHSSP 2017 Launches (Horus 41 & 42) - 22nd Jan 2017. Added IMU and simultaneous capture from two cameras (Visible and Near-IR). Two payloads were flown, each with two cameras. A third payload (same as on Horus 40) was also flown, which captured the image below. Read more here: http://www.areg.org.au/archives/206739
* v0.5 - Minor updates. Flown on Horus 43 through Horus 49.
* v0.6 - Updated to the latest fsk_demod version from codec2-dev. This allows reception without requiring CSDR.
* v0.7 - More tweaks to the start_rx script to better support lower-rate modes. Update to the latest fsk_demod in the instructions.
![Image downlinked via Wenet on Horus 42](http://rfhead.net/temp/horus_42_small.jpg)

Wyświetl plik

@ -3,7 +3,8 @@
# Wenet RX-side Initialisation Script
# 2018-12-20 Mark Jessop <vk5qi@rfhead.net>
#
# This assumes an RTLSDR will be used for RX.
# This code mostly assumes an RTLSDR will be used for RX.
# For the lower rate variants (4800/9600), GQRX could be used.
#
# Set CHANGEME to your callsign.
@ -46,6 +47,14 @@ cd ~/wenet/rx/
# 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
@ -55,39 +64,56 @@ 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.
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 ssdv_upload.py $MYCALL &
SSDV_UPLOAD_PID=$!
#python ssdv_upload.py $MYCALL &
#SSDV_UPLOAD_PID=$!
# Start the SSDV RX GUI.
python rx_gui.py &
RX_GUI_PID=$!
# Start the Telemetry GUI.
python TelemetryGUI.py $MYCALL &
TELEM_GUI_PID=$!
# 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)
# Do some checks if we are in GQRX mode.
if [ "$RX_FLOW" != "GQRX" ]; then
echo "Using SDR Sample Rate: $SDR_RATE Hz"
echo "Using SDR Centre Frequency: $RX_SSB_FREQ Hz"
# 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)
if [ "$BIAS" = "1" ]; then
echo "Enabling Bias Tee"
rtl_biast -b 1
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.
@ -100,6 +126,16 @@ if [ "$RX_FLOW" = "IQ" ]; then
./fsk_demod --cu8 -s --stats=100 2 $SDR_RATE $BAUD_RATE - - 2> >(python fskdemodgui.py --wide) | \
./drs232_ldpc - - -vv | \
python rx_ssdv.py --partialupdate 16
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 fskdemodgui.py --wide) | \
./drs232_ldpc - - -vv | \
python rx_ssdv.py --partialupdate 4
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.
@ -114,5 +150,8 @@ else
fi
# Kill off the SSDV Uploader (since that has no GUI and we can't easily close it)
kill $SSDV_UPLOAD_PID
# Kill off the SSDV Uploader and the GUIs
kill $SSDV_UPLOAD_PID
kill $RX_GUI_PID
kill $TELEM_GUI_PID

Wyświetl plik

@ -123,6 +123,7 @@ class PacketTX(object):
txthread.start()
def frame_packet(self,packet, fec=False):
# Ensure payload size is equal to the desired payload length
if len(packet) > self.payload_length:
@ -176,7 +177,7 @@ class PacketTX(object):
def close(self):
self.transmit_active = False
self.udp_listener_running = False
self.listener_thread.join()
#self.listener_thread.join()
# Deprecated function
@ -190,7 +191,7 @@ class PacketTX(object):
# Deprecated function.
def wait(self):
while not self.ssdv_queue.empty():
while (not self.ssdv_queue.empty()) and self.transmit_active:
sleep(0.01)
# New packet queueing and queue querying functions (say that 3 times fast)

79
tx/tx_fm_radio.py 100644
Wyświetl plik

@ -0,0 +1,79 @@
#!/usr/bin/env python
#
# Proof-of-concept code to transmit Wenet FSK using a FM rig with a 9600 baud input.
# Currently just transmits example images.
#
# Notes:
# I used a 5V FTDI USB-TTL adaptor, and an Icom IC-7000
# DTR was wired directly to the PTT line on the 6-pin mini-DIN connector.
# DTR Active (Low) = PTT enabled.
# The TXD line was dropped in level using a 1k 10-turn potentiometer, and fed
# into the DATA IN line on the 6-pin mini-DIN. The 10-turn pot was set so the
# output Vp-p is about 0.3V, though I then did more adjustment looking at the
# spectrum of the generated signal.
#
# This method of producing FSK is pretty nasty, and probably isn't recommended
# for serious use.
#
# Copyright (C) 2019 Mark Jessop <vk5qi@rfhead.net>
# Released under GNU GPL v3 or later
#
import PacketTX, sys, os, argparse
# Set to whatever resolution you want to test.
file_path = "../test_images/%d_320x240.ssdv" # _raw, _800x608, _640x480, _320x240
image_numbers = xrange(1,14)
debug_output = False # If True, packet bits are saved to debug.bin as one char per bit.
def transmit_file(filename, tx_object):
file_size = os.path.getsize(filename)
if file_size % 256 > 0:
print("File size not a multiple of 256 bytes!")
return
print("Transmitting %d Packets." % (file_size/256))
f = open(filename,'rb')
for x in range(file_size/256):
data = f.read(256)
tx_object.tx_packet(data)
f.close()
print("Waiting for tx queue to empty...")
tx_object.wait()
parser = argparse.ArgumentParser()
parser.add_argument("--port", default='/dev/ttyUSB0', type=str, help="Serial port to use for transmit.")
parser.add_argument("--baudrate", default=4800, type=int, help="Transmitter baud rate. Defaults to 4800 baud.")
args = parser.parse_args()
tx = PacketTX.PacketTX(debug=debug_output, serial_port=args.port, serial_baud=args.baudrate)
# Start the transmit thread
tx.start_tx()
# Enable the PTT
tx.s.dtr = True
print("PTT ON!")
print("TX Started. Press Ctrl-C to stop.")
try:
for img in image_numbers:
filename = file_path % img
print("\nTXing: %s" % filename)
transmit_file(filename,tx)
tx.close()
except KeyboardInterrupt:
print("Closing...")
# Disable the PTT
tx.s.dtr = False
print("PTT Off")
tx.close()