Output Options
This page explains what gr_satellites does with decoded frames by default and how to change it: hex dumps, telemetry output files, KISS files with timestamps, the KISS TCP server, the ZeroMQ PUB socket, and dumping the demodulators' internal signals for debugging. All output options can be combined in one run.
Default Output
Without output options, gr_satellites "does its best" for each satellite, based on the data section of its SatYAML file:
| Data entry type | Default action |
|---|---|
telemetry: <definition> |
Parse each frame and print the fields to standard output. |
unknown |
Print each frame in hex. |
files: <receiver> |
Reassemble files into the current directory. |
image: <receiver> |
Reassemble images into the current directory and display them with feh. |
decoder: <datasink> |
Run that custom data sink (for example Codec2 voice over UDP for LilacSat-1). |
If telemetry submission is enabled in the configuration, frames are also submitted.
Option Reference
| Option | Default | Effect |
|---|---|---|
--hexdump |
off | Print every frame in hex and disable telemetry parsing. |
--telemetry_output FILE |
standard output | Write parsed telemetry to a file (only for satellites with a telemetry parser). |
--kiss_out FILE |
none | Write all frames to a KISS file (overwritten). |
--kiss_append |
off | Append to the --kiss_out file instead of overwriting it. |
--kiss_server [PORT] |
off; port 8100 if given without a value |
Serve frames to TCP clients in KISS format. |
--kiss_server_address ADDR |
127.0.0.1 |
Address the KISS server binds to. |
--zmq_pub [ADDRESS] |
off; tcp://127.0.0.1:5555 if given without a value |
Publish frames on a ZeroMQ PUB socket. |
--dump_path DIR |
none | Write the demodulators' internal signals to files in DIR. |
The file and image receiver options (--file_output_path, --verbose_file_receiver) are described in Files and Images.
Hex Dump
gr_satellites FUNcube-1 --wavfile ao73.wav --hexdump
--hexdump prints every frame produced by every deframer, using GNU Radio's Message Debug block (print port). The output shows the PDU metadata, the length and a hex dump with offsets. The metadata contains the name of the transmitter that produced the frame (gr-satellites adds a transmitter key to every frame). The exact layout of the header lines depends on the GNU Radio version; the body of a frame looks similar to this:
pdu_length = 256
contents =
0000: 89 00 00 00 00 00 00 00 00 1f cc 00 ce 02 d1 00
0010: 00 07 08 09 09 00 00 05 01 01 00 40 13 2f c8 f2
...
What --hexdump changes:
- Telemetry parsers and
unknowndata entries are not created, so nothing is parsed. - Transports are still built but their output is not connected to any data sink.
- File receivers, image receivers and
decoderdata sinks that are fed directly by a transmitter keep working. Those fed through a transport do not (LilacSat-1 images, for example, stop being reassembled). - KISS output, the KISS server, ZMQ and telemetry submission are unaffected.
Note that the hex dump shows deframer output, before any transport. For a satellite that sends a KISS stream inside fixed-size frames, you see the frames with their c0 padding, not the packets inside.
Telemetry Output File
gr_satellites FUNcube-1 --udp --samp_rate 48e3 --telemetry_output funcube.txt
The file is opened in append mode, so successive runs add to it. Each parsed frame is preceded by a line naming the transmitter:
-> Packet from 1k2 BPSK downlink
If a frame cannot be parsed, the parser writes Could not parse telemetry beacon followed by the construct error to the same output, and continues. The option only exists for satellites with a telemetry data entry.
KISS File Output
gr_satellites AU03 --wavfile au03.wav --kiss_out au03.kss
gr_satellites AU03 --wavfile au03_pass2.wav --kiss_out au03.kss --kiss_append
KISS is a simple framing format: each frame is enclosed between FEND bytes (0xC0), and 0xC0/0xDB inside the data are escaped as 0xDB 0xDC/0xDB 0xDD. Files written by gr-satellites contain, for each decoded frame:
- A timestamp frame:
C0 09followed by the reception time as a big-endian unsigned 64-bit integer of milliseconds since the UNIX epoch (UTC), thenC0. This is an extension proposed by Mike Rupprecht (DK3WN), whose decoders can read it. - A data frame:
C0 00(data command on port 0), the escaped frame bytes,C0.
KISS readers that only handle data frames (command 0) skip the 0x09 frames, so files stay usable by software that does not know the extension. gr-satellites itself skips them when reading with --kiss_in.
KISS files store deframer output: every frame from every transmitter, before transports. The timestamps follow the rules in --throttle and --start_time.
KISS Server
gr_satellites AU03 --udp --samp_rate 48e3 --kiss_server
gr_satellites AU03 --udp --samp_rate 48e3 --kiss_server 8200 --kiss_server_address 0.0.0.0
Starts a TCP server (GNU Radio Socket PDU block in TCP_SERVER mode) and sends each frame to every connected client in KISS format. Other programs, such as telemetry viewers, connect as clients. By default the server binds to 127.0.0.1, so only local programs can connect. Use --kiss_server_address 0.0.0.0 or --kiss_server_address '' to accept connections from the network.
The server sends the same timestamp frames as the KISS file output, before each data frame.
ZeroMQ PUB Socket
gr_satellites AU03 --udp --samp_rate 48e3 --zmq_pub
gr_satellites AU03 --udp --samp_rate 48e3 --zmq_pub 'tcp://*:5555'
Publishes each frame with GNU Radio's ZMQ PUB Message Sink. Several programs can subscribe at once. The messages are serialized GNU Radio PDUs (metadata plus payload), so the easiest receiver is a GNU Radio flowgraph with the ZMQ SUB Message Source block. The default endpoint tcp://127.0.0.1:5555 accepts local subscribers only; tcp://*:5555 listens on all interfaces. No timestamp frames are added on this output.
Dumping Internal Signals
mkdir -p /tmp/fsk
gr_satellites AU02 --wavfile au02.wav --dump_path /tmp/fsk
For developers and for tuning difficult recordings, the demodulators can write their internal signals to files in the given directory. The directory must already exist. Use a short recording: the files grow at the sample or symbol rate.
| Demodulator | Files |
|---|---|
| FSK (and AFSK, through its internal FSK demodulator) | waveform.f32 (input to clock recovery), clock_recovery_out.f32 (symbols), clock_recovery_err.f32, clock_recovery_T_inst.f32, clock_recovery_T_avg.f32 |
| BPSK | agc_in.c64, agc_out.c64, clock_recovery_out.c64, clock_recovery_err.f32, clock_recovery_T_inst.f32, clock_recovery_T_avg.f32; plus fll_freq.f32, fll_phase.f32, fll_error.f32 unless --disable_fll; plus costas_out.c64, costas_frequency.f32, costas_phase.f32, costas_error.f32 for coherent (non-differential) BPSK |
.f32 files are raw float32; .c64 files are raw complex64. Read them with NumPy:
import numpy as np
import matplotlib.pyplot as plt
x = np.fromfile('/tmp/fsk/clock_recovery_out.f32', dtype='float32')
plt.plot(x, '.')
plt.show()
Well-recovered FSK symbols form two clean horizontal bands around +1 and −1. A cycle slip in clock recovery shows up as a jump in the pattern partway through a packet. The upstream documentation shows exactly that case for AU02, fixed by adding --clk_bw 0.1.
The repository also contains tools/waveform_plot.py, which plots a float32 file next to its histogram (add --lines for faster rendering of large files):
python3 tools/waveform_plot.py /tmp/fsk/clock_recovery_out.f32
Warning: All demodulators write to the same file names. For a satellite with several transmitters, every demodulator writes into the same directory with the same names, and the files clash. Use a SatYAML copy with a single transmitter when dumping (see Recipes).