Doppler correction tool for SDR

Doppler is the last tool that is missing for receiving data from satellites using software defined radio (SDR) in a UNIX fashion:

Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface.

– Doug McIlroy

As I mentioned in my earlier post there exists many GUI based SDR tools for doing doppler correction and demodulation. However there aren’t tools available for doing this:

rtl_sdr | doppler | demod | multimon-ng

Some readers might already know that rtl_sdr is used for getting IQ data out of simple SDR dongles and multimon-ng is a tool that decodes actual packets from demodulated audio. Demod is a new tool that I wrote for demodulating IQ stream. Currently it supports only FM modulation, however it is quite easy to add more demodulators that are supported by liquid-dsp library.
Doppler was the last missing piece from the pipeline.

 Doppler

Doppler uses the same library for calculating satellite position and other parameters as Gpredict. Bill Shupp has extracted core functions from Gpredict source and released them as standalone library called libgpredict. This is the library that does heavy lifting for calculating doppler shift.
Baseband signal is shifted by doppler frequency in the following way:

float complex c_sample;
float complex c_corrector;
int n = 0;

for (k=0; k<len; k+=2) {
    // convert int16_t IQ to complex float
    c_sample = iqbuffer[k] / 32768.0 + 
               iqbuffer[k+1] / 32768.0 * I;

    c_corrector = cexpf(0.0 -2*M_PI*doppler_hz/samplerate*n*I);
    c_sample = c_sample * c_corrector;

    // convert float back to int16_t IQ
    iqbuffer[k] = crealf(c_sample) * 32767.0; // I part
    iqbuffer[k+1] = cimagf(c_sample) * 32767.0; // Q part
    n++;
}

Thats it - basically this is the only thing what it does. Computes doppler shift and centers baseband signal according to this value.

 Examples

 Working in realtime

Suppose you have RTL-SDR dongle and you would like to decode AX.25 packets from cube satellite ESTCube-1 that transmits last days on 437.505 MHz. Lets set rtl_sdr center frequency off by 5 kHz to mitigate DC offset that is occurring with some of the dongles. That is why here rtl_sdr uses 437.500 MHz as center frequency and doppler uses -o 5000 (offset) parameter. Here multimon-ng fork that supports 48 kHz input is used because it decodes more reliably than original 22.050 kHz. TLE file cubesat.txt can be downloaded from here.

rtl_sdr -f 437500000 -s 1024000 -g 20 - | doppler -s 1024000 -i i16 -d -t cubesat.txt -n 'ESTCUBE 1' --location lat=58.26541,lon=26.46667,alt=76.1 -f 437505000 -o 5000 | demod -s 1024000 -r 48000 -b 4500 -m fm d=3500 | multimon-ng -t raw -a FSK9600 /dev/stdin

 Working with recordings

Suppose we have recorded a satellite overpass to a file and now we want to decode packets from that file. Here --log doppler.log is used to write doppler information to the file instead of stderr. Also offset parameter -o 5000 is used because recording was taken with center frequency of 437.500 MHz. If dealing with old recordings use TLE parameters from the same time, otherwise doppler correction might be wrong.

cat ec1_256000_i16_2015-02-19T20-53-56Z.iq | doppler -s 256000 -i i16 -d -t cubesat.txt -n 'ESTCUBE 1' --location lat=58.26541,lon=26.46667,alt=76.1 -f 437505000 -o 5000 --time 2015-02-19T20:53:56 --log doppler.log | demod -s 256000 -r 48000 -b 4500 -m fm d=3500 | multimon-ng -t raw -a FSK9600 /dev/stdin

 Disclaimer

I have not yet used it in real environment, so there might be some quirks. Doppler correction was also little bit off when I tried it with old recordings. It was especially off in the end of a the overpass. I am planning to add automatic frequency correction (AFC) support to this tool to correct those mismatches. It should improve packet decoding quite a lot because it is very important to feed demodulator with zero offset baseband signal.

 
41
Kudos
 
41
Kudos

Now read this

Examples of creating Rust bindings

Couple of months ago I developed two SDR tools called doppler and demod. These tools were using unix pipe to transfer IQ data stream from one process to another and they were written in C that time. I have read a lot of blog posts about... Continue →