diff --git a/FC_Board/code.py b/FC_Board/code.py index b0f1fc3e..ede841bd 100644 --- a/FC_Board/code.py +++ b/FC_Board/code.py @@ -4,8 +4,8 @@ """ Built for the PySquared FC Board -Version: 1.2.0 (Beta) -Published: Nov 12, 2024 +Version: 2.0.0 +Published: Nov 19, 2024 """ import time @@ -13,8 +13,8 @@ print("=" * 70) print("Hello World!") -print("PySquared FC Board Circuit Python Software Version: 1.2.0 (Beta)") -print("Published: November 12, 2024") +print("PySquared FC Board Circuit Python Software Version: 2.0.0") +print("Published: November 19, 2024") print("=" * 70) loiter_time = 5 diff --git a/FC_Board/lib/functions.py b/FC_Board/lib/functions.py index c0484430..36ee0537 100755 --- a/FC_Board/lib/functions.py +++ b/FC_Board/lib/functions.py @@ -34,10 +34,45 @@ def __init__(self, cubesat): self.Errorcount = 0 self.facestring = [None, None, None, None, None] self.jokes = [ - "Hey Its pretty cold up here, did someone forget to pay the electric bill?" + "Hey it is pretty cold up here, did someone forget to pay the electric bill?", + "sudo rf - rf*", + "Why did the astronaut break up with his girlfriend? He needed space.", + "Why did the sun go to school? To get a little brighter.", + "why is the mall called the mall? because instead of going to one store you go to them all", + "Alien detected. Blurring photo...", + "Wait it is all open source? Always has been... www.github.com/proveskit", + "What did 0 say to 1? You're a bit too much.", + "Pleiades - Orpheus has been recently acquired by the Onion News Network", + "This jokesat was brought to you by the Bronco Space Ministry of Labor and Job Placement", + "Catch you on the next pass!", + "Pleiades - Orpheus was not The Impostor", + "Sorry for messing with your long-exposure astrophoto!", + "Better buy a telescope. Wanna see me. Buy a telescope. Gonna be in space.", + "According to all known laws of aviation, there is no way bees should be able to fly...", + "You lost the game ", + "Bobby Tables is a good friend of mine", + "Why did the computer cross the road? To get a byte to eat!", + "Why are the astronauts not hungry when they got to space? They had a big launch.", + "Why did the computer get glasses? To improve its web sight!", + "What are computers favorite snacks? Chips!", + "Wait! I think I see a White 2019 Subaru Crosstrek 2.0i Premium", + "IS THAT A SUPRA?!", + "Finally escpaed the LA Traffic", + "My CubeSat is really good at jokes, but its delivery is always delayed.", + "exec order 66", + "I had a joke about UDP, but I am not sure if you'd get it.", + "I am not saying FSK modulation is the best way to send jokes, but at least it is never monotone!", + "I am sorry David, I am afrain I can not do that.", + "My memory is volatile like RAM, so it only makes sense that I forget things.", + "Imagine it gets stuck and just keeps repeating this joke every 2 mins", + "Check Engine: Error Code 404: Joke Not Found", + "CQ CQ KN6NAQ ... KN6NAT are you out there?", + "Woah is that the Launcher Orbiter?????", + "Everything in life is a spring if you think hard enough!", ] self.last_battery_temp = 20 - self.callsign = "" + self.sleep_duration = 30 + self.callsign = "KO6AZM" self.state_bool = False self.face_data_baton = False self.detumble_enable_z = True @@ -68,6 +103,18 @@ def safe_sleep(self, duration=15): self.cubesat.watchdog_pet() + def listen_loiter(self): + self.debug_print("Listening for 10 seconds") + self.cubesat.watchdog_pet() + self.cubesat.radio1.receive_timeout = 10 + self.listen() + self.cubesat.watchdog_pet() + + self.debug_print("Sleeping for 20 seconds") + self.cubesat.watchdog_pet() + self.safe_sleep(self.sleep_duration) + self.cubesat.watchdog_pet() + """ Radio Functions """ @@ -105,11 +152,10 @@ def beacon(self): try: lora_beacon = ( - f"{self.callsign} Hello I am Yearling^2! I am in: " + f"{self.callsign} Hello I am Orpheus! I am: " + str(self.cubesat.power_mode) - + " power mode. V_Batt = " - + str(self.cubesat.battery_voltage) - + f"V. IHBPFJASTMNE! {self.callsign}" + + f" UT:{self.cubesat.uptime} BN:{self.cubesat.c_boot} EC:{self.cubesat.c_error_count} " + + f"IHBPFJASTMNE! {self.callsign}" ) except Exception as e: self.debug_print( @@ -211,7 +257,7 @@ def listen(self): try: self.debug_print("Listening") self.cubesat.radio1.receive_timeout = 10 - received = self.cubesat.radio1.receive(keep_listening=True) + received = self.cubesat.radio1.receive_with_ack(keep_listening=True) except Exception as e: self.debug_print( "An Error has occured while listening: " @@ -340,7 +386,7 @@ def log_error_data(self, data): def detumble(self, dur=7, margin=0.2, seq=118): self.debug_print("Detumbling") self.cubesat.RGB = (255, 255, 255) - self.cubesat.all_faces_on() + try: import Big_Data diff --git a/FC_Board/lib/pysquared.py b/FC_Board/lib/pysquared.py index 9f1501fc..894dad42 100755 --- a/FC_Board/lib/pysquared.py +++ b/FC_Board/lib/pysquared.py @@ -101,6 +101,7 @@ def __init__(self): self.vlowbatt = 6.0 self.battery_voltage = 3.3 # default value for testing REPLACE WITH REAL VALUE self.current_draw = 255 # default value for testing REPLACE WITH REAL VALUE + self.REBOOT_TIME = 3600 # 1 hour self.turbo_clock = False """ @@ -330,6 +331,7 @@ def __init__(self): self.spi0cs2.switch_to_output() self.can_bus = CAN(self.spi0, self.spi0cs2, loopback=True, silent=True) self.hardware["CAN"] = True + self.can_bus.sleep() except Exception as e: self.debug_print( @@ -446,6 +448,7 @@ def __init__(self): self.error_print( "[ERROR][CAMERA]" + "".join(traceback.format_exception(e)) ) + self.hardware["CAM"] = False else: self.error_print("[ERROR][CAMERA]TCA Not Initialized") @@ -591,7 +594,6 @@ def reset_vbus(self): if self.hardware["SDcard"]: try: umount("/sd") - self.spi1.deinit() time.sleep(3) except Exception as e: self.error_print( @@ -700,7 +702,6 @@ def take_image(self): """ def watchdog_pet(self): - ... self.watchdog_pin.value = True time.sleep(0.01) self.watchdog_pin.value = False @@ -708,7 +709,7 @@ def watchdog_pet(self): def check_reboot(self): self.UPTIME = self.uptime self.debug_print(str("Current up time: " + str(self.UPTIME))) - if self.UPTIME > 86400: + if self.UPTIME > self.REBOOT_TIME: self.micro.reset() def powermode(self, mode): diff --git a/FC_Board/main.py b/FC_Board/main.py old mode 100644 new mode 100755 index b75f0e33..69d731a6 --- a/FC_Board/main.py +++ b/FC_Board/main.py @@ -6,6 +6,9 @@ """ from pysquared import cubesat as c + +c.watchdog_pet() + import asyncio import time import traceback @@ -14,6 +17,8 @@ import functions from debugcolor import co +beacon_interval = 15 + def debug_print(statement): if c.debug: @@ -29,8 +34,8 @@ def initial_boot(): c.watchdog_pet() f.listen() c.watchdog_pet() - f.state_of_health() - f.listen() + # f.state_of_health() + # f.listen() c.watchdog_pet() @@ -47,195 +52,54 @@ def initial_boot(): debug_print("Something went wrong!") -def critical_power_operations(): - - initial_boot() +def send_imu(): + debug_print("Looking to get imu data...") + IMUData = [] c.watchdog_pet() - - f.Long_Hybernate() - - -def minimum_power_operations(): - - initial_boot() + debug_print("IMU has baton") + IMUData = f.get_imu_data() c.watchdog_pet() + f.send(IMUData) - f.Short_Hybernate() - - -def normal_power_operations(): - - debug_print("Entering Norm Operations") - - # Defining L1 Tasks - def check_power(): - gc.collect() - - debug_print("Checking Power State") - - if c.power_mode == "normal" or c.power_mode == "maximum": - pwr = True - if c.power_mode == "normal": - c.RGB = (255, 255, 0) - else: - c.RGB = (0, 255, 0) - else: - pwr = False - - debug_print(c.power_mode) - gc.collect() - return pwr - - async def s_lora_beacon(): - - while check_power(): - f.beacon() - f.listen() - c.watchdog_pet() - f.state_of_health() - f.listen() - c.watchdog_pet() - time.sleep(1) # Guard Time - - await asyncio.sleep(30) - - async def g_face_data(): - - while check_power(): - try: - debug_print("Consider Adding a Logging Function Here!") - f.all_face_data() - - except Exception as e: - debug_print("Outta time! " + "".join(traceback.format_exception(e))) - - gc.collect() - await asyncio.sleep(60) - - async def g_batt_data(): - - while check_power(): - try: - debug_print("Looking to get battery data...") - batt_data = f.get_battery_data() - - debug_print("Battery Data: " + str(batt_data)) - - debug_print(batt_data[0]) - debug_print(batt_data[1]) - debug_print(batt_data[2]) - - c.battery_voltage = batt_data[0] - c.draw_current = batt_data[1] - c.charge_voltage = batt_data[2] - c.charge_current = batt_data[3] - c.is_charging = batt_data[4] - c.battery_percentage = batt_data[5] - - c.check_reboot() - - except Exception as e: - debug_print("Outta time! " + "".join(traceback.format_exception(e))) - - gc.collect() - - await asyncio.sleep(30) - - async def s_face_data(): - - await asyncio.sleep(20) - - while check_power(): - try: - debug_print("Looking to send face data...") - f.send_face() - - except asyncio.TimeoutError as e: - debug_print("Outta time! " + "".join(traceback.format_exception(e))) - - gc.collect() - - await asyncio.sleep(200) - - async def s_imu_data(): - - await asyncio.sleep(45) - - while check_power(): - - try: - debug_print("Looking to get imu data...") - IMUData = [] - - debug_print("IMU has baton") - IMUData = f.get_imu_data() - f.send(IMUData) - f.face_data_baton = False - - except Exception as e: - debug_print("Outta time! " + "".join(traceback.format_exception(e))) +def main(): + f.beacon() - gc.collect() + f.listen_loiter() - await asyncio.sleep(100) + f.state_of_health() - async def detumble(): + f.listen_loiter() - await asyncio.sleep(300) + f.all_face_data() + c.watchdog_pet() + f.send_face() - while check_power(): - try: - debug_print("Looking to detumble...") - f.detumble() - debug_print("Detumble complete") + f.listen_loiter() - except Exception as e: - debug_print(f"Outta time!" + "".join(traceback.format_exception(e))) + send_imu() - gc.collect() + f.listen_loiter() - await asyncio.sleep(300) + f.joke() - async def joke(): - await asyncio.sleep(500) + f.listen_loiter() - while check_power(): - try: - debug_print("Joke send go!") - f.joke() - if f.listen_joke(): - f.joke() - debug_print("done!") - except Exception as e: - debug_print(f"Outta time!" + "".join(traceback.format_exception(e))) - gc.collect() - await asyncio.sleep(500) +def critical_power_operations(): - async def check_watchdog(): + initial_boot() + c.watchdog_pet() - c.hardware["WDT"] = True - while check_power(): - c.watchdog_pet() - await asyncio.sleep(5) - c.hardware["WDT"] = False + f.Long_Hybernate() - async def main_loop(): - # log_face_data_task = asyncio.create_task(l_face_data()) - t1 = asyncio.create_task(s_lora_beacon()) - t2 = asyncio.create_task(s_face_data()) - t3 = asyncio.create_task(s_imu_data()) - t4 = asyncio.create_task(g_face_data()) - t5 = asyncio.create_task(g_batt_data()) - t6 = asyncio.create_task(detumble()) - t7 = asyncio.create_task(joke()) - t8 = asyncio.create_task(check_watchdog()) +def minimum_power_operations(): - await asyncio.gather(t1, t2, t3, t4, t5, t6, t7, t8) + initial_boot() + c.watchdog_pet() - asyncio.run(main_loop()) + f.Short_Hybernate() ######################### MAIN LOOP ############################## @@ -255,11 +119,11 @@ async def main_loop(): elif c.power_mode == "normal": c.RGB = (255, 255, 0) - normal_power_operations() + main() elif c.power_mode == "maximum": c.RGB = (0, 255, 0) - normal_power_operations() + main() else: f.listen()