Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/flight-software/lib/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ adafruit-circuitpython-asyncio @ git+https://github.com/adafruit/adafruit_circui
adafruit-circuitpython-drv2605==1.3.4
adafruit-circuitpython-lis2mdl==2.1.23
adafruit-circuitpython-lsm6ds==4.5.13
adafruit-circuitpython-mcp9808==3.3.24
adafruit-circuitpython-neopixel==6.3.12
adafruit-circuitpython-register==1.10.1
adafruit-circuitpython-rfm==1.0.3
Expand All @@ -15,3 +14,4 @@ adafruit-circuitpython-hashlib==1.4.19
Adafruit_CircuitPython_MCP230xx
proves-circuitpython-rv3028 @ git+https://github.com/proveskit/PROVES_CircuitPython_RV3028@1.0.0
proves-circuitpython-sx1280 @ git+https://github.com/proveskit/CircuitPython_SX1280@1.0.3
circuitpython-hmac @ git+https://github.com/jimbobbennett/CircuitPython_HMAC@0.2.1
4 changes: 3 additions & 1 deletion src/flight-software/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from lib.pysquared.beacon import Beacon
from lib.pysquared.cdh import CommandDataHandler
from lib.pysquared.config.config import Config
from lib.pysquared.config.jokes_config import JokesConfig
from lib.pysquared.hardware.busio import _spi_init, initialize_i2c_bus
from lib.pysquared.hardware.digitalio import initialize_pin
from lib.pysquared.hardware.imu.manager.lsm6dsox import LSM6DSOXManager
Expand Down Expand Up @@ -45,6 +46,7 @@

logger.debug("Initializing Config")
config: Config = Config("config.json")
jokes_config: JokesConfig = JokesConfig("jokes.json")

loiter_time: int = 5
for i in range(loiter_time):
Expand Down Expand Up @@ -138,7 +140,7 @@
0.2,
)

cdh = CommandDataHandler(logger, config, uhf_packet_manager)
cdh = CommandDataHandler(logger, config, uhf_packet_manager, jokes_config)

beacon = Beacon(
logger,
Expand Down
195 changes: 184 additions & 11 deletions src/flight-software/repl.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import json
import os
import time

Expand All @@ -8,6 +9,7 @@
from lib.pysquared.beacon import Beacon
from lib.pysquared.cdh import CommandDataHandler
from lib.pysquared.config.config import Config
from lib.pysquared.config.jokes_config import JokesConfig
from lib.pysquared.file_validation.manager.file_validation import FileValidationManager
from lib.pysquared.hardware.burnwire.manager.burnwire import BurnwireManager
from lib.pysquared.hardware.busio import _spi_init, initialize_i2c_bus
Expand All @@ -22,7 +24,7 @@
from lib.pysquared.hardware.radio.manager.rfm9x import RFM9xManager
from lib.pysquared.hardware.radio.manager.sx1280 import SX1280Manager
from lib.pysquared.hardware.radio.packetizer.packet_manager import PacketManager
from lib.pysquared.hardware.temperature_sensor.manager.mcp9808 import MCP9808Manager
from lib.pysquared.hardware.temperature_sensor.manager.tmp112 import TMP112Manager
from lib.pysquared.logger import Logger
from lib.pysquared.nvm.counter import Counter
from lib.pysquared.protos.power_monitor import PowerMonitorProto
Expand All @@ -49,6 +51,7 @@

logger.debug("Initializing Config")
config: Config = Config("config.json")
jokes_config: JokesConfig = JokesConfig("jokes.json")


def get_temp(sensor):
Expand Down Expand Up @@ -163,8 +166,7 @@ def get_temp(sensor):
0.2,
)

cdh = CommandDataHandler(logger, config, uhf_packet_manager)

cdh = CommandDataHandler(logger, config, uhf_packet_manager, jokes_config)
beacon = Beacon(
logger,
config.cubesat_name,
Expand Down Expand Up @@ -278,46 +280,46 @@ def all_faces_on():
# temp_sensor6 = None
# temp_sensors.append(temp_sensor6)

# TCA-connected temp sensors
# TCA-connected temp sensors (TMP112 default address 0x48)
try:
sensor = MCP9808Manager(logger, tca[0], addr=27)
sensor = TMP112Manager(logger, tca[0]) # type: ignore[arg-type]
temp_sensors.append(sensor)
except Exception:
logger.debug("WARNING!!! Temp sensor (TCA[0]) failed")
temp_sensors.append(None)
try:
sensor = MCP9808Manager(logger, tca[1], addr=27)
sensor = TMP112Manager(logger, tca[1]) # type: ignore[arg-type]
temp_sensors.append(sensor)
except Exception:
logger.debug("WARNING!!! Temp sensor 1 failed")
temp_sensors.append(None)
try:
sensor = MCP9808Manager(logger, tca[2], addr=27)
sensor = TMP112Manager(logger, tca[2]) # type: ignore[arg-type]
temp_sensors.append(sensor)
except Exception:
logger.debug("WARNING!!! Temp sensor 2 failed")
temp_sensors.append(None)
try:
sensor = MCP9808Manager(logger, tca[3], addr=27)
sensor = TMP112Manager(logger, tca[3]) # type: ignore[arg-type]
temp_sensors.append(sensor)
except Exception:
logger.debug("WARNING!!! Temp sensor 3 failed")
temp_sensors.append(None)
try:
sensor = MCP9808Manager(logger, tca[5], addr=24)
sensor = TMP112Manager(logger, tca[5]) # type: ignore[arg-type]
temp_sensors.append(sensor)
except Exception:
logger.debug("WARNING!!! Temp sensor 4 failed (Z- Face Bottom pins")
temp_sensors.append(None)
# these are the bottom 6 pins on the z- face connection, uncomment if that is where you plug in a face for the z- board
# try:
# sensor = MCP9808Manager(logger, tca[6], addr=24)
# sensor = TMP112Manager(logger, tca[6])
# temp_sensors.append(sensor)
# except Exception:
# logger.debug("WARNING!!! Temp sensor 4 failed (Z- Face Top pins)")
# # temp_sensors.append(None)
try:
sensor = MCP9808Manager(logger, tca[7], addr=25)
sensor = TMP112Manager(logger, tca[7]) # type: ignore[arg-type]
temp_sensors.append(sensor)
except Exception:
logger.debug("WARNING!!! Temp sensor 5 failed (Antenna Board)")
Expand All @@ -337,3 +339,174 @@ def all_faces_on():
antenna_deployment = BurnwireManager(
logger, burnwire_heater_enable, burnwire1_fire, enable_logic=True
)


def test_magnetorquer():
print("____ Test: Magnetorquer _______")
m_val_1 = magnetometer.get_magnetic_field().value
print("Magnetorquer value (initial):", m_val_1)
print("You have 2 seconds to move the FC board")
time.sleep(2)
m_val_2 = magnetometer.get_magnetic_field().value
print("Magnetorquer value (after):", m_val_2)
diff = tuple(m_val_1[i] - m_val_2[i] for i in range(3))
print("Difference:", diff)
return input("Is this acceptable? (Y/N): ").strip().upper()


def test_imu():
print("\n____ Test: IMU Sensors _______")
imu_results = {}
# Acceleration
acc1 = imu.get_acceleration().value
print("Initial acceleration:", acc1)
print("You have 2 seconds to move the FC board")
time.sleep(2)
acc2 = imu.get_acceleration().value
print("New acceleration:", acc2)
acc_diff = tuple(acc1[i] - acc2[i] for i in range(3))
print("Acceleration difference:", acc_diff)
imu_results["acceleration"] = input("Is this acceptable? (Y/N): ").strip().upper()
# Angular velocity
ang1 = imu.get_angular_velocity().value
print("Initial angular velocity:", ang1)
print("You have 2 seconds to move the FC board")
time.sleep(2)
ang2 = imu.get_angular_velocity().value
print("New angular velocity:", ang2)
ang_diff = tuple(ang1[i] - ang2[i] for i in range(3))
print("Angular velocity difference:", ang_diff)
imu_results["angular_velocity"] = (
input("Is this acceptable? (Y/N): ").strip().upper()
)
# Temperature
temp1 = imu.get_temperature().value
print("Initial temperature:", temp1)
print("You have 10 seconds to heat the temp sensor")
time.sleep(10)
temp2 = imu.get_temperature().value
print("New temperature:", temp2)
temp_diff = temp1 - temp2
print("Temperature difference:", temp_diff)
imu_results["temperature"] = input("Is this acceptable? (Y/N): ").strip().upper()
return imu_results


def test_burnwire():
print("\n____ Test: Burnwire _______")
choice = input("Would you like to try the burnwire test (Y/N)?: ").strip().lower()
if choice == "y":
print("Burning for 5 seconds....")
antenna_deployment.burn(5)
print("Finished burning.")
return input("Did the burnwire get hot? (Y/N): ").strip().upper()
return "N/A"


def test_light_sensors():
print("\n____ Test: LEDs and Light Sensors _______")
load_switches = [
load_switch_0,
load_switch_1,
load_switch_2,
load_switch_3,
load_switch_4,
]
light_results = {}
for i, switch in enumerate(load_switches):
print(f"\nTesting Load Switch {i}")
switch.disable_load()
led_off = input("Did a face LED turn OFF? (Y/N): ").strip().upper()
switch.enable_load()
led_on = input("Did the face LED turn ON? (Y/N): ").strip().upper()
sensor = light_sensors[i]
if sensor is not None:
lux_before = sensor.get_lux().value
print("Initial lux:", lux_before)
time.sleep(2)
lux_after = sensor.get_lux().value
print("New lux:", lux_after)
sensor_result = (
input("Did the lux value change noticeably? (Y/N): ").strip().upper()
)
else:
lux_before = lux_after = "N/A"
sensor_result = "N"
light_results[f"load_switch_{i}"] = {
"led_off": led_off,
"led_on": led_on,
"lux_changed": sensor_result,
}
return light_results


def test_radio():
print("\n____ Test: UHF Radio _______")
message = {"command": "ping"}
print("Sending Ping Command...")
uhf_packet_manager.send(json.dumps(message).encode("utf-8"))
count = 0
result = "N"
while count < 10:
count += 1
b = uhf_packet_manager.listen(1)
time.sleep(1)
uhf_packet_manager.send(json.dumps(message).encode("utf-8"))

if b is not None:
if b != b"ACK":
print("Received not ACK :")
else:
print("Received ACK response:", b.decode("utf-8"))
result = "Y"
break
return result


def test_battery_monitor():
print("\n____ Test: Battery Power Monitor _______")
value_with_batteries = battery_power_monitor.get_bus_voltage().value
print("Voltage with batteries:", value_with_batteries)
input("Please unplug the batteries and press Enter when done.")
value_without_batteries = battery_power_monitor.get_bus_voltage().value
print("Voltage without batteries:", value_without_batteries)
if (value_with_batteries - value_without_batteries) >= 4.0:
print("Voltage dropped by more than 4V. PASS.")
return "Y"
else:
print("Voltage drop too small. FAIL.")
return "N"


def test_solar_monitor():
print("\n____ Test: Solar Power Monitor _______")
solar_with_light = solar_power_monitor.get_bus_voltage().value
print("Voltage with light:", solar_with_light)
input("Please cover the solar panels and press Enter when ready.")
solar_without_light = solar_power_monitor.get_bus_voltage().value
print("Voltage without light:", solar_without_light)
if (solar_with_light - solar_without_light) >= 0.5:
print("Solar voltage dropped significantly. PASS.")
return "Y"
else:
print("Solar voltage did not drop enough. FAIL.")
return "N"


# ========== MAIN FUNCTION ==========


def test_all():
results = {}
results["magnetorquer"] = test_magnetorquer()
imu_results = test_imu()
results.update({f"imu_{k}": v for k, v in imu_results.items()})
results["burnwire"] = test_burnwire()
light_results = test_light_sensors()
results.update(light_results)
results["radio_send"] = test_radio()
results["battery_power_monitor"] = test_battery_monitor()
results["solar_power_monitor"] = test_solar_monitor()
print("\n===== FINAL RESULTS =====")
for key, val in results.items():
print(f"{key}: {val}")
1 change: 1 addition & 0 deletions src/ground-station/lib/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ adafruit-circuitpython-asyncio @ git+https://github.com/adafruit/adafruit_circui
adafruit-circuitpython-rfm==1.0.3
adafruit-circuitpython-ticks==1.1.1
pysquared-ground-station @ git+https://github.com/proveskit/pysquared@d1b22be#subdirectory=circuitpython-workspaces/ground-station
circuitpython-hmac @ git+https://github.com/jimbobbennett/CircuitPython_HMAC@0.2.1