Looking at BY70-1 image downlink

BY70-1 is a Chinese Amateur satellite that will launch on Monday 26 December. It has a V/U FM repeater, a camera and a 9k6 BPSK downlink on 70cm that transmits telemetry and the JPEG images taken by the camera. The BPSK downlink uses the same modulation and coding as LilacSat-2, of which I have spoken several times. Recently, Wei MingChuan BG2BHC has added support for the image downlink of BY70-1 to gr-lilacsat and a bit stream recording to test the image receiver.

Unfortunately, the image decoder is closed-source, as it contains some certification methods used to avoid fake packets over the internet. However, Wei gave me a brief description of how the image downlink protocol works. After seeing the closed-source decoder running, I had enough to figure out how the protocol works. I have implemented an open-source image decoder as a python GNU Radio block. It is in my gr-lilacsat fork, and it will soon be included in the upstream gr-lilacsat repository. Here I look at the protocol used for the image downlink.

The images are JPEG files and they are transmitted in chunks. The chunks are 64 bytes long in the recording I’ve used. It is worthy to note that LilacSat-1 will also have an onboard camera using the same protocol. According to what I’ve read, LilacSat-1’s camera is thermal infrared, which is even more interesting than the visible light camera on BY70-1.

These are the first two packets corresponding to a JPEG file:

0000: b8 64 2e 00 06 00 00 00 00 96 79 00 00 00 00 ff 
0010: d8 ff e0 00 10 4a 46 49 46 00 01 01 01 00 00 00 
0020: 00 00 00 ff db 00 43 00 08 06 06 07 06 05 08 07 
0030: 07 07 09 09 08 0a 0c 14 0d 0c 0b 0b 0c 19 12 13 
0040: 0f 14 1d 1a 1f 1e 1d 1a 1c 1c 20 24 2e 27 20 5b
0050: 06 00 00 2d cf 94 4d

0000: b8 64 2f 00 06 00 00 00 00 96 79 00 40 00 00 22 
0010: 2c 23 1c 1c 28 37 29 2c 30 31 34 34 34 1f 27 39 
0020: 3d 38 32 3c 2e 33 34 32 ff db 00 43 01 09 09 09 
0030: 0c 0b 0c 18 0d 0d 18 32 21 1c 21 32 32 32 32 32 
0040: 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 5c 
0050: 06 00 00 96 e6 b4 f1 

Each packet contains the following (the first byte is counted as byte 0):

  • Bytes 0 through 3: the CSP header of the packet. A destination field of 6 is used for JPEG image chunks, while the telemetry is sent with a destination of 5.
  • Bytes 4 through 8: the id of the JPEG image as a little endian unsigned 32bit integer (6 in this case)
  • Bytes 9 through 11: the length of the JPEG file in bytes as a little endian unsigned 24bit integer (31126 bytes in this case)
  • Bytes 12 through 14: the offset in bytes of this chunk within the JPEG file as a little endian unsigned 24bit integer. The offsets for the first and second chunk are 0 and 64, as one would expect for 64 byte chunks.
  • Bytes 15 through 78: the 64 byte chunk of the JPEG file

Thanks to Wei for correcting some small errors in my first “reverse-engineered” specifications.

After running examples/replay_by70_1_opensource_decoder.grc in my gr-lilacsat fork with the bitstream recording, I got the following 800×600 JPEG image.

Test image taken and sent by BY70-1

The GNU Radio image decoder block can even use feh to display the image in real-time as it is being received. Below you can see the decoder working halfway through the bitstream recording.

GNU radio image receiver working in real-time

The natural question is how much time does an image like this take to transmit. In the bitstream recording, the image is transmitted in 3 minutes and 13 seconds. This is great. It allows several images to be downloaded during a pass, and it compares very well with the SSTV transmissions from the ISS. These often use PD180, which takes 3 minutes to transmit an analog image.

9 comments

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.