kopia lustrzana https://github.com/projecthorus/wenet
Major ease-of-use updates, added start of non-SSDV message support.
rodzic
c2e41f775c
commit
023c8861d3
25
PacketTX.py
25
PacketTX.py
|
@ -44,7 +44,7 @@ class PacketTX(object):
|
|||
idle_sequence = "\x55"*256
|
||||
|
||||
|
||||
def __init__(self,serial_port="/dev/ttyAMA0", serial_baud=115200, payload_length=256, fec=False, debug = False):
|
||||
def __init__(self,serial_port="/dev/ttyAMA0", serial_baud=115200, payload_length=256, fec=False, debug = False, callsign="N0CALL"):
|
||||
# WARNING: 115200 baud is ACTUALLY 115386.834 baud, as measured using a freq counter.
|
||||
if debug == True:
|
||||
self.s = BinaryDebug()
|
||||
|
@ -55,13 +55,14 @@ class PacketTX(object):
|
|||
|
||||
self.crc16 = crcmod.predefined.mkCrcFun('crc-ccitt-false')
|
||||
self.fec = fec
|
||||
self.callsign = callsign
|
||||
|
||||
def start_tx(self):
|
||||
self.transmit_active = True
|
||||
txthread = Thread(target=self.tx_thread)
|
||||
txthread.start()
|
||||
|
||||
def frame_packet(self,packet):
|
||||
def frame_packet(self,packet, fec=False):
|
||||
# Ensure payload size is equal to the desired payload length
|
||||
if len(packet) > self.payload_length:
|
||||
packet = packet[:self.payload_length]
|
||||
|
@ -71,11 +72,24 @@ class PacketTX(object):
|
|||
|
||||
crc = struct.pack("<H",self.crc16(packet))
|
||||
|
||||
if self.fec:
|
||||
if fec:
|
||||
return self.preamble + self.unique_word + packet + crc + ldpc_encode_string(packet+crc)
|
||||
else:
|
||||
return self.preamble + self.unique_word + packet + crc
|
||||
|
||||
# Either generate an idle message, or read one in from a file (tx_idle_message.txt) if it exists.
|
||||
# This might be a useful way of getting error messages down from the payload.
|
||||
def generate_idle_message(self):
|
||||
# Try and read in a message from a file.
|
||||
try:
|
||||
f = open("tx_idle_message.txt")
|
||||
idle_data = f.read()
|
||||
f.close()
|
||||
except:
|
||||
idle_data = "DE %s Wenet High-Speed FSK Transmitter" % self.callsign
|
||||
# Append a \x00 control code before the data
|
||||
return "\x00" + idle_data
|
||||
|
||||
|
||||
def tx_thread(self):
|
||||
while self.transmit_active:
|
||||
|
@ -84,7 +98,8 @@ class PacketTX(object):
|
|||
self.s.write(packet)
|
||||
else:
|
||||
if not self.debug:
|
||||
self.s.write(self.idle_sequence)
|
||||
#self.s.write(self.idle_sequence)
|
||||
self.s.write(self.frame_packet(self.generate_idle_message()))
|
||||
else:
|
||||
sleep(0.05)
|
||||
|
||||
|
@ -99,7 +114,7 @@ class PacketTX(object):
|
|||
sleep(0.01)
|
||||
|
||||
def tx_packet(self,packet,blocking = False):
|
||||
self.txqueue.put(self.frame_packet(packet))
|
||||
self.txqueue.put(self.frame_packet(packet, self.fec))
|
||||
|
||||
if blocking:
|
||||
while not self.txqueue.empty():
|
||||
|
|
|
@ -249,9 +249,27 @@ class RFM22B(object):
|
|||
self.write_register(REG.OPERATING_FUNCTION_CONTROL_1,mode)
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
# Attempt to extract a frequency from the first argument:
|
||||
if len(sys.argv)<2:
|
||||
print("Usage: \tpython init_rfm22b.py <TX Frequency in MHz>")
|
||||
print("Example: \tpython init_rfm22b.py 441.200")
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
tx_freq = float(sys.argv[1])
|
||||
except:
|
||||
print("Unable to parse input.")
|
||||
|
||||
if tx_freq>450.0 or tx_freq<430.00:
|
||||
print("Frequency out of 70cm band, using default.")
|
||||
tx_freq = 441.200*1e6
|
||||
else:
|
||||
tx_freq = tx_freq*1e6
|
||||
|
||||
rfm = RFM22B()
|
||||
rfm.set_tx_power(TXPOW.TXPOW_14DBM | 0x08)
|
||||
rfm.set_frequency(441.2E6) # 441.2MHz.
|
||||
rfm.set_frequency(tx_freq)
|
||||
rfm.write_register(REG.GPIO2_CONFIGURATION,0x30) # TX Data In
|
||||
rfm.set_bulk(CONFIGS.REGISTERS,CONFIGS.DIRECT_120K) # Direct Asynchronous mode, ~120KHz tone spacing.
|
||||
rfm.set_mode(0x09)
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# PiCam Wrapper Functions
|
||||
#
|
||||
|
||||
import os,glob
|
||||
|
||||
picam_str = "raspistill -t 100 -ex auto -o %s -vf -hf -w 1600 -h 1200"
|
||||
temp_file_prefix = "./temp_pic"
|
||||
|
||||
|
||||
def capture_single(filename="temp.jpg"):
|
||||
os.system(picam_str % filename)
|
||||
|
||||
def capture_multiple(filename="output.jpg", n=10, temp_prefix=temp_file_prefix):
|
||||
# Remove any existing temporary images
|
||||
os.system("rm %s*.jpg"%temp_prefix)
|
||||
|
||||
# Capture n images
|
||||
for pic_num in range(n):
|
||||
capture_single("%s_%d.jpg"%(temp_prefix,pic_num))
|
||||
|
||||
# Super high-tech image quality recognition filter
|
||||
# (pick the largest image... thanks daveake!)
|
||||
pic_list = glob.glob("%s*.jpg"%temp_prefix)
|
||||
pic_sizes = []
|
||||
for pic in pic_list:
|
||||
pic_sizes.append(os.path.getsize(pic))
|
||||
largest_pic = pic_list[pic_sizes.index(max(pic_sizes))]
|
||||
|
||||
# Copy best image to resultant filename.
|
||||
os.system("cp %s %s" % (largest_pic, filename))
|
||||
|
||||
# Remove temporary images
|
||||
os.system("rm %s*.jpg"%temp_prefix)
|
||||
|
||||
if __name__ == "__main__":
|
||||
capture_multiple()
|
10
rx_ssdv.py
10
rx_ssdv.py
|
@ -24,6 +24,10 @@ def ssdv_packet_info(packet):
|
|||
if len(packet) != 256:
|
||||
return {'error': "ERROR: Invalid Packet Length"}
|
||||
|
||||
if (packet[1] != 0x66) and (packet[1] != 0x67):
|
||||
print("Not a SSDV Packet! Contents: %s" % str(data))
|
||||
return {'error': "ERROR: Not a SSDV Packet."}
|
||||
|
||||
# We got this far, may as well try and extract the packet info.
|
||||
try:
|
||||
packet_info = {
|
||||
|
@ -79,16 +83,16 @@ while True:
|
|||
# Attempt to decode current image, and write out to a file.
|
||||
temp_f.close()
|
||||
# Run SSDV
|
||||
returncode = os.system("ssdv -d rxtemp.bin %s_%d.jpg" % (current_packet_time,current_image))
|
||||
returncode = os.system("ssdv -d rxtemp.bin ./rx_images/%s_%d.jpg" % (current_packet_time,current_image))
|
||||
if returncode == 1:
|
||||
print("ERROR: SSDV Decode failed!")
|
||||
else:
|
||||
print("SSDV Decoded OK!")
|
||||
# Make a copy of the raw binary data.
|
||||
os.system("mv rxtemp.bin %s_%d.bin" % (current_packet_time,current_image))
|
||||
os.system("mv rxtemp.bin ./rx_images/%s_%d.bin" % (current_packet_time,current_image))
|
||||
|
||||
# Update live displays here.
|
||||
trigger_gui_update("%s_%d.jpg" % (current_packet_time,current_image))
|
||||
trigger_gui_update("./rx_images/%s_%d.jpg" % (current_packet_time,current_image))
|
||||
|
||||
# Trigger upload to habhub here.
|
||||
else:
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Start RX using an Airspy.
|
||||
#
|
||||
python rx_gui.py &
|
||||
airspy_rx -f441.0 -r /dev/stdout -a 1 -h 21 | csdr convert_s16_f | csdr bandpass_fir_fft_cc 0.025 0.175 0.025 | csdr fractional_decimator_ff 2.708277 | csdr realpart_cf | csdr convert_f_s16 | ./fsk_demod 2X 8 923096 115387 - - S 2> >(python fskdemodgui.py) | ./drs232 - - | python rx_ssdv.py --partialupdate 16
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Start RX using a rtlsdr.
|
||||
#
|
||||
python rx_gui.py &
|
||||
rtl_sdr -s 1000000 -f 441000000 -g 35 - | csdr convert_u8_f | csdr bandpass_fir_fft_cc 0.1 0.4 0.05 | csdr fractional_decimator_ff 1.08331 | csdr realpart_cf | csdr convert_f_s16 | ./fsk_demod 2X 8 923096 115387 - - S 2> >(python fskdemodgui.py --wide) | ./drs232 - - | python rx_ssdv.py --partialupdate 16
|
|
@ -0,0 +1,10 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Wenet TX-side Initialisation Script
|
||||
# 2016-08-07 Mark Jessop <vk5qi@rfhead.net>
|
||||
#
|
||||
# Run this to set up an attached RFM22B and start transmitting!
|
||||
# Replace the transmit frequency and callsign with your own.
|
||||
#
|
||||
python init_rfm22b.py 441.200
|
||||
python tx_picam.py VK5QI &
|
20
tx_picam.py
20
tx_picam.py
|
@ -1,16 +1,23 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# PiCam Transmitter Script
|
||||
# Capture images from the PiCam, and transmit them,
|
||||
# Capture images from the PiCam, and transmit them.
|
||||
#
|
||||
# Mark Jessop <vk5qi@rfhead.net>
|
||||
#
|
||||
|
||||
import PacketTX, sys, os, datetime
|
||||
from picam_wrapper import *
|
||||
|
||||
# Set to whatever resolution you want to transmit.
|
||||
tx_resolution = "1024x768"
|
||||
callsign = "VK5QI"
|
||||
try:
|
||||
callsign = sys.argv[1]
|
||||
if len(callsign)>6:
|
||||
callsign = callsign[:6]
|
||||
except:
|
||||
print("Usage: python tx_picam.py CALLSIGN")
|
||||
sys.exit(1)
|
||||
|
||||
print("Using callsign: %s" % callsign)
|
||||
|
||||
|
||||
debug_output = False # If True, packet bits are saved to debug.bin as one char per bit.
|
||||
|
@ -45,12 +52,13 @@ try:
|
|||
# Capture image using PiCam
|
||||
print("Capturing Image...")
|
||||
capture_time = datetime.datetime.utcnow().strftime("%Y%m%d-%H%M%SZ")
|
||||
os.system("raspistill -t 100 -o ./tx_images/%s.jpg -vf -hf -w 1024 -h 768" % capture_time)
|
||||
capture_multiple(filename="./tx_images/%s.jpg"%capture_time)
|
||||
#os.system("raspistill -t 100 -o ./tx_images/%s.jpg -vf -hf -w 1024 -h 768" % capture_time)
|
||||
# Resize using convert
|
||||
print("Processing...")
|
||||
#os.system("convert temp.jpg -resize %s\! temp.jpg" % tx_resolution)
|
||||
# SSDV'ify the image.
|
||||
os.system("ssdv -e -c %s -i %d ./tx_images/%s.jpg temp.ssdv" % (callsign,image_id,capture_time))
|
||||
os.system("ssdv -e -n -c %s -i %d ./tx_images/%s.jpg temp.ssdv" % (callsign,image_id,capture_time))
|
||||
# Transmit image
|
||||
print("Transmitting...")
|
||||
transmit_file("temp.ssdv",tx)
|
||||
|
|
Ładowanie…
Reference in New Issue