DSLWP-B corrupted SSDV frames

In my previous post I looked at the first SSDV transmission made by DSLWP-B from lunar orbit. There I used the recording made at the Dwingeloo radiotelescope and showed how to decode the SSDV frames and produce a JPEG image.

Only four SSDV frames where transmitted by DSLWP-B, and out of those four, only two could be decoded correctly. I wondered why the decoding of the other two frames failed, since the SNR of the signal as recorded at Dwingeloo was very good, yielding essentially no bit errors (even before FEC decoding).

Now I have looked at the signal more in detail and have found the cause of the corrupted SSDV frames. I have demodulated the signal in Python and have looked at the position where an ASM (attached sync marker) is transmitted. As explained in this post, the ASM marks the beginning of each Turbo codeword. The Turbo codewords are 3576 symbols long and contain a single SSDV frame.

A total of four ASMs are found in the GMSK transmission that contains the SSDV frames, which matches the four SSDV transmitted. However, the distance between some of the ASMs doesn’t agree with the expected length of the Turbo codeword. Two of the Turbo codewords where cut short and not transmitted completely. This explains why the decoding of the corresponding SSDV frames fails.

The detailed analysis can be seen in this Jupyter notebook.

This is rather interesting, as it seems that DSLWP-B had some problem when transmitting the SSDV frames. I have no idea about the cause of the problem, however. It would be convenient to monitor carefully future SSDV transmissions to see if any similar problem happens again.

First SSDV transmission from DSLWP-B

As some of you may know, DSLWP-B, the Chinese lunar-orbiting Amateur satellite carries a camera which is able to take pictures of the Moon and stars. The pictures can be downlinked through the 70cm 250bps GMSK telemetry channel using the SSDV protocol. Since an r=1/2 turbo code is used, this gives a net rate of 125bps, without taking into account overhead due to headers. Thus, even small 640×480 images can take many minutes to transfer, but that is the price one must pay for sending pictures over a distance of 400000km.

On Saturday August 3, at 01:27 UTC, the first SSDV downlink in the history of DSLWP-B was attempted. According to Wei Mingchuan BG2BHC, the groundstation at Harbin managed to command the picture download at 436.400MHz a few minutes before the GMSK transmitter went off at 01:30 UTC. A few SSDV frames were received by the PI9CAM radiotelescope at Dwingeloo.

The partial image that was received was quickly shared on Twitter and on the DSLWP-B camera webpage. The PI9CAM team has now published the IQ recording of this event in their recording repository. Here I analyze that recording and perform my own decoding of the image.

Trying to decode EQUiSat

EQUiSat is a cubesat from Brown University that was launched to the ISS on May 21 with the Cygnus CRS-9 supply ship. It was released from the ISS on July 13. The payload of EQUiSat is rather interesting: an optical beacon, formed by an array of 4 high power LEDs designed to flash and be visible with the naked eye.

The EQUiSat radio system is also quite interesting and unusual. It uses the PacificCrest XDL Micro transmitter in 4FSK mode. This UHF transmitter is normally used to transmit data between survey GNSS receivers. Unfortunately, there is very little documentation about the radio protocol used by this transmitter.

I am in communication with the satellite team, since they are interested in producing a GNU Radio decoder. However, they don’t know much about the radio protocol either. Here is my first try at trying to decode transmissions from EQUiSat.

DSLWP-B GMSK detector

Following the success of my JT4G detector, which I used to detect very weak signals from DSWLP-B and was also tested by other people, I have made a similar detector for the 250baud GMSK telemetry transmissions.

The coding used by the DSLWP-B GMSK telemetry follows the CCSDS standards for turbo-encoded GMSK/OQPSK. The relevant documentation can be found in the TM Synchronization and Channel Coding and Radio Frequency and Modulation Systems–Part 1: Earth Stations and Spacecraft blue books.

The CCSDS standards specify that a 64bit ASM shall be attached to each \(r=1/2\) turbo codeword. The idea of this algorithm is to correlate against the ASM (adequately precoded and modulated in GMSK). The ASM spans 256ms and the correlation is done as a single coherent integration. As a rule of thumb, this should achieve a reliable detection of signals down to around 12dB C/N0, which is equivalent to -12dB Eb/N0 or -22dB SNR in 2500Hz. Note that the decoding threshold for the \(r=1/2\) turbo code is around 1.5dB Eb/N0, so it is much easier to detect the GMSK beacon using this algorithm than to decode it. The difficulty of GMSK detection is comparable to the difficulty of JT4G decoding, which has a decoding threshold of around -23dB SNR in 2500Hz.

Here I explain the details of this GMSK ASM detector. The Python script for the detector is dslwp_gmsk.py.

DSLWP-B first JT4G test

Yesterday, between 9:00 and 11:00, DSLWP-B made its first JT4G 70cm transmissions from lunar orbit. Several stations such as Cees Bassa and the rest of the PI9CAM team at Dwingeloo, the Netherlands, Fer IW1DTU in Italy, Tetsu JA0CAW and Yasuo JA5BLZ in Japan, Mike DK3WN in Germany, Jiang Lei BG6LQV in China, Dave G4RGK in the UK, and others exchanged reception reports on Twitter. Some of them have also shared their recordings of the signals.

Last week I presented a JT4G detection algorithm intended to detect very weak signals from DSLWP-B, down to -25dB SNR in 2500Hz. I have now processed the recordings of yesterday’s transmissions with this algorithm and here I look at the results. I have also made a Python script with the algorithm so that people can process their recordings easily. Instructions are included in this post.

JT4G detection algorithm for DSLWP-B

Now that DSLWP-B has already been for 17 days in lunar orbit, there have been several tests of the 70cm Amateur Radio payload, using 250bps GMSK with an r=1/2 turbo code. Several stations have received and decoded these transmissions successfully, ranging from the 25m radiotelescope at PI9CAM in Dwingeloo, the Netherlands (see recordings here) and the old 12m Inmarsat C-band dish in Shahe, Beijing, to much more modest stations such as DK3WN‘s, with a 15.4dBic 20-element crossed yagi in RHCP. The notices for future tests are published in Wei Mingchuan BG2BHC’s twitter account.

As far as I know, there have been no tests using JT4G yet. According to the documentation of WSJT-X 1.9.0, JT4G can be decoded down to -17dB SNR measured in 2.5kHz bandwidth. However, if we don’t insist on decoding the data, but only detecting the signal, much weaker signals can be detected. The algorithm presented here achieves reliable detections down to about -25dB SNR, or 9dB C/N0.

This possibility is very interesting, because it enables very modest stations to detect signals from DSLWP-B. In comparison, the r=1/2 turbo code can achieve decodes down to 1dB Eb/N0, or 25dB C/N0. In theory, this makes detection of JT4G signals 16dB easier than decoding the GMSK telemetry. Thus, very small stations should be able to detect JT4G signals from DSLWP-B.

P25 vocoder FEC

Following a discussion with Carlos Cabezas EB4FBZ over on the Spanish telegram group Radiofrikis about using Codec2 with DMR, I set out to study the error correction used in DMR, since it quickly caught my eye as something rather interesting. As some may know, I’m not a fan of using DMR for Amateur Radio, so I don’t know much about its technical details. On the other hand, Carlos knows a lot about DMR, so I’ve learned much with this discussion.

In principle, DMR is codec agnostic, but all the existing implementations use a 2450bps AMBE codec. The details of the encoding and FEC are taken directly from the P25 Half Rate Vocoder specification, which encodes a 2450bps MBE stream as a 3600bps stream. Here I look at some interesting details regarding the FEC in this specification.

WSJT-X and linear satellites: part II

This is a follow-up to the part I post about using WSJT-X modes through a linear transponder on a LEO satellite. In part I, we considered the tolerance of several WSJT-X modes to the residual Doppler produced by a temporal offset in the Doppler computation used for computer Doppler correction. There, we introduced a parameter \(\delta\) which represents the time shift between the real Doppler curve and the computed Doppler curve. The main idea was that a decoder could try to correct the residual Doppler by trying several values of \(\delta\) until a decode is produced.

Here we examine the effect of TLE age on the accuracy of the Doppler computation. The problem is that, when a satellite pass occurs, TLEs have been calculated at an epoch in the past, so there is an error between the actual Doppler curve and the Doppler curve predicted by the TLEs. We show that the actual Doppler curve is very well approximated by applying a time shift to the Doppler curve predicted by the TLEs, justifying the study in part I.

Acquisition and wipeoff for JT9A

Lately, I have been playing around with the concept of doing acquisition and wipeoff of JT9A signals, using a locally generated replica when the transmitted message is known. These are concepts and terminologies that come from GNSS signal processing, but they can applied to many other cases.

In GNSS, most of the systems transmit a known spreading sequence using BPSK. When the signal arrives to the receiver, the frequency offset (given by Doppler and clock error) and delay are unknown. The receiver runs a search correlating against a locally generated replica signal which uses the same spreading sequence. The correlation will peak for the correct values of frequency offset and delay. The receiver then mixes the incoming signal with the replica to remove the DSSS modulation, so that only the data bits that carry the navigation message remain. This process can be understood as a matched filter that removes a lot of noise bandwidth. The procedure is called code wipeoff.

The same ideas can be applied to almost any kind of signal. A JT9A signal is a 9-FSK signal, so when trying to do an FFT to visually detect the signal in a spectrum display, the energy of the signal spreads over several bins and we lose SNR. We can generate a replica JT9A signal carrying the same message and at the same temporal delay than the signal we want to detect. Then we mix the signal with the complex conjugate of the replica. The result is a CW tone at the difference of frequencies of both signals, which we call wiped signal. This is much easier to detect in an FFT, because all the energy is concentrated in a single bin. Here I look at the procedure in detail and show an application with real world signals. Recordings and a Python script are included.

WSJT-X and linear satellites: part I

Several weeks ago, in an AMSAT EA informal meeting, Eduardo EA3GHS wondered about the possibility of using WSJT-X modes through linear transponder satellites in low Earth orbit. Of course, computer Doppler correction is a must, but even under the best circumstances we cannot assume a perfect Doppler correction. First, there are errors in the Doppler computation because the TLEs used are always measured at an earlier time and do not reflect exactly the current state of the satellite. This was the aspect that Eduardo was studying. Second, there are also errors because the computer clock is not perfect. Even a 10ms error in the computer clock can produce a noticeable error in the Doppler computation. Also, usually there is a delay between the time that the RF signal reaches the antenna and the time that the Doppler correction is computed for and applied to the signal, especially if using SDR hardware, which can have large buffers for the signal. This delay can be measured and compensated in the Doppler calculation, but this is usually not done.

Here we look at errors of the second kind. We denote by \(D(t)\) the function describing the Doppler frequency, where \(t\) is the time when the signal arrives at the antenna. We assume that the correction is not done using \(D(t)\), but rather \(D(t – \delta)\), where \(\delta\) is a small constant. Thus, a residual Doppler \(D(t)-D(t-\delta)\) is still present in the received signal. We will study this residual Doppler and how tolerant to it are several WSJT-X modes, depending on the value of \(\delta\).

The dependence of Doppler on the age of the TLEs will be studied in a later post, but it is worthy to note that the largest error made by using old TLEs is in the along-track position of the satellite, and that this effect is well modelled by offsetting the Doppler curve in time. This justifies the study of the residual Doppler \(D(t)-D(t-\delta)\).