diff --git a/PacketTX.py b/PacketTX.py index 3d8f0df..d2039e1 100644 --- a/PacketTX.py +++ b/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("") + 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) diff --git a/picam_wrapper.py b/picam_wrapper.py new file mode 100644 index 0000000..8170045 --- /dev/null +++ b/picam_wrapper.py @@ -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() diff --git a/rx_images/rx_images_go_here.txt b/rx_images/rx_images_go_here.txt new file mode 100644 index 0000000..e69de29 diff --git a/rx_ssdv.py b/rx_ssdv.py index 2c9231f..e627729 100644 --- a/rx_ssdv.py +++ b/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: diff --git a/start_rx_airspy.sh b/start_rx_airspy.sh new file mode 100644 index 0000000..eae0042 --- /dev/null +++ b/start_rx_airspy.sh @@ -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 \ No newline at end of file diff --git a/start_rx_rtlsdr.sh b/start_rx_rtlsdr.sh new file mode 100755 index 0000000..74396cb --- /dev/null +++ b/start_rx_rtlsdr.sh @@ -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 \ No newline at end of file diff --git a/start_tx.sh b/start_tx.sh new file mode 100755 index 0000000..ad60744 --- /dev/null +++ b/start_tx.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# +# Wenet TX-side Initialisation Script +# 2016-08-07 Mark Jessop +# +# 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 & diff --git a/tx_picam.py b/tx_picam.py index 0499564..d53f5ad 100644 --- a/tx_picam.py +++ b/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 # 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)