Common issues and solutions for building, running, and debugging the UniSat CubeSat platform.
Symptom: WARNING: ARM toolchain not found, building for host (test mode)
Cause: arm-none-eabi-gcc is not in your PATH.
Solution:
# Ubuntu/Debian
sudo apt install gcc-arm-none-eabi
# macOS
brew install --cask gcc-arm-embedded
# Windows — download from https://developer.arm.com/downloads/-/gnu-rm
# Add the bin/ directory to your PATH
After installing, verify: arm-none-eabi-gcc --version
Symptom: fatal error: cmsis_os2.h: No such file or directory
Cause: FreeRTOS and CMSIS-RTOS2 headers are not included in the base repo. The firmware expects STM32CubeMX-generated middleware.
Solution:
Middlewares/ directory into firmware/stm32/.CMakeLists.txt:
include_directories(stm32/Middlewares/Third_Party/FreeRTOS/Source/include)
Alternatively, build in simulation mode (host build) which skips FreeRTOS:
cd firmware && mkdir build && cd build
cmake .. && make
The SIMULATION_MODE define is set automatically when the ARM toolchain is absent.
sgp4Symptom: error: Microsoft Visual C++ 14.0 or greater is required (Windows)
Solution: The sgp4 package includes C extensions. Install Build Tools for Visual Studio, or use a pre-built wheel:
pip install sgp4 --only-binary=:all:
aiofilesSymptom: ModuleNotFoundError: No module named 'aiofiles'
Solution: This dependency is required by the flight-software DataLogger:
cd flight-software
pip install -r requirements.txt
Symptom: serial.serialutil.SerialException: [Errno 13] could not open port /dev/ttyS0: [Errno 13] Permission denied
Solution:
# Add your user to the dialout group
sudo usermod -aG dialout $USER
# Log out and back in, then verify
groups | grep dialout
Symptom: FileNotFoundError: [Errno 2] No such file or directory: '/dev/ttyS0'
Cause: The default serial port in CommunicationManager is /dev/ttyS0. Your device may be at a different path.
Solution: Pass the correct port via config:
comm = CommunicationManager(config={"port": "/dev/ttyUSB0", "baud_rate": 9600})
On Windows, use COM3 (or whichever port your device is on):
comm = CommunicationManager(config={"port": "COM3"})
Symptom: FileNotFoundError: mission_config.json when starting the flight controller
Solution: The controller looks for mission_config.json first in the CWD, then in the repository root. Either:
cd unisat && python flight-software/flight_controller.pyFlightController("/absolute/path/to/mission_config.json")cd configurator && streamlit run configurator_app.pySymptom: sqlite3.OperationalError: database is locked
Cause: The DataLogger uses check_same_thread=False for async access. Multiple processes writing to the same database file simultaneously can cause locks.
Solution: Ensure only one FlightController instance writes to a given db_dir at a time. If testing, delete data/telemetry_current.db and restart.
Symptom: bash: streamlit: command not found
Solution:
cd ground-station
pip install -r requirements.txt
# If still not found, use the module directly:
python -m streamlit run app.py
Symptom: The browser opens but the page is blank or shows a spinner indefinitely.
Possible causes:
pip install -r ground-station/requirements.txtstreamlit run app.py --server.port 8502
plotly >= 5.18.0.Symptom: Dashboard displays synthetic data instead of real telemetry.
Cause: The ground station pages generate demo data when no serial connection is configured. This is by design for development.
Solution: To connect to real hardware, configure the serial port in mission_config.json under ground_station.network_port and ensure the TNC (e.g., Direwolf) is running and forwarding packets.
Symptom: Error: unable to find a matching CMSIS-DAP device or No ST-Link detected
Solution:
sudo apt install stlink-toolsst-info --probeCause: The Nucleo board is not powered, or the target MCU is in a locked state.
Solution:
st-flash erase
st-flash write firmware/build/unisat_firmware.bin 0x08000000
Solution using SWD with OpenOCD:
openocd -f interface/stlink.cfg -f target/stm32f4x.cfg \
-c "program firmware/build/unisat_firmware.elf verify reset exit"
If OpenOCD fails, try STM32CubeProgrammer as an alternative:
STM32_Programmer_CLI -c port=SWD -w firmware/build/unisat_firmware.bin 0x08000000 -v -rst
Symptom: Packet too short or Bad sync word: 0x... errors in logs
Cause: The parser expects packets starting with the 4-byte sync word 0x1ACFFC1D. Possible causes:
Solution:
CommunicationManager.CCSDS_Init() was called).Symptom: crc_valid: False in parsed CCSDSPacket
Cause: The ground station ccsds_parser.py uses CRC-16/CCITT (poly 0x1021). The firmware must use the same polynomial.
Solution: Check firmware/stm32/Core/Src/ccsds.c uses the matching CRC algorithm. If you modified the firmware CRC, update crc16_ccitt() in ground-station/utils/ccsds_parser.py to match.
Symptom: decode_obc(data) or similar returns {}
Cause: The payload bytes are shorter than the decoder expects. Minimum sizes:
Solution: Verify the firmware telemetry packing matches the expected struct layout. Check firmware/stm32/Core/Src/telemetry.c against the struct formats in ground-station/utils/telemetry_decoder.py.
Symptom: ModuleNotFoundError: No module named 'orbit_simulator'
Cause: The simulation scripts use relative imports and must be run from the simulation/ directory.
Solution:
cd simulation
pip install -r requirements.txt
python mission_analyzer.py
Symptom: plot_ground_track() runs but no window appears.
Solution: The visualize.py script saves figures as HTML files. Open the generated files in a browser:
cd simulation
python visualize.py
# Open output_ground_track.html, output_power_budget.html, output_thermal.html
For interactive display, use Jupyter or call fig.show() instead of fig.write_html().