From 3f1996faf2d6c391252de20046dcb7dc6730e6f6 Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Mon, 19 May 2025 19:10:42 -0400 Subject: [PATCH 1/2] Add beacon functionality --- .gitignore | 1 + lib/proveskit_rp2040_v4/__init__.py | 0 lib/proveskit_rp2040_v4/register.py | 8 ++++ main.py | 69 +++++++++++++++++------------ repl.py | 7 +-- 5 files changed, 51 insertions(+), 34 deletions(-) create mode 100644 lib/proveskit_rp2040_v4/__init__.py create mode 100644 lib/proveskit_rp2040_v4/register.py diff --git a/.gitignore b/.gitignore index 75b636d..0d454ea 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ firmware.uf2 # libs /lib/* !/lib/requirements.txt +!/lib/proveskit_rp2040_v4/ diff --git a/lib/proveskit_rp2040_v4/__init__.py b/lib/proveskit_rp2040_v4/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/lib/proveskit_rp2040_v4/register.py b/lib/proveskit_rp2040_v4/register.py new file mode 100644 index 0000000..46bbc83 --- /dev/null +++ b/lib/proveskit_rp2040_v4/register.py @@ -0,0 +1,8 @@ +class Register: + boot_count = 0 + error_count = 7 + flag = 16 + + +class BitIndex: + use_fsk = 7 diff --git a/main.py b/main.py index 62b28c2..619b4eb 100644 --- a/main.py +++ b/main.py @@ -23,7 +23,8 @@ import os import lib.pysquared.functions as functions -import lib.pysquared.nvm.register as register +from lib.proveskit_rp2040_v4.register import BitIndex, Register +from lib.pysquared.beacon import Beacon from lib.pysquared.cdh import CommandDataHandler from lib.pysquared.config.config import Config from lib.pysquared.hardware.busio import _spi_init, initialize_i2c_bus @@ -35,15 +36,20 @@ from lib.pysquared.nvm.counter import Counter from lib.pysquared.nvm.flag import Flag from lib.pysquared.rtc.manager.microcontroller import MicrocontrollerManager -from lib.pysquared.satellite import Satellite from lib.pysquared.sleep_helper import SleepHelper from lib.pysquared.watchdog import Watchdog from version import __version__ +boot_time: float = time.monotonic() + rtc = MicrocontrollerManager() +(boot_count := Counter(index=Register.boot_count)).increment() +error_count: Counter = Counter(index=Register.error_count) +use_fsk = Flag(index=Register.flag, bit_index=BitIndex.use_fsk) + logger: Logger = Logger( - error_counter=Counter(index=register.ERRORCNT), + error_counter=error_count, colorized=False, ) @@ -53,9 +59,8 @@ software_version=__version__, ) -loiter_time: int = 5 - try: + loiter_time: int = 5 for i in range(loiter_time): logger.info(f"Code Starting in {loiter_time-i} seconds") time.sleep(1) @@ -77,7 +82,7 @@ radio = RFM9xManager( logger, config.radio, - Flag(index=register.FLAG, bit_index=7), + use_fsk, spi0, initialize_pin(logger, board.SPI0_CS0, digitalio.Direction.OUTPUT, True), initialize_pin(logger, board.RF1_RST, digitalio.Direction.OUTPUT, True), @@ -94,38 +99,43 @@ imu = LSM6DSOXManager(logger, i2c1, 0x6B) - c = Satellite(logger, config) - - sleep_helper = SleepHelper(c, logger, watchdog, config) + sleep_helper = SleepHelper(logger, watchdog, config) cdh = CommandDataHandler(config, logger, radio) + beacon = Beacon( + logger, + config.cubesat_name, + radio, + boot_time, + imu, + magnetometer, + radio, + use_fsk, + error_count, + boot_count, + ) + f = functions.functions( - c, logger, config, sleep_helper, radio, - magnetometer, - imu, watchdog, cdh, ) def initial_boot(): watchdog.pet() - f.beacon() + beacon.send() watchdog.pet() f.listen() watchdog.pet() try: - c.boot_count.increment() - logger.info( "FC Board Stats", bytes_remaining=gc.mem_free(), - boot_number=c.boot_count.get(), ) initial_boot() @@ -146,11 +156,12 @@ def send_imu_data(): radio.send(IMUData) def main(): - f.beacon() + beacon.send() f.listen_loiter() - f.state_of_health() + # TODO(nateinaction): replace me + # f.state_of_health() f.listen_loiter() @@ -182,22 +193,22 @@ def minimum_power_operations(): try: while True: # L0 automatic tasks no matter the battery level - c.check_reboot() + # TODO(nateinaction): reemplement power level check when we have state of health + # c.check_reboot() - if c.power_mode == "critical": - critical_power_operations() + # if c.power_mode == "critical": + # critical_power_operations() - elif c.power_mode == "minimum": - minimum_power_operations() + # elif c.power_mode == "minimum": + # minimum_power_operations() - elif c.power_mode == "normal": - main() + # elif c.power_mode == "normal": + # main() - elif c.power_mode == "maximum": - main() + # elif c.power_mode == "maximum": + # main() - else: - f.listen() + main() except Exception as e: logger.critical("Critical in Main Loop", e) diff --git a/repl.py b/repl.py index 1ba2b67..3dd7438 100644 --- a/repl.py +++ b/repl.py @@ -1,13 +1,10 @@ -import lib.pysquared.nvm.register as register +from lib.proveskit_rp2040_v4.register import Register from lib.pysquared.config.config import Config from lib.pysquared.logger import Logger from lib.pysquared.nvm.counter import Counter -from lib.pysquared.satellite import Satellite logger: Logger = Logger( - error_counter=Counter(index=register.ERRORCNT), + error_counter=Counter(index=Register.error_count), colorized=False, ) config: Config = Config("config.json") -logger.info("Initializing a cubesat object as `c` in the REPL...") -c: Satellite = Satellite(logger, config) From d01008f224c342a2a89b6e186e28ad46289b685b Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Fri, 30 May 2025 20:42:17 -0400 Subject: [PATCH 2/2] Using packet manager --- config.json | 2 +- main.py | 102 +++++++++++++++++++++++++++++++++++++--------------- uv.lock | 66 ---------------------------------- 3 files changed, 75 insertions(+), 95 deletions(-) diff --git a/config.json b/config.json index af56489..2e9e731 100644 --- a/config.json +++ b/config.json @@ -56,7 +56,7 @@ "longest_allowable_sleep_time": 600, "turbo_clock": false, "radio": { - "license": "", + "license": "KK4PDM", "receiver_id": 250, "sender_id": 251, "start_time": 80000, diff --git a/main.py b/main.py index 619b4eb..4f67f5d 100644 --- a/main.py +++ b/main.py @@ -9,6 +9,8 @@ """ import gc +import os +import random import time import digitalio @@ -20,9 +22,6 @@ except ImportError: import board -import os - -import lib.pysquared.functions as functions from lib.proveskit_rp2040_v4.register import BitIndex, Register from lib.pysquared.beacon import Beacon from lib.pysquared.cdh import CommandDataHandler @@ -32,6 +31,7 @@ from lib.pysquared.hardware.imu.manager.lsm6dsox import LSM6DSOXManager from lib.pysquared.hardware.magnetometer.manager.lis2mdl import LIS2MDLManager from lib.pysquared.hardware.radio.manager.rfm9x import RFM9xManager +from lib.pysquared.hardware.radio.packetizer.packet_manager import PacketManager from lib.pysquared.logger import Logger from lib.pysquared.nvm.counter import Counter from lib.pysquared.nvm.flag import Flag @@ -40,7 +40,7 @@ from lib.pysquared.watchdog import Watchdog from version import __version__ -boot_time: float = time.monotonic() +boot_time: float = time.time() rtc = MicrocontrollerManager() @@ -88,6 +88,13 @@ initialize_pin(logger, board.RF1_RST, digitalio.Direction.OUTPUT, True), ) + packet_manager = PacketManager( + logger, + radio, + config.radio.license, + 0.2, + ) + i2c1 = initialize_i2c_bus( logger, board.I2C1_SCL, @@ -106,7 +113,7 @@ beacon = Beacon( logger, config.cubesat_name, - radio, + packet_manager, boot_time, imu, magnetometer, @@ -116,20 +123,13 @@ boot_count, ) - f = functions.functions( - logger, - config, - sleep_helper, - radio, - watchdog, - cdh, - ) - def initial_boot(): watchdog.pet() beacon.send() watchdog.pet() - f.listen() + message: bytes | None = packet_manager.listen() + if message: + cdh.message_handler(message) watchdog.pet() try: @@ -153,41 +153,87 @@ def send_imu_data(): logger.info("IMU has baton") IMUData = imu.get_gyro_data() watchdog.pet() - radio.send(IMUData) + packet_manager.send(str(IMUData).encode("utf-8")) def main(): + radio.send(config.radio.license.encode("utf-8")) + beacon.send() - f.listen_loiter() + watchdog.pet() + + message: bytes | None = packet_manager.listen() + if message: + cdh.message_handler(message) + + watchdog.pet() + + sleep_helper.safe_sleep(config.sleep_duration) + + watchdog.pet() # TODO(nateinaction): replace me # f.state_of_health() - f.listen_loiter() + message: bytes | None = packet_manager.listen() + if message: + cdh.message_handler(message) + + watchdog.pet() + + sleep_helper.safe_sleep(config.sleep_duration) + + watchdog.pet() + + message: bytes | None = packet_manager.listen() + if message: + cdh.message_handler(message) watchdog.pet() - f.listen_loiter() + sleep_helper.safe_sleep(config.sleep_duration) + + watchdog.pet() send_imu_data() - f.listen_loiter() + watchdog.pet() - f.joke() + message: bytes | None = packet_manager.listen() + if message: + cdh.message_handler(message) - f.listen_loiter() + watchdog.pet() + + sleep_helper.safe_sleep(config.sleep_duration) - def critical_power_operations(): - initial_boot() watchdog.pet() - sleep_helper.long_hibernate() + packet_manager.send(random.choice(config.jokes).encode("utf-8")) + + watchdog.pet() + + message: bytes | None = packet_manager.listen() + if message: + cdh.message_handler(message) + + watchdog.pet() + + sleep_helper.safe_sleep(config.sleep_duration) - def minimum_power_operations(): - initial_boot() watchdog.pet() - sleep_helper.short_hibernate() + # def critical_power_operations(): + # initial_boot() + # watchdog.pet() + + # sleep_helper.long_hibernate() + + # def minimum_power_operations(): + # initial_boot() + # watchdog.pet() + + # sleep_helper.short_hibernate() ######################### MAIN LOOP ############################## try: diff --git a/uv.lock b/uv.lock index f7bf2fa..1a0d04c 100644 --- a/uv.lock +++ b/uv.lock @@ -101,15 +101,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7b/6b/0f13486003aea3eb349c2946b7ec9753e7558b78e35d22c938062a96959c/binho_host_adapter-0.1.6-py3-none-any.whl", hash = "sha256:f71ca176c1e2fc1a5dce128beb286da217555c6c7c805f2ed282a6f3507ec277", size = 10540 }, ] -[[package]] -name = "certifi" -version = "2025.4.26" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e8/9e/c05b3920a3b7d20d3d3310465f50348e5b3694f4f88c6daf736eef3024c4/certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6", size = 160705 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4a/7e/3db2bd1b1f9e95f7cddca6d6e75e2f2bd9f51b1246e546d88addca0106bd/certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3", size = 159618 }, -] - [[package]] name = "cfgv" version = "3.4.0" @@ -119,28 +110,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c5/55/51844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", size = 7249 }, ] -[[package]] -name = "charset-normalizer" -version = "3.4.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e4/33/89c2ced2b67d1c2a61c19c6751aa8902d46ce3dacb23600a283619f5a12d/charset_normalizer-3.4.2.tar.gz", hash = "sha256:5baececa9ecba31eff645232d59845c07aa030f0c81ee70184a90d35099a0e63", size = 126367 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ea/12/a93df3366ed32db1d907d7593a94f1fe6293903e3e92967bebd6950ed12c/charset_normalizer-3.4.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:926ca93accd5d36ccdabd803392ddc3e03e6d4cd1cf17deff3b989ab8e9dbcf0", size = 199622 }, - { url = "https://files.pythonhosted.org/packages/04/93/bf204e6f344c39d9937d3c13c8cd5bbfc266472e51fc8c07cb7f64fcd2de/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eba9904b0f38a143592d9fc0e19e2df0fa2e41c3c3745554761c5f6447eedabf", size = 143435 }, - { url = "https://files.pythonhosted.org/packages/22/2a/ea8a2095b0bafa6c5b5a55ffdc2f924455233ee7b91c69b7edfcc9e02284/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3fddb7e2c84ac87ac3a947cb4e66d143ca5863ef48e4a5ecb83bd48619e4634e", size = 153653 }, - { url = "https://files.pythonhosted.org/packages/b6/57/1b090ff183d13cef485dfbe272e2fe57622a76694061353c59da52c9a659/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98f862da73774290f251b9df8d11161b6cf25b599a66baf087c1ffe340e9bfd1", size = 146231 }, - { url = "https://files.pythonhosted.org/packages/e2/28/ffc026b26f441fc67bd21ab7f03b313ab3fe46714a14b516f931abe1a2d8/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c9379d65defcab82d07b2a9dfbfc2e95bc8fe0ebb1b176a3190230a3ef0e07c", size = 148243 }, - { url = "https://files.pythonhosted.org/packages/c0/0f/9abe9bd191629c33e69e47c6ef45ef99773320e9ad8e9cb08b8ab4a8d4cb/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e635b87f01ebc977342e2697d05b56632f5f879a4f15955dfe8cef2448b51691", size = 150442 }, - { url = "https://files.pythonhosted.org/packages/67/7c/a123bbcedca91d5916c056407f89a7f5e8fdfce12ba825d7d6b9954a1a3c/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1c95a1e2902a8b722868587c0e1184ad5c55631de5afc0eb96bc4b0d738092c0", size = 145147 }, - { url = "https://files.pythonhosted.org/packages/ec/fe/1ac556fa4899d967b83e9893788e86b6af4d83e4726511eaaad035e36595/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ef8de666d6179b009dce7bcb2ad4c4a779f113f12caf8dc77f0162c29d20490b", size = 153057 }, - { url = "https://files.pythonhosted.org/packages/2b/ff/acfc0b0a70b19e3e54febdd5301a98b72fa07635e56f24f60502e954c461/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:32fc0341d72e0f73f80acb0a2c94216bd704f4f0bce10aedea38f30502b271ff", size = 156454 }, - { url = "https://files.pythonhosted.org/packages/92/08/95b458ce9c740d0645feb0e96cea1f5ec946ea9c580a94adfe0b617f3573/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:289200a18fa698949d2b39c671c2cc7a24d44096784e76614899a7ccf2574b7b", size = 154174 }, - { url = "https://files.pythonhosted.org/packages/78/be/8392efc43487ac051eee6c36d5fbd63032d78f7728cb37aebcc98191f1ff/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4a476b06fbcf359ad25d34a057b7219281286ae2477cc5ff5e3f70a246971148", size = 149166 }, - { url = "https://files.pythonhosted.org/packages/44/96/392abd49b094d30b91d9fbda6a69519e95802250b777841cf3bda8fe136c/charset_normalizer-3.4.2-cp313-cp313-win32.whl", hash = "sha256:aaeeb6a479c7667fbe1099af9617c83aaca22182d6cf8c53966491a0f1b7ffb7", size = 98064 }, - { url = "https://files.pythonhosted.org/packages/e9/b0/0200da600134e001d91851ddc797809e2fe0ea72de90e09bec5a2fbdaccb/charset_normalizer-3.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:aa6af9e7d59f9c12b33ae4e9450619cf2488e2bbe9b44030905877f0b2324980", size = 105641 }, - { url = "https://files.pythonhosted.org/packages/20/94/c5790835a017658cbfabd07f3bfb549140c3ac458cfc196323996b10095a/charset_normalizer-3.4.2-py3-none-any.whl", hash = "sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0", size = 52626 }, -] - [[package]] name = "circuitpy-flight-software" version = "2.0.0" @@ -152,7 +121,6 @@ dependencies = [ { name = "pre-commit" }, { name = "pyright", extra = ["nodejs"] }, { name = "pytest" }, - { name = "requests" }, ] [package.metadata] @@ -163,7 +131,6 @@ requires-dist = [ { name = "pre-commit", specifier = "==4.0.1" }, { name = "pyright", extras = ["nodejs"], specifier = "==1.1.399" }, { name = "pytest", specifier = "==8.3.2" }, - { name = "requests", specifier = "==2.32.3" }, ] [[package]] @@ -239,15 +206,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/74/a1/68a395c17eeefb04917034bd0a1bfa765e7654fa150cca473d669aa3afb5/identify-2.6.6-py2.py3-none-any.whl", hash = "sha256:cbd1810bce79f8b671ecb20f53ee0ae8e86ae84b557de31d89709dc2a48ba881", size = 99083 }, ] -[[package]] -name = "idna" -version = "3.10" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 }, -] - [[package]] name = "iniconfig" version = "2.0.0" @@ -405,21 +363,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 }, ] -[[package]] -name = "requests" -version = "2.32.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "certifi" }, - { name = "charset-normalizer" }, - { name = "idna" }, - { name = "urllib3" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 }, -] - [[package]] name = "sysv-ipc" version = "1.1.0" @@ -435,15 +378,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 }, ] -[[package]] -name = "urllib3" -version = "2.4.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8a/78/16493d9c386d8e60e442a35feac5e00f0913c0f4b7c217c11e8ec2ff53e0/urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466", size = 390672 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6b/11/cc635220681e93a0183390e26485430ca2c7b5f9d33b15c74c2861cb8091/urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813", size = 128680 }, -] - [[package]] name = "virtualenv" version = "20.29.1"