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.
The JT4G transmissions are made just after the end of each GMSK telemetry packet, as illustrated by the following figure made by Cees Bassa using the signals he received at Dwingeloo. Also note that the JT4G signal starts at an UTC minute, as it is common with WSJT-X modes. The frequency of the lowest JT4G tone seems to be 1kHz higher than the GMSK carrier.
An interesting thing about the JT4G signal transmitted by DSLWP-B is that a tone separation of 312.5Hz is used instead of the standard 315Hz. This is due to hardware limitations. Wei Mingchuan BG2BHC warned me about this (note that there is a mistake in his tweet) and I was able to confirm this using IW1DTU’s high SNR recording. I have needed to adjust my detection algorithm to account for this difference.
A tone separation of 315Hz is used in standard JT4G because 315Hz is an integer multiple of the baudrate (4.375Hz). Therefore, when using an FFT size of one symbol, the tone separation will be an integer number of FFT bins, simplifying things. For a tone separation of 312.5Hz, there are several ways of adjusting things. An option is to use an FFT size such that 312.5Hz is an integer number of bins. This has the disadvantage that each transform no longer spans a single symbol, which can give other kinds of problems. It is also possible to use the same FFT size and round each of the tone frequencies to the nearest integer FFT bin. Finally, another option is to generate each of the tone frequencies using a complex exponential instead of a shift of the FFT. This has the advantage that the tone frequencies are generated exactly, but however the number of FFTs to compute increases by a factor of four.
After some experimentation I have decided to use the second option: use the same FFT size and round the tone separation to an integer number of FFT bins. Although the frequency shifts are only approximate, this gives a good result, as we will see below.
I have also added an SNR estimator. This is motivated by the fact that Wei and I have noted that the SNR estimator in WSJT-X 1.9.1 doesn’t work properly. I have tested it with signals generated using
jt49sim having different SNRs and the WSJT-X decoder always reports an SNR between -18dB and -16dB.
The algorithm I use to estimate SNR is the following. After the correlation peak in time and frequency has been found, the power spectra are summed to accumulate all four FSK tones into a single FFT bin (the bin size is still 4.375Hz). The noise power per bin is estimated by averaging several bins near the correlation frequency and taking into account that each bin contains the noise power corresponding to four bins. The signal plus noise power is computed by summing the power in the correlation frequency and its nearest four bins.
The Python script used to perform the detection is dslwp_jt4.py. It must be run as
dslwp_jt4.py input.wav output_path label
The input must be a WAV file whose sample rate is a multiple of 35Hz. Both IQ and real (single-channel) WAV files are supported. It is expected that a single JT4G transmission is contained in the file and that there are no strong interferers (any possible interference in neighbouring frequencies should be filtered out before running the detector). The
output_path is the path where the detector will store its output plots. The filename of each plot will be produced by appending some string, such as
_time.png to the
output_path, so set this accordingly. The
label is only used as a title in the plots.
An easy way to produce valid input files for the detector is to use WSJT-X recording capabilities (the “Save > Save all” menu option) and then convert them from 12000Hz to 11025Hz using sox as
sox input.wav output.wav rate 11025
The results of running the detector on the recordings linked above are as follows. The recording by Fer IW1DTU has a rather high SNR of -12dB.
The antenna used by IW1DTU is an array of 4 yagis of 23 elements, with a theoretical gain of 23dBi.
The signal received by BG6LQV is weak, at -20dB.
He is using a 10-turn helix antenna. Its gain should be around 11dBic.
The two recordings shared by Tetsu JA0CAW have an SNR of -18dB. I don’t know what antenna he is using.
Note that in the frequency plots above the correlation energy is concentrated almost in a single frequency bin. This means that rounding the frequency shifts to an integer number of bins works well.
The important question now is what is the smallest antenna that could be used to detect DSLWP-B’s JT4G signals. In particular, I want to try luck with my 7 element Arrow yagi. This should have a gain of about 12dBi, so looking at BG6LQV’s results it looks quite feasible.
I’m interested in reports from other stations, particularly from the smaller ones. If you have a small 70cm yagi, try to listen during the next JT4G test, run WSJT-X and record all data as WAV. Then share your data and/or run my detector script.