From 04dda2aadfcef2fe3f52aae88521b2bf76cabc11 Mon Sep 17 00:00:00 2001 From: Alan Johnston Date: Thu, 5 Mar 2026 15:56:29 -0500 Subject: [PATCH] Update transmit.py resolve merge conflicts --- transmit.py | 737 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 456 insertions(+), 281 deletions(-) diff --git a/transmit.py b/transmit.py index 602dd3cd..57feed85 100644 --- a/transmit.py +++ b/transmit.py @@ -3,13 +3,99 @@ import RPi.GPIO as GPIO from RPi.GPIO import output #import subprocess -#import time +import time from time import sleep #import os import sys from os import system +from os import path from PIL import Image, ImageDraw, ImageFont, ImageColor import serial +import random +import subprocess + +def output(pin, value): + if (pin != 20): + command = "gpio -g write " + str(pin) + " " + str(value) + system(command) + print(command) + else: # ptt pin + GPIO.output(pin, value) + +def input(pin): + # command = "gpio -g read " + str(pin) + query = ["gpio", "-g", "read", str(pin)] # Read GPIO pin + try: + result = subprocess.run(query, capture_output=True, text=True, check=True) + print(f"Command run was: {query}") + print("Sucess!") + print(f"Output of the command (stdout): {result.stdout}") + return int(result.stdout) + except subprocess.CalledProcessError as e: + print(f"Command failed with return code: {e.returncode}") + print(f"Command run was: {e.cmd}") + print(f"Output of the command (stdout): {e.stdout}") + print(f"Error output of the command (stderr): {e.stderr}") + return -1 + +def setup(pin, config): + if config == "in" or config == "out" or config == "up" or config == "down": + if (pin != 20): + command = "gpio -g mode " + str(pin) + " " + config + system(command) + print(command) + else: # ptt pin + GPIO.setwarnings(False) + GPIO.setmode(GPIO.BCM) + if config == "out: + GPIO.setup(27, GPIO.OUT) + else: + GPIO.setup(27, GPIO.IN) + else: + print(f"Unknown GPIO setup configuration: {config}") + +def blink(times): + powerPin = 16 + for i in range(times): + system("gpio -g write " + str(powerPin) + " 0") # blink two times + sleep(0.1) + system("gpio -g write " + str(powerPin) + " 1") + sleep(0.1) + +def sim_failure_check(): + try: + global card + global cam_fail + global sim_mode + global sim_config + cam_fail = False + file = open("/home/pi/CubeSatSim/failure_mode.txt") + fail_mode = int(file.read(2)) +# print("Fail_mode: ") +# print(fail_mode) + if (fail_mode == 11): + card = "Device" # Change audio so no FM audio plays + print("Failure mode no FM audio") + sim_mode = True + elif (fail_mode == 7): + cam_fail = True + print("Failure mode camera fail") + sim_mode = True + card = "Headphones" + elif (fail_mode == -1): + print("No failure mode") + card = "Headphones" + if sim_config: + sim_mode = True + else: + print("Other failure mode") + card = "Headphones" + sim_mode = True + except: + print("No failure mode") + card = "Headphones" + if sim_config: + sim_mode = True def battery_saver_check(): try: @@ -22,6 +108,14 @@ def battery_saver_check(): except: print("battery saver not activated") # txc = True + +def blink(times): + powerPin = 16 + for i in range(times): + output(powerPin, 0) # blink + sleep(0.1) + output(powerPin, 1) + sleep(0.1) def increment_mode(): print("increment mode") @@ -38,76 +132,26 @@ def increment_mode(): print(mode) if (mode == 'a'): mode = 'f' - GPIO.output(powerPin, 0) # blink two times - sleep(0.1) - GPIO.output(powerPin, 1) - sleep(0.1) - GPIO.output(powerPin, 0) - sleep(0.1) - GPIO.output(powerPin, 1) + blink(2) sleep(2.5) elif (mode == 'f'): mode = 'b' - GPIO.output(powerPin, 0) # blink three times - sleep(0.1) - GPIO.output(powerPin, 1) - sleep(0.1) - GPIO.output(powerPin, 0) - sleep(0.1) - GPIO.output(powerPin, 1) - sleep(0.1) - GPIO.output(powerPin, 0) - sleep(0.1) - GPIO.output(powerPin, 1) + blink(3) sleep(2.5) elif (mode == 'b'): mode = 's' - GPIO.output(powerPin, 0) # blink four times - sleep(0.1) - GPIO.output(powerPin, 1) - sleep(0.1) - GPIO.output(powerPin, 0) - sleep(0.1) - GPIO.output(powerPin, 1) - sleep(0.1) - GPIO.output(powerPin, 0) - sleep(0.1) - GPIO.output(powerPin, 1) - sleep(0.1) - GPIO.output(powerPin, 0) - sleep(0.1) - GPIO.output(powerPin, 1) + blink(4) sleep(2.5) elif (mode == 's'): mode = 'm' - GPIO.output(powerPin, 0) # blink five times - sleep(0.1) - GPIO.output(powerPin, 1) - sleep(0.1) - GPIO.output(powerPin, 0) - sleep(0.1) - GPIO.output(powerPin, 1) - sleep(0.1) - GPIO.output(powerPin, 0) - sleep(0.1); - GPIO.output(powerPin, 1) - sleep(0.1) - GPIO.output(powerPin, 0) - sleep(0.1) - GPIO.output(powerPin, 1) - sleep(0.1) - GPIO.output(powerPin, 0) - sleep(0.1) - GPIO.output(powerPin, 1) + blink(5) sleep(2.5) else: mode = 'a' - GPIO.output(powerPin, 0) # blink one time - sleep(0.1) - GPIO.output(powerPin, 1) + blink(1) sleep(2.5) try: @@ -117,13 +161,13 @@ def increment_mode(): file.close() print(".mode file written") - GPIO.setwarnings(False) - GPIO.output(txLed, 0) - GPIO.output(powerPin, 0) +# GPIO.setwarnings(False) + output(txLed, 0) + output(powerPin, 0) print("sudo reboot -h now") - GPIO.setwarnings(False) - GPIO.setup(powerPin, GPIO.OUT) - GPIO.output(powerPin, 0); +# GPIO.setwarnings(False) + setup(powerPin, "out") + output(powerPin, 0); # system("reboot -h now") # release = True; @@ -135,8 +179,57 @@ def increment_mode(): except: print("can't write to .mode file") +def camera_photo(): + global cam_fail + global os_status + sim_failure_check() + system("sudo rm /home/pi/CubeSatSim/camera_out.jpg") + stored_image = False + try: + if os_status == "bookworm": + system("rpicam-still -o /home/pi/CubeSatSim/camera_out.jpg --width 320 --height 256") # > /dev/null 2>&1") + else: + system("raspistill -o /home/pi/CubeSatSim/camera_out.jpg -w 320 -h 256") + f = open("/home/pi/CubeSatSim/camera_out.jpg") + f.close() + print("Photo taken") + if (cam_fail == True): + system("cp /home/pi/CubeSatSim/sstv//sstv_image_2_320_x_256.jpeg /home/pi/CubeSatSim/camera_out.jpg") + print("Using stored image") + stored_image = True + except: + system("cp /home/pi/CubeSatSim/sstv//sstv_image_2_320_x_256.jpeg /home/pi/CubeSatSim/camera_out.jpg") + print("Using stored image") + stored_image = True + if (stored_image == False): + file='/home/pi/CubeSatSim/camera_out.jpg' + font1 = ImageFont.truetype('DejaVuSerif.ttf', 20) + font2 = ImageFont.truetype('DejaVuSerif-Bold.ttf', 16) + + try: + filep = open("/home/pi/CubeSatSim/telem_string.txt") + telem_string = filep.readline() + except: + telem_string = "" + if (debug_mode == 1): + print("Can't read telem_string.txt") + print(telem_string) + + img = Image.open(file) + draw = ImageDraw.Draw(img) + # draw.text((10, 10), callsign, font=font2, fill='white') + # draw.text((120, 10), telem_string, font=font2, fill='white') + draw.text((12, 12), callsign, font=font1, fill='black') + draw.text((10, 10), callsign, font=font1, fill='white') + draw.text((112, 12), telem_string, font=font2, fill='black') # was 122 + draw.text((110, 10), telem_string, font=font2, fill='white') # was 120 + img.save(file) -print("CubeSatSim v2.1 transmit.py starting...") + return True + else: + return False + +print("CubeSatSim v2.2 transmit.py starting...") pd = 21 ptt = 20 @@ -147,20 +240,18 @@ powerPin = 16 command_tx = True -GPIO.setmode(GPIO.BCM) -GPIO.setwarnings(False) -GPIO.setup(13, GPIO.IN, pull_up_down=GPIO.PUD_UP) -GPIO.setup(12, GPIO.IN, pull_up_down=GPIO.PUD_UP) -GPIO.setup(27, GPIO.IN, pull_up_down=GPIO.PUD_UP) -GPIO.setup(txc_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP) -GPIO.setup(green, GPIO.OUT) -GPIO.output(powerPin, 1) +# GPIO.setmode(GPIO.BCM) +# GPIO.setwarnings(False) +setup(13, "up") +setup(12, "up") +setup(27, "up") +setup(txc_pin, "up") +setup(green, "out") +output(powerPin, 1) transmit = False txLed = 27 -txLedOn = 1 -txLedOff = 0 -if GPIO.input(12) == False: +if input(12) == False: print("LPF present") transmit = True else: @@ -168,38 +259,38 @@ else: # GPIO.setup(txLed, GPIO.OUT) -# output(txLed, txLedOff) +# output(txLed, 0) -GPIO.setmode(GPIO.BCM) # Repeat to make LED work on Pi 4 -GPIO.setwarnings(False) -GPIO.setup(txLed, GPIO.OUT) +# GPIO.setmode(GPIO.BCM) # Repeat to make LED work on Pi 4 +# GPIO.setwarnings(False) +setup(txLed, "out") -GPIO.setup(pd, GPIO.OUT) +setup(pd, "out") #output(pd, 1) output(pd, 0) -GPIO.setup(ptt, GPIO.OUT) +setup(ptt, "out") output (ptt, 1) txc = False -if GPIO.input(txc_pin) == False: +if input(txc_pin) == False: print("TXC is present") txc = True; else: print("TXC not present") # txc = False # forcing it off -output(txLed, txLedOn) +output(txLed, 1) sleep(1) -output(txLed, txLedOff) +output(txLed, 0) battery_saver_check() -# print(txLedOn) +# print(1) print(txLed) # GPIO.setup(27, GPIO.OUT) # GPIO.output(27, 0) -debug_mode = 0 #no debugging transmit +debug_mode = 0 # change to 1 to debug transmit skip = False @@ -218,6 +309,14 @@ if __name__ == "__main__": print(transmit) + uptime_time = 55 # 55 second boot time if Pi Zero + try: + f = open("/home/pi/CubeSatSim/pi_zero2", "r") + f.close() + print("Pi Zero 2 detected!") + uptime_time = 30 # 30 second boot time if Pi Zero 2 + except: + print("Pi Zero 2 not detected") try: system("cat /proc/uptime > /home/pi/CubeSatSim/uptime") @@ -226,14 +325,16 @@ if __name__ == "__main__": print(up) uptime = float(up) print(uptime) - if (uptime < 45): - print("Uptime < 45 seconds") + if (uptime < uptime_time): + print("Uptime < threshold seconds") else: - print("Uptime > 45 seconds") + print("Uptime > threshold seconds") + print("Skip CW ID") skip = True file.close() except: print("Can't open /proc/uptime") + print(skip) if ( mode == "y"): try: @@ -277,29 +378,53 @@ if __name__ == "__main__": rx_value = '0' sq = '0' tx = '434.9000' - rx = '435.0000' + rx = '435.0000' + txr = '144.9000' + sim_mode = False + sim_config = False + hab_mode = False try: file = open("/home/pi/CubeSatSim/sim.cfg") # callsign = file.readline().split(" ")[0] config = file.readline().split() callsign = config[0] + if len(config) > 4: + if config[4] == 'y' or config[4] == 'yes': + sim_mode = True + sim_config = True + print("Simulated telemetry mode is configured") + else: + try: + if path.isfile("/home/pi/CubeSatSim/sim_mode_auto"): + print("Simulated telemetry mode automatically turned on!") + sim_mode = True + sim_config = True + except: + if (debug_mode == 1): + print("/home/pi/CubeSatSim/sim_mode_auto not found") if len(config) > 5: if (mode != 'p') and (mode != 'P'): # squelch off for Pacsat sq = config[5] print(f'squelch: {sq}') if len(config) > 6: - txf = float(config[6]) -# print(txf) -# print( "{:.4f}".format(txf)) - tx = "{:.4f}".format(txf) - print(tx) + txf = float(config[6]) + if (mode == 'e'): + txr = (txf - 290.0) # - 0.1 # Cross Band Repeater mode transmit frequency in 2m band + tx = "{:.4f}".format(txr) + else: + tx = "{:.4f}".format(txf) + print("Transmit frequency: ",tx) if len(config) > 7: rxf = float(config[7]) # print(rxf) # print( "{:.4f}".format(rxf)) rx = "{:.4f}".format(rxf) print(rx) + if len(config) > 8: + if config[8] == 'y' or config[8] == 'yes': + hab_mode = True + print("Balloon (HAB) mode is configured.") if len(config) > 9: rxpl = float(config[9]) # print(rxpl) @@ -316,11 +441,11 @@ if __name__ == "__main__": print # print(callsign) print(sq) - if sq == '8': - print("squelch set to 8, no command input!") - no_command = True - else: - no_command = False +# if sq == '8': +# print("squelch set to 8, no command input!") +# no_command = True +# else: + no_command = False print(no_command) except: callsign = "AMSAT" @@ -328,92 +453,119 @@ if __name__ == "__main__": print("Can't read callsign from sim.cfg file, defaulting to AMSAT") file.close() - if (mode != 'p') and (mode != 'P'): - try: - f = open("/home/pi/CubeSatSim/command_control", "r") - f.close() - GPIO.setmode(GPIO.BCM) - GPIO.setwarnings(False) - GPIO.setup(squelch, GPIO.IN, pull_up_down=GPIO.PUD_UP) ## pull up in case pin is not connected - if GPIO.input(squelch) == False: - print("squelch not set correctly, no command input!") - no_command = True - else: + no_command = True + try: + f = open("/home/pi/CubeSatSim/command_control", "r") + f.close() +# GPIO.setmode(GPIO.BCM) +# GPIO.setwarnings(False) + setup(squelch, "up") ## pull up in case pin is not connected + if input(squelch) == False: + print("squelch not set correctly, no command input!") + else: + if (mode != 'n') and (mode != 'x'): print("command and control is activated") no_command = False - # system("/home/pi/CubeSatSim/command &") system("sudo systemctl start command") - except: - print("command and control not activated") - no_command = True - + else: + print("Command and control not activated since Transmit Commands mode") + txc = True # Transmit commands only works with FM transceiver, so bypass Battery Saver if activated + except: + print("command and control not activated") + print(callsign) - GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi 4 - print(txLed) - print(txLedOn) - GPIO.setup(txLed, GPIO.OUT) +# GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi 4 +# print(txLed) +# print(1) +# setup(txLed, "out") + query = ["grep", "VERSION_CODENAME=bullseye", "/etc/os-release"] + try: + result = subprocess.run(query, capture_output=True, text=True, check=True) + print(f"Command run was: {query}") + os_status = result.stdout.strip() + print(f"Output of the command (stdout): {os_status}") + except subprocess.CalledProcessError as e: +# print(f"Command failed with return code: {e.returncode}") + print(f"Command run was: {e.cmd}") + os_status = e.stdout.strip() + print(f"Output of the command (stdout): {e.stdout}") +# print(f"Error output of the command (stderr): {e.stderr}") + if os_status != "VERSION_CODENAME=bullseye": + os_status = "bookworm" + else: + os_status = "bullseye" + print (os_status) + card = "Headphones" # default using pcm audio output of Pi Zero # card = "Device" # using USB sound card for audio output - print("Programming FM module!\n"); - output(pd, 1) - output (ptt, 1) + query = ["sudo", "systemctl", "is-active", "gpsd.socket"] try: - ser = serial.Serial("/dev/ttyAMA0", 9600) - print(ser.portstr) -# uhf_string = "AT+DMOSETGROUP=0," + rx +"," + tx + ",0,3,0,0\r\n" - uhf_string = "AT+DMOSETGROUP=0," + rx + "," + tx + "," + rxpl_value + "," + sq + "," + txpl_value + ",0\r\n" - print(uhf_string) - for i in range(6): -# ser.write(b"AT+DMOSETGROUP=0,435.0000,434.9000,0,3,0,0\r\n") - ser.write(uhf_string.encode()) - sleep(0.1) - ser.close() - ser = serial.Serial("/dev/ttyAMA0", 115200) # reset back to 115200 for cubesatsim code for payload sensor data - except: - print("Error in serial write") - output(pd, 0) - -# if (mode != 'x') and (skip == False): -# sleep(10) # delay so cubesatsim code catches up - - system("echo 'hi hi de " + callsign + "' > id.txt && gen_packets -M 20 /home/pi/CubeSatSim/id.txt -o /home/pi/CubeSatSim/morse.wav -r 48000 > /dev/null 2>&1") - -# command_control_check() - -# if (mode != ) and (command_tx == True): -# if (command_tx == True): - if ((mode == 'a') or (mode == 'b') or (mode == 'f') or (mode == 's') or (mode == 'p') or (mode == 'P')) and (command_tx == True) and (skip == False): -# battery_saver_mode - GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 - GPIO.setup(txLed, GPIO.OUT) - output(txLed, txLedOn) -# if (txc): -# output(pd, 1) -# output (ptt, 0) -# sleep(0.1) -# system("aplay -D plughw:CARD=" + card + ",DEV=0 /home/pi/CubeSatSim/morse.wav") -# sleep(0.1) -# output (ptt, 1) -# output(pd, 0) -# else: - if (True): + result = subprocess.run(query, capture_output=True, text=True, check=True) + print(f"Command run was: {query}") + gpsd_status = result.stdout.strip() + print(f"Output of the command (stdout): {gpsd_status}") + except subprocess.CalledProcessError as e: +# print(f"Command failed with return code: {e.returncode}") + print(f"Command run was: {e.cmd}") + gpsd_status = e.stdout.strip() + print(f"Output of the command (stdout): {e.stdout}") +# print(f"Error output of the command (stderr): {e.stderr}") + + if (mode != 'e'): + + if (gpsd_status == "active"): + print("Stopping gpsd.socket") + system("sudo systemctl stop gpsd.socket") + print("Programming FM module!\n"); + output(pd, 1) + output (ptt, 1) + try: + ser = serial.Serial("/dev/ttyAMA0", 9600) + print(ser.portstr) + # uhf_string = "AT+DMOSETGROUP=0," + rx +"," + tx + ",0,3,0,0\r\n" + uhf_string = "AT+DMOSETGROUP=0," + rx + "," + tx + "," + rxpl_value + "," + sq + "," + txpl_value + ",0\r\n" + print(uhf_string) + for i in range(6): + # ser.write(b"AT+DMOSETGROUP=0,435.0000,434.9000,0,3,0,0\r\n") + ser.write(uhf_string.encode()) + sleep(0.1) + ser.close() + ser = serial.Serial("/dev/ttyAMA0", 115200) # reset back to 115200 for cubesatsim code for payload sensor data + except: + print("Error in serial write") + output(pd, 0) + if (gpsd_status == "active"): + print("Restarting gpsd.socket") + system("sudo systemctl restart gpsd.socket") + + sim_failure_check() + if (hab_mode == True) and (mode == 'a'): + print("Don't transmit CW ID since APRS HAB mode is active") + else: + if (((mode == 'a') or (mode == 'b') or (mode == 'f') or (mode == 's') or (mode == 'j') or (mode == 'p') or (mode == 'P')) and (command_tx == True) and (skip == False)) or ((mode == 'e') and (command_tx == True)): # battery_saver_mode +# GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 +# setup(txLed, "out") + output(txLed, 1) + print("Transmit CW ID") + status = "" + if not no_command: + status = status + " C" + if sim_mode: + status = status + " S" if (debug_mode == 1): -# system("echo 'hi hi de " + callsign + "' > id.txt && gen_packets -M 20 /home/pi/CubeSatSim/id.txt -o /home/pi/CubeSatSim/morse.wav -r 48000 > /dev/null 2>&1 && cat /home/pi/CubeSatSim/morse.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f 434.9e3") - system("echo 'hi hi de " + callsign + "' > id.txt && gen_packets -M 20 /home/pi/CubeSatSim/id.txt -o /home/pi/CubeSatSim/morse.wav -r 48000 > /dev/null 2>&1 && cat /home/pi/CubeSatSim/morse.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f " + tx + "e3") + system("echo 'hi hi de " + callsign + status + "' > id.txt && gen_packets -M 20 /home/pi/CubeSatSim/id.txt -o /home/pi/CubeSatSim/morse.wav -r 48000 > /dev/null 2>&1 && cat /home/pi/CubeSatSim/morse.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f " + tx + "e3") else: -# system("echo 'hi hi de " + callsign + "' > id.txt && gen_packets -M 20 /home/pi/CubeSatSim/id.txt -o /home/pi/CubeSatSim/morse.wav -r 48000 > /dev/null 2>&1 && cat /home/pi/CubeSatSim/morse.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f 434.9e3 > /dev/null 2>&1") - system("echo 'hi hi de " + callsign + "' > id.txt && gen_packets -M 20 /home/pi/CubeSatSim/id.txt -o /home/pi/CubeSatSim/morse.wav -r 48000 > /dev/null 2>&1 && cat /home/pi/CubeSatSim/morse.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f " + tx + "e3 > /dev/null 2>&1") + system("echo 'hi hi de " + callsign + status + "' > id.txt && gen_packets -M 20 /home/pi/CubeSatSim/id.txt -o /home/pi/CubeSatSim/morse.wav -r 48000 > /dev/null 2>&1 && cat /home/pi/CubeSatSim/morse.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f " + tx + "e3 > /dev/null 2>&1") + output(txLed, 0) + + sleep(1) + else: + print("Don't transmit CW ID since command_tx is False or APRS mode or change of mode") + - output(txLed, txLedOff) - - sleep(1) - else: - print("Don't transmit CW ID since command_tx is False or APRS mode") - if (transmit): - # print 'Length: ', len(sys.argv) # if (len(sys.argv)) > 1: @@ -451,12 +603,13 @@ if __name__ == "__main__": GPIO.output(txLed, 0) print("0") else: - GPIO.output(powerPin, 0) +# GPIO.output(powerPin, 0) print("Transmit APRS Commands") + system("sudo systemctl stop command") # while True: # sleep(0.1) - if (mode != 'n'): - system("touch /home/pi/CubeSatSim/ready") +# if (mode != 'n'): +# system("touch /home/pi/CubeSatSim/ready") while True: try: @@ -467,20 +620,21 @@ if __name__ == "__main__": system("gen_packets -o /home/pi/CubeSatSim/telem.wav /home/pi/CubeSatSim/t.txt -r 48000 > /dev/null 2>&1") system("cat /home/pi/CubeSatSim/t.txt") if (command_tx == True): - GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 - GPIO.setup(txLed, GPIO.OUT) - output(txLed, txLedOn) +# GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 +# setup(txLed, "out") + output(txLed, 1) # output(pd, 1) # output (ptt, 0) # sleep(.1) # # battery_saver_check() if (txc): + sim_failure_check() # output(pd, 1) sleep(0.1) # add delay before transmit output (ptt, 0) sleep(0.3) # add even more time at start - system("aplay -D plughw:CARD=" + card + ",DEV=0 /home/pi/CubeSatSim/telem.wav") + system("aplay -D plughw:CARD=" + card + ",DEV=0 /home/pi/CubeSatSim/telem.wav") sleep(0.2) # add more time at end output (ptt, 1) # output(pd, 0) @@ -494,7 +648,7 @@ if __name__ == "__main__": sleep(0.1) # output (ptt, 1) # output(pd, 0) - output(txLed, txLedOff) + output(txLed, 0) system("sudo rm /home/pi/CubeSatSim/ready") f.close() @@ -502,11 +656,12 @@ if __name__ == "__main__": print("Ready for next packet!") sleep(0.5) + except: # command_control_check() sleep(1) elif (mode == 'm'): - system("touch /home/pi/CubeSatSim/cwready") +# system("touch /home/pi/CubeSatSim/cwready") print("CW") while True: # command_control_check() @@ -523,11 +678,12 @@ if __name__ == "__main__": system(command) ## chan = chan + 1 if (command_tx == True): - GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 - GPIO.setup(txLed, GPIO.OUT) - output(txLed, txLedOn) +# GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 +# setup(txLed, "out") + output(txLed, 1) if (txc): + sim_failure_check() # output (pd, 1) sleep(0.3) output (ptt, 0) @@ -539,8 +695,8 @@ if __name__ == "__main__": if (debug_mode == 1): system("cat /home/pi/CubeSatSim/morse.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f " + tx + "e3") else: - system("cat /home/pi/CubeSatSim/morse.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f " + tx + "e3 > /dev/null 2>&1") - output(txLed, txLedOff) + system("cat /home/pi/CubeSatSim/morse.wav | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f " + tx + "e3 > /dev/null 2>&1") + output(txLed, 0) # command_control_check() sleep(2) @@ -559,7 +715,10 @@ if __name__ == "__main__": # from pysstv.sstv import SSTV # camera = PiCamera() print("Testing for camera") - system("raspistill -o /home/pi/CubeSatSim/camera_out.jpg -w 320 -h 256") + if os_status == "bookworm": + system("rpicam-still -o /home/pi/CubeSatSim/camera_out.jpg --width 320 --height 256") # > /dev/null 2>&1") + else: + system("raspistill -o /home/pi/CubeSatSim/camera_out.jpg -w 320 -h 256") f = open("/home/pi/CubeSatSim/camera_out.jpg") f.close() print("Camera present") @@ -571,7 +730,7 @@ if __name__ == "__main__": camera_present = 0 # while 1: - output(txLed, txLedOff) + output(txLed, 0) # output (ptt, 1) # output(pd, 0) if (camera_present == 1): @@ -583,12 +742,13 @@ if __name__ == "__main__": if (command_tx == True): print ("Sending SSTV image") - GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 - GPIO.setup(txLed, GPIO.OUT) - output(txLed, txLedOn) +# GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 +# setup(txLed, "out") + output(txLed, 1) # battery_saver_check() if (txc): + sim_failure_check() # output(pd, 1) output (ptt, 0) system("aplay -D plughw:CARD=" + card + ",DEV=0 /home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg.wav") @@ -600,42 +760,14 @@ if __name__ == "__main__": else: system("cat /home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg.wav | csdr convert_i16_f | csdr gain_ff 14000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f " + tx + "e3 > /dev/null 2>&1") - output(txLed, txLedOff) + output(txLed, 0) # sleep(1) except: print("image 2 did not load - copy from CubeSatSim/sstv directory") while 1: # command_control_check() - - system("raspistill -o /home/pi/CubeSatSim/camera_out.jpg -w 320 -h 256") # > /dev/null 2>&1") - print("Photo taken") - - file='/home/pi/CubeSatSim/camera_out.jpg' - font1 = ImageFont.truetype('DejaVuSerif.ttf', 20) - font2 = ImageFont.truetype('DejaVuSerif-Bold.ttf', 16) - - try: - filep = open("/home/pi/CubeSatSim/telem_string.txt") - telem_string = filep.readline() - except: - telem_string = "" - if (debug_mode == 1): - print("Can't read telem_string.txt") - print(telem_string) - - img = Image.open(file) - draw = ImageDraw.Draw(img) -# draw.text((10, 10), callsign, font=font2, fill='white') -# draw.text((120, 10), telem_string, font=font2, fill='white') - draw.text((12, 12), callsign, font=font1, fill='black') - draw.text((10, 10), callsign, font=font1, fill='white') - draw.text((122, 12), telem_string, font=font2, fill='black') - draw.text((120, 10), telem_string, font=font2, fill='white') - img.save(file) - -# command_control_check() - + camera_photo() system("/home/pi/PiSSTVpp/pisstvpp -r 48000 -p s2 /home/pi/CubeSatSim/camera_out.jpg") system("sudo rm /home/pi/CubeSatSim/camera_out.jpg > /dev/null 2>&1") @@ -643,12 +775,14 @@ if __name__ == "__main__": if (command_tx == True): print ("Sending SSTV image") - GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 - GPIO.setup(txLed, GPIO.OUT) - output(txLed, txLedOn) +# GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 +# setup(txLed, "out") + output(txLed, 1) # battery_saver_check() if (txc): +# print(card) + sim_failure_check() # output(pd, 1) output (ptt, 0) system("aplay -D plughw:CARD=" + card + ",DEV=0 /home/pi/CubeSatSim/camera_out.jpg.wav") @@ -660,7 +794,7 @@ if __name__ == "__main__": else: system("cat /home/pi/CubeSatSim/camera_out.jpg.wav | csdr convert_i16_f | csdr gain_ff 14000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f " + tx + "e3 > /dev/null 2>&1") - output(txLed, txLedOff) + output(txLed, 0) # output (ptt, 1) # output(pd, 0) @@ -679,13 +813,14 @@ if __name__ == "__main__": if (command_tx == True): print ("Sending SSTV image") - GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 - GPIO.setup(txLed, GPIO.OUT) - output(txLed, txLedOn) +# GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 +# setup(txLed, "out") + output(txLed, 1) # battery_saver_check() if (txc): + sim_failure_check() # output(pd, 1) output (ptt, 0) system("aplay -D plughw:CARD=" + card + ",DEV=0 /home/pi/CubeSatSim/sstv_image_1_320_x_256.jpg.wav") @@ -697,7 +832,7 @@ if __name__ == "__main__": else: system("cat /home/pi/CubeSatSim/sstv_image_1_320_x_256.jpg.wav | csdr convert_i16_f | csdr gain_ff 14000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f " + tx + "e3 > /dev/null 2>&1") - output(txLed, txLedOff) + output(txLed, 0) # output (ptt, 1) # output(pd, 0) sleep(1) @@ -716,12 +851,13 @@ if __name__ == "__main__": if (command_tx == True): print ("Sending SSTV image") - GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 - GPIO.setup(txLed, GPIO.OUT) - output(txLed, txLedOn) +# GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 +# setup(txLed, "out") + output(txLed, 1) # battery_saver_check() if (txc): + sim_failure_check() # output(pd, 1) output (ptt, 0) system("aplay -D plughw:CARD=" + card + ",DEV=0 /home/pi/CubeSatSim/sstv_image_1_320_x_256.jpg.wav") @@ -733,7 +869,7 @@ if __name__ == "__main__": else: system("cat /home/pi/CubeSatSim/sstv_image_2_320_x_256.jpg.wav | csdr convert_i16_f | csdr gain_ff 14000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f " + tx + "e3 > /dev/null 2>&1") - output(txLed, txLedOff) + output(txLed, 0) # output (ptt, 1) # output(pd, 0) sleep(10) @@ -746,13 +882,14 @@ if __name__ == "__main__": if (command_tx == True): # command_control_check() - GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 - GPIO.setup(txLed, GPIO.OUT) - output(txLed, txLedOn) +# GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 +# setup(txLed, "out") + output(txLed, 1) # battery_saver_check() if (txc): + sim_failure_check() # output(pd, 1) output (ptt, 0) system("aplay -D plughw:CARD=" + card + ",DEV=0 /home/pi/CubeSatSim/sstv.wav") @@ -761,102 +898,140 @@ if __name__ == "__main__": else: sleep(60) - output(txLed, txLedOff) + output(txLed, 0) # output (ptt, 1) # output(pd, 0) sleep(10) - elif (mode == 'b'): + elif (mode == 'b') or (mode == 'j'): # command_control_check() - print("BPSK") + if (mode == 'b'): + print("BPSK") + else: + print("FUNcube") print("turn on FM rx") output(pd, 1) output(ptt, 1) - GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi 4 - GPIO.setup(txLed, GPIO.OUT) +# GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi 4 +# setup(txLed, "out") if (command_tx == True): # system("sudo nc -l 8080 | csdr convert_i16_f | csdr fir_interpolate_cc 2 | csdr dsb_fc | csdr bandpass_fir_fft_cc 0.002 0.06 0.01 | csdr fastagc_ff | sudo /home/pi/rpitx/sendiq -i /dev/stdin -s 96000 -f 434.9e6 -t float &") system("sudo nc -l 8080 | csdr convert_i16_f | csdr fir_interpolate_cc 2 | csdr dsb_fc | csdr bandpass_fir_fft_cc 0.002 0.06 0.01 | csdr fastagc_ff | sudo /home/pi/rpitx/sendiq -i /dev/stdin -s 96000 -f " + tx + "e6 -t float &") print("Turning LED on/off and listening for carrier") + image_id = random.randint(0, 255) + print("Initial image_id: " + str(image_id) + "\n") while 1: - output(txLed, txLedOff) +# print ("LED on") + output(txLed, 0) sleep(0.4) # if (command_tx == False): -# output(txLed, txLedOn) +# output(txLed, 1) # sleep(0.03) -# output(txLed, txLedOff) +# output(txLed, 0) # command_control_check() if (command_tx == True): - GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 - GPIO.setup(txLed, GPIO.OUT) - output(txLed, txLedOn) +# GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 +# setup(txLed, "out") + output(txLed, 1) # print(txLed) -# print(txLedOn) - sleep(4.2) +# print(1) + + if (mode == 'b'): + sleep(4.2) + else: # FUNcube mode image + for i in range(4): +# print("Checking image_file.bin") + try: + file = open("/home/pi/CubeSatSim/image_file.bin") + file.close() + # image_present = True + sleep(1.0) + except: + # image_present = False + + # if (image_present == False): + start = time.perf_counter() + camera_photo() + system("/home/pi/ssdv/ssdv -e -n -i " + str(image_id) + " -q 3 -J /home/pi/CubeSatSim/camera_out.jpg /home/pi/CubeSatSim/image_file.bin") + print("image_id: " + str(image_id) + "\n") + image_id = ( image_id + 1 ) % 256 + print("new image_id: " + str(image_id) + "\n") + elapsed_time = time.perf_counter() - start + print("Elapsed time: ") + print(elapsed_time) + if (elapsed_time < 9): + sleep(9 - time.perf_counter() + start) + # else: + sleep(0.6) elif (mode == 'e'): # code based on https://zr6aic.blogspot.com/2016/11/creating-2m-fm-repeater-with-raspberry.html - print("Repeater") - print("Stopping command and control") - system("sudo systemctl stop command") + print("Cross Band Repeater Mode") +# print("Stopping command and control") +# system("sudo systemctl stop command") print("turn on FM rx") output(pd, 1) output(ptt, 1) - GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi 4 - GPIO.setup(txLed, GPIO.OUT) - GPIO.setup(powerPin, GPIO.OUT) - GPIO.setup(squelch, GPIO.IN, pull_up_down=GPIO.PUD_UP) ## pull up in case pin is not connected - GPIO.output(powerPin, 0) +# GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi 4 +# setup(txLed, "out") +# GPIO.setup(powerPin, GPIO.OUT) + setup(squelch, "up") ## pull up in case pin is not connected +# GPIO.output(powerPin, 1) # was 0 +# txf = float(tx) - 288.9 +# print("Transmit frequency: ",txf) + if (command_tx != True): + print("Beacon mode off so no repeater transmission") + + print("Ready to detect carrier") while True: - sleep(0.5) - if (GPIO.input(squelch) == False): + if (input(squelch) == False) and (command_tx == True): print("Carrier detected, starting repeater") - GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 - GPIO.setup(txLed, GPIO.OUT) - output(txLed, txLedOn) -# system("arecord -D plughw:CARD=Device,DEV=0 | csdr convert_i16_f | csdr gain_ff 14000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f " + tx + "e3 &") -## system("arecord -D plughw:CARD=Device,DEV=0 -f S16_LE -r 48000 -c 1 | csdr convert_s16_f | csdr gain_ff 14000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f " + tx + "e3 &") - system("sudo nc -l 8011 | csdr convert_i16_f | csdr gain_ff 16000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f " + tx + "e3 &") - sleep(1) - system("sudo arecord -D plughw:CARD=Device,DEV=0 -r48000 -fS16_LE -c1 | nc localhost 8011 &") - GPIO.output(powerPin, 1) +# GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 +# setup(txLed, "out") + output(txLed, 1) + system("sudo nc -l 8011 | csdr convert_i16_f | csdr gain_ff 16000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f " + tx + "e3 > /dev/null 2>&1 &") sleep(0.5) - GPIO.output(powerPin, 0) - while (GPIO.input(squelch) == False): + system("sudo arecord -D shared_mic -r48000 -fS16_LE -c1 | nc localhost 8011 &") + while (input(squelch) == False): sleep(1) print("No carrier detected, stopping repeater") - output(txLed, txLedOff) + output(txLed, 0) + system("sudo rpitx -i null > /dev/null 2>&1") system("sudo killall -9 arecord > /dev/null 2>&1") system("sudo killall -9 nc > /dev/null 2>&1") system("sudo killall -9 rpitx > /dev/null 2>&1") - + print("Resetting audio") + system("sudo /etc/init.d/alsa-utils stop") + system("sudo /etc/init.d/alsa-utils start") + print("Finished resetting audio") + print("Ready to detect carrier") else: print("FSK") print("turn on FM rx") output(pd, 1) output(ptt, 1) - GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi 4 - GPIO.setup(txLed, GPIO.OUT) +# GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi 4 +# setup(txLed, "out") if (command_tx == True): system("sudo nc -l 8080 | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo /home/pi/rpitx/rpitx -i- -m RF -f " + tx + "e3 &") print("Turning LED on/off and listening for carrier") while 1: - output(txLed, txLedOff) + output(txLed, 0) sleep(0.4) # if (command_tx == False): -# output(txLed, txLedOn) +# output(txLed, 1) # sleep(0.03) -# output(txLed, txLedOff) +# output(txLed, 0) # command_control_check() if (command_tx == True): - GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 - GPIO.setup(txLed, GPIO.OUT) - output(txLed, txLedOn) +# GPIO.setmode(GPIO.BCM) # added to make Tx LED work on Pi Zero 2 and Pi 4 +# setup(txLed, "out") + output(txLed, 1) # print(txLed) -# print(txLedOn) +# print(1) sleep(4.2) else: print("No Low Pass Filter so no telemetry transmit. See http://cubesatsim.org/wiki for instructions on how to build the LPF.")