Skip to content

Repository files navigation

🛰️ FramSat-1 Downlink Reception & Telemetry Decoder

Open-source GNU Radio Companion (GRC) receiver pipeline and Python telemetry decoder for the FramSat-1 CubeSat by Orbit NTNU.

FramSat-1 transmits periodic direct HDLC-framed telemetry beacons on the 70 cm amateur satellite band. This repository provides amateur radio operators with everything needed to receive, demodulate, and extract raw packet frames and sensor telemetry.


📂 Repository Contents

File Description
framsat1_rtlsdr_rx.grc The main GNU Radio Companion flowgraph. Open this in GRC to view and run the receiver visually.
framsat1_rtlsdr_rx.py Standalone Python script generated by GNU Radio. Can be run directly in headless environments (e.g. Raspberry Pi) without opening the GRC GUI.
framsat1_decoder.py Standalone frame and telemetry decoder. Unpacks FS1.0 health data (battery, uptime) and 9x GSS/ESS sensor arrays. Parses raw hex or listens live via --listen.
FramSat_1_Reception_Guide.pdf Full technical documentation and RF specification guide.

📡 Radio Frequency & Modulation Specifications

Parameter Specification
Downlink Frequency 435.141 MHz (IARU Coordinated)
Modulation GFSK (2-FSK with Gaussian filter)
Baud Rate 9600 bps
Frequency Deviation ($\Delta f$) $\pm 3.0$ kHz ($h \approx 0.625$)
Pulse Shaping Gaussian ($BT = 0.5$ / $BT = 1.0$)
Scrambler G3RUH ($1 + x^{12} + x^{17}$, Mask: 0x21)
Bit Encoding NRZI
Frame Format Direct Synchronous HDLC (compatible with AX.25 UI encapsulation)
Frame Length 209 bytes fixed (6 B transport header + 199 B telemetry payload + 4 B CRC)
Telemetry Identifier FS1.0

📊 Housekeeping Telemetry Format

The telemetry beacon begins with the static signature "FS1.0" (located at byte offset 6 following the 6-byte onboard transport header). All multi-byte numeric fields are serialized in standard Big-Endian format (network byte order, MSB first).

In LEOP deployment mode (operating_mode = 2), the 180-byte attitude sensor payload array is zero-padded while sensors remain unpowered to conserve power.

Offset Size Field Type Description
0–4 5 B signature ASCII Beacon sync signature: always "FS1.0"
5 1 B beacon_id uint8 Beacon sequence ID counter
6 1 B operating_mode uint8 1 = Default Mode, 2 = LEOP (Launch/Early Orbit)
7 1 B satellite_rssi uint8 Ground uplink RSSI recorded by satellite
8–9 2 B telecommand_count uint16 Total telecommands accepted by satellite
10 1 B eps_flags uint8 EPS status and subsystem power flags
11–12 2 B reboot_count uint16 Total OBC / EPS reboot counter
13–14 2 B battery_voltage uint16 Battery voltage ($V = \text{val} / 1000.0$ V)
15–18 4 B uptime_sec uint32 Satellite uptime in seconds
19–198 180 B sensor_data Array[9] 9x Attitude sensor samples (Sun Sensor & Earth Sensor array)

🛠️ GNU Radio Receiver Pipeline

Prerequisites: Requires GNU Radio with gr-satellites and gr-osmosdr installed (both are included out-of-the-box in Radioconda).

The recommended receiver flowgraph (framsat1_rtlsdr_rx.grc) is optimized for standard RTL-SDR dongles:

FramSat-1 GNU Radio Flowgraph

  1. RTL-SDR Source: Samples at a stable 2.4 MSps on 435.141 MHz with RF gain set to 40 dB.
  2. Low Pass Filter (Decimator): Decimates by 25 down to 96 kSps with a 40 kHz cutoff to suppress adjacent out-of-band noise.
  3. FSK Demodulator & NRZI: Demodulates the GFSK signal and decodes transitions.
  4. Descrambler & HDLC Deframer: Descrambles G3RUH and validates the 16-bit CRC-CCITT (FCS).

⚡ How to Run & Decode

Mode 1: Graphical Interface (GNU Radio Companion)

  1. Plug in your RTL-SDR dongle.
  2. Open framsat1_rtlsdr_rx.grc in GNU Radio Companion.
  3. Press Execute (Play). Received frames will print directly in the Message Debug console. (Optional: Enable the Socket PDU block to simultaneously stream packets over TCP).

Mode 2: Headless Live Reception (Command Line)

For server setups (e.g. Raspberry Pi), run the SDR receiver in the background and attach the live decoder:

# Terminal 1: Start the RTL-SDR receiver
python3 framsat1_rtlsdr_rx.py

# Terminal 2: Listen and decode live frames over TCP (port 52001)
python3 framsat1_decoder.py --listen

Mode 3: Offline Frame Inspection

Pass a received hexadecimal string as a command-line argument to parse historical or recorded frames.

Test against verified on-orbit LEOP frame (Beacon #181, 8.308 V Battery, 13.46 hours uptime):

python3 framsat1_decoder.py 8500850000cf4653312e30b50200000000000120740000bd59000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ce47af75

Expected terminal output:

=================================================================
🛰️  FramSat-1 Frame Received at ...
   Total Frame Length: 209 bytes
   Telemetry Found:    Offset index 6
   Transport Header:   8500850000CF (6 bytes)

   ─── [ FramSat-1 Housekeeping Telemetry ] ───
   Signature:             FS1.0
   Beacon ID:             #181
   Operating Mode:        LEOP (Launch / Deployment Mode)
   Satellite Uplink RSSI: N/A (No uplink signal received)
   Telecommands Accepted: 0
   EPS Flags:             0x00
   OBC / EPS Reboot Count:1
   Battery Voltage:       8.308 V (8308 mV)
   Satellite Uptime:      48473 s (13.46 hours)

   ─── [ Attitude Sensors (LEOP Mode) ] ───
   Status:                Sensors unpowered during deployment (180 bytes zero-padded).
=================================================================

📄 Full PDF Guide

For complete technical details, download the included FramSat_1_Reception_Guide.pdf.

📬 Submitting Reception Reports

We welcome reception reports and baseband recordings! Please submit reports via email to satcom@orbitntnu.com or upload observations to the SatNOGS Network under satellite FramSat-1.

About

FramSat-1 GNU Radio receiver flowgraph and AX.25 frame decoder for amateur radio operators.

Resources

Stars

6 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages