|
| 1 | +\section{Transmitting data} |
| 2 | + |
| 3 | +Similarly to downlink, the uplink uses AX.25 frames (APRS) encoded as ZeroMQ messages, sent to ground station's endpoint (\texttt{tcp://<host>:7000}). |
| 4 | + |
| 5 | +The message follows AX.25 format: |
| 6 | + |
| 7 | + |
| 8 | +\begin{longtable}{l|l} |
| 9 | + \toprule |
| 10 | + \textbf{Bytes} & \textbf{Meaning} \\ |
| 11 | + \midrule |
| 12 | + \endhead |
| 13 | + 7 bytes & Destination call sign \\ |
| 14 | + 7 bytes & Source call sign \\ |
| 15 | + 1 byte & Frame type (constant 0x03) \\ |
| 16 | + 1 byte & Protocol Id (constant 0xF0) \\ |
| 17 | + 4 bytes & Security Code (verified na OBC) \\ |
| 18 | + 1 byte & Frame APID \\ |
| 19 | + 195 bytes & Frame Payload \\ |
| 20 | + \bottomrule |
| 21 | +\end{longtable} |
| 22 | + |
| 23 | +PW-Sat2 OBC repository contains Python code for all available Telecommands to generate payload for AX.25 frames. Below is an example (simplified) python code to connect to ground station, encode telecommand and transmit it. |
| 24 | + |
| 25 | +\begin{verbatim} |
| 26 | +
|
| 27 | +import aprs |
| 28 | +import zmq |
| 29 | +
|
| 30 | +class Wrap: |
| 31 | + def __init__(self, byte_str): |
| 32 | + self.byte_str = byte_str |
| 33 | +
|
| 34 | + def encode(self, *args): |
| 35 | + return self.byte_str |
| 36 | +
|
| 37 | +def send(): |
| 38 | + sock = self.context.socket(zmq.PUB) |
| 39 | + sock.connect("tcp://%s:%d" % (target, port)) |
| 40 | +
|
| 41 | + aprs_frame = aprs.Frame() |
| 42 | + aprs_frame.source = aprs.Callsign(self.source_callsign) |
| 43 | + aprs_frame.destination = aprs.Callsign(self.destination_callsign) |
| 44 | +
|
| 45 | + payload = frame.build() |
| 46 | + aprs_frame.text = Wrap(convert_bytes_to_string(payload)) |
| 47 | + buff = array.array('B', self.aprs_frame.encode_kiss()) |
| 48 | + msg = convert_bytes_to_string(buff) |
| 49 | + sock.send(msg) |
| 50 | +
|
| 51 | +\end{verbatim} |
| 52 | + |
| 53 | +Example: requesting beacon frame using PW-Sat2 OBC repository code: |
| 54 | + |
| 55 | +\begin{verbatim} |
| 56 | +import telecommand |
| 57 | +send(telecommand.SendBeacon()) |
| 58 | +\end{verbatim} |
| 59 | + |
| 60 | +% connect to tcp://<host>:7000 |
| 61 | + |
| 62 | +% KISS-encoded APRS frame: |
| 63 | +% - aprs python library |
| 64 | +% - source and destination callsign set (destination is "PWSAT2-0") |
| 65 | +% - payload = Telecommand bytes |
| 66 | + |
| 67 | + |
| 68 | +% class UplinkFrame: |
| 69 | +% MAX_PAYLOAD_SIZE = 200 - 5 |
| 70 | + |
| 71 | +% def __init__(self, apid, content, security_code=None): |
| 72 | +% if security_code is None: |
| 73 | +% from build_config import config |
| 74 | +% security_code = config['COMM_SECURITY_CODE'] |
| 75 | +% self._bytes = ensure_byte_list(struct.pack('>L', security_code)) |
| 76 | +% self._bytes += [apid] |
| 77 | +% self._bytes += ensure_byte_list(content) |
| 78 | + |
| 79 | + |
| 80 | +% cały frame: |
| 81 | +% destination_callsign - 7 bytes |
| 82 | +% source_callsign - 7 bytes |
| 83 | +% (no digipeater addreses) |
| 84 | +% control field: 0x03 |
| 85 | +% protocol id: 0xf0 |
| 86 | + |
| 87 | +% payload starts here: |
| 88 | +% security code: 4 bytes |
| 89 | +% apid: 1 byte |
| 90 | +% content: 0-195 bytes |
0 commit comments