AO-40 is an Amateur satellite that was active between 2000 and 2004. It had several transponders and beacons covering many bands from HF to microwave and its position on a HEO orbit provided several consecutive hours of coverage each day and allowed long distance contacts. Since then, many interesting things have happened with Amateur satellites, particularly the high increase of the number of cubesats that is happening over the last few years, but even so, we haven’t seen again any other satellite with the characteristics of AO-40 nor it is to be expected in the near future.
I was quite young when AO-40 was operational, so for me this is all history. However, Pieter N4IP has posted recently on Twitter some IQ recordings of AO-40 that he made back in 2003. I have been playing with these recordings to see how AO-40 was like. One of the things I’ve dong is to write my own telemetry decoder using GNU Radio.
AO-40 transmitted telemetry using 400bps BPSK. There were two modes: an uncoded mode which used no forward error correction and an experimental FEC mode proposed by Phil Karn KA9Q. The FEC mode was used later in the FUNcube satellites, and I’ve already talked about it in a previous post. The beacon in Pieter’s recordings is in uncoded mode. Here I describe this mode in detail and how my decoder works. The decoder and a small sample taken from Pieter’s recordings have already been included in gr-satellites.
The specifications for the uncoded telemetry are in this document. The data is transmitted using Manchester-encoded differential BPSK. One has to be careful when understanding this. It is important to note at which point in the processing chain the differential encoding is done. In this case, the data bitstream is first differentially encoded, which means that a ‘0’ is represented as no change and a ‘1’ as a change from ‘0’ to ‘1’ or vice versa, and then the differentially-encoded bitstream is Manchester-encoded. This amounts to XORing the 400bps bitstream with a 400Hz clock.
There are several ways to process this encoding upon reception. What I have done is to use an 800baud non-coherent BPSK receiver which outputs one sample per symbol. Then I use a decimating filter with taps [1,-1] and decimation by 2. This takes care of XORing the 400Hz clock again and recovering the differentially-encoded bitstream. However, this will only work if the decimating filter is properly aligned with the 400Hz clock. As it might be one sample out of phase, processing is done both on the output from the BPSK receiver and on the output delayed one sample. After decimation, differential decoding is done on the BPSK symbols. Since this is a non-coherent receiver, carrier recovery (using a Costas loop or similar) is not done. The differential decoder takes care of any small mistuning. The relevant part of the GNU Radio flowgraph can be seen below.
Framing is done using a 32bit syncword and 514 byte frames. These can be extracted using the “Sync and create packed PDU” hierarchical block from gr-satellites. Each frame takes 10.36 seconds to transmit at 400bps. The last 2 bytes of each frame are a CRC16. The CRC variant used is what is called CRC16_CCITT_FALSE in this online CRC calculator. This CRC uses the same polynomial as the CRC16 used in AX.25, but there are some differences. CRC checking is done in a custom block that I have implemented in Python.
After checking the CRC, no further processing is done with the telemetry frames. However, they contain lots of ASCII data. For instance, this is the hex dump of the two frames that decode from the small wav sample I’ve extracted frome Pieter’s recordings. It contains an A block, which carried 128 analogue and 128 digital telemetry channels; and an L block, which was used for the mailbox or broadcast messages. You can scroll the textbox to the right to see the ASCII dump.
00000000 41 20 20 48 49 2c 20 54 48 49 53 20 49 53 20 41 |A HI, THIS IS A| 00000010 4d 53 41 54 20 4f 53 43 41 52 2d 34 30 20 20 20 |MSAT OSCAR-40 | 00000020 20 20 20 20 32 30 30 33 2d 30 33 2d 31 34 20 20 | 2003-03-14 | 00000030 32 33 3a 33 37 3a 35 35 20 20 23 30 38 44 37 20 |23:37:55 #08D7 | 00000040 2b 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d |+---------------| 00000050 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d |----------------| * 00000070 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2b |---------------+| 00000080 7c 20 20 55 70 64 61 74 65 73 20 69 6e 20 4d 2d || Updates in M-| 00000090 62 6c 6f 63 6b 2c 20 53 63 68 65 64 75 6c 65 20 |block, Schedule | 000000a0 69 6e 20 4e 2d 62 6c 6f 63 6b 2c 20 45 58 43 45 |in N-block, EXCE| 000000b0 50 54 20 46 4f 52 20 54 45 53 54 49 4e 47 20 7c |PT FOR TESTING || 000000c0 2b 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d |+---------------| 000000d0 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d |----------------| * 000000f0 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2b |---------------+| 00000100 7d 08 08 0b 15 08 87 0f 11 31 33 b1 09 b0 4e a4 |}........13...N.| 00000110 ab 61 ab 08 08 08 45 08 25 25 46 08 08 08 08 46 |.a....E.%%F....F| 00000120 44 af 08 32 4e 08 08 5d 2e fd a2 29 26 08 08 08 |D..2N..]...)&...| 00000130 08 08 08 08 08 08 08 08 6a 4d 08 08 2b 4a 72 85 |........jM..+Jr.| 00000140 7f 8f 86 8b 90 8d 95 a0 9d 98 fc f9 6b 7f 7f 7f |............k...| 00000150 7e 6b 98 8f fc 42 8f 8d 8e 87 88 87 8c 42 8e 91 |~k...B.......B..| 00000160 42 80 fc fc fc 84 86 8a 8e 91 8a fc 89 85 82 fc |B...............| 00000170 b3 b1 b1 b1 b0 b1 b1 b1 b2 22 22 5a 22 22 22 22 |.........""Z""""| 00000180 00 00 00 00 0a 00 80 00 00 08 40 01 02 13 08 08 |..........@.....| 00000190 ff de 03 de 20 ef b1 40 b6 40 0a a4 00 75 01 01 |.... ..@.@...u..| 000001a0 00 bb 00 7c 05 b6 40 04 00 37 25 17 f3 23 01 00 |...|..@..7%..#..| 000001b0 00 00 01 00 00 00 01 00 00 00 01 00 00 00 00 00 |................| 000001c0 fe 5f fe 5f fe 5f 51 00 01 40 20 00 00 74 00 00 |._._._Q..@ ..t..| 000001d0 d8 92 00 00 00 00 00 1b 00 c2 03 00 00 ef 1a 00 |................| 000001e0 d7 08 00 00 05 00 00 20 00 00 00 00 00 00 00 00 |....... ........| 000001f0 00 02 00 10 00 24 08 30 00 40 00 50 10 64 00 74 |.....$.0.@.P.d.t| 00000200 97 d4 4c 20 20 57 68 6f 6c 65 20 4f 72 62 69 74 |..L Whole Orbit| 00000210 20 44 61 74 61 20 56 32 2e 30 20 20 20 53 61 6d | Data V2.0 Sam| 00000220 70 6c 65 73 3a 20 32 20 20 20 20 43 61 70 74 75 |ples: 2 Captu| 00000230 72 65 64 20 43 68 61 6e 6e 65 6c 3a 20 23 30 31 |red Channel: #01| 00000240 30 39 1f 1f 1f 1f 1f 1e 1e 1e 1e 1f 1e 1e 1e 1f |09..............| 00000250 1e 1e 1e 1e 20 1f 1f 1f 1f 1f 1f 1e 1e 1e 1f 1e |.... ...........| 00000260 1e 1e 1f 1f 1e 30 31 31 31 1f 1f 1f 20 1f 1f 1f |.....0111... ...| 00000270 1f 1f 1e 1e 1e 1f 1f 1e 1e 1f 1f 1f 1f 1e 1e 1e |................| 00000280 1e 1e 1e 24 25 25 25 25 26 26 26 24 26 25 26 23 |...$%%%%&&&%&#|
00000290 26 25 25 1e 1f 1e 1f 1e 1e 1f 1e 1e 1f 1f 1f 1f |&%%.............|
000002a0 1f 1f 1f 1f 1e 1e 1e 1e 1f 1e 1e 1e 1e 1e 1f 1f |................|
000002b0 1f 1f 1f 1e 1e 1e 1e 1f 1e 1e 1f 1e 1f 1e 1f 1f |................|
000002c0 1f 1f 1f 1f 1f 1e 1f 1e 1e 1f 1e 1f 1e 1f 1e 1f |................|
000002d0 1f 1f 1e 1f 1e 1f 1e 1e 1e 1e 1f 1e 1e 1e 1e 1f |................|
000002e0 1f 1f 1f 1f 1f 31 20 20 20 20 20 20 20 20 20 20 |.....1 |
000002f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | |
*
000003c0 20 20 53 74 61 72 74 3d 20 32 33 3a 31 33 3a 35 | Start= 23:13:5|
000003d0 35 20 39 32 30 32 20 20 23 33 46 37 30 20 20 20 |5 9202 #3F70 |
000003e0 20 20 4c 61 73 74 3d 20 32 33 3a 33 33 3a 35 38 | Last= 23:33:58|
000003f0 20 39 32 30 33 20 20 23 34 30 42 36 20 20 20 20 | 9203 #40B6 |
00000400 20 20 c4 b0 | ..|
00000404
It is interesting to note the particular shape of AO-40’s beacon on the waterfall, which can be seen on the top of this post. It is the product of Manchester encoding and the fact that the data is unscrambled and there are many consecutive identical bytes inside each frame.
Hey Daniel can you send me the link for the entire decoding blocks of AO-40 fom source to gui frequency sink.
Hi Mark, what do you mean? All these blocks are now included in gr-satellites (potentially with some changes since the post was written in 2017).
I wanted to know how the satellite decoder block is working from inside i.e including all the filters.
In gr-satellite there is only a block I wanted to know in detail how the blocks are inside the decoder.
Like the connection of BPSK and filters etc.