OQPSK for Meteor MN2-2 LRPT

It appears Meteor MN2-2 uses OQPSK demodulation, where as the older Meteor MN2 uses QPSK demodulation. The current 3rd party LRPT demodulation scripts for gr-satnogs only support QPSK demodulation.

I’m trying to adapt the 3rd party LRPT demodulator that we use with gr-satnogs to enable OQPSK demodulation.

The difference between OQPSK and QPSK is that the former uses exclusively 90 degree phase changes, but at twice the symbol rate. So far I’ve managed to get a clean constellation diagram by increasing the symbol rate by a factor of 2 to deal with the half symbol phase changes. Unfortunately using only half of the decoded bits does not seem to work for OQPSK input.

Any suggestions for how to fix this?

I’ve extracted 10s of data from a Meteor MN2 and Meteor MN2-2 pass from station #39 and uploaded them to:

The gnuradio flowgraph is at https://www.dropbox.com/s/i5ebj0lkhegqv0w/offline_lrpt_mn22.grc?dl=0 (Note that this has a 144ksps symbol rate and uses the ‘Keep 1 in 2’ block before the constellation decoder).


Hi there!

So, i have also previously tried to write a decoder for OQPSK but eventually came across some issues. The way i see it, in an abstract way, OQPSK modulates the input bits in a way that there is only one “new” bit of information at each constellation point : if you start counting the transmitter’s constellation points, the even points modulate the even input bits on the I component - and keep the Q component the same as the previous- and odd points modulate the odd bits - again by keeping the I component the same- achieving at most 90 degree shifts. This way the symbol rate is indeed two times that of a QPSK signal. The “Keep 1 in 2” block that you use though, discards one of the two constellation points that hold either the even or the odd bits, so that’s why i think that it doesn’t work


Thanks for the pointers. So you suggest to run the flowchart at twice the symbol rate and deal with it in the bitstream?

Yes, i would deal with it in the bitstream since i don’t see any other way that this can be done with existing gnuradio blocks. As for the symbol rate, i would go with the one reported for the Meteor. If a symbol rate of 72k is reported by the operators then i would assume that it refers to OQPSK symbols, so i’d run the flowgraph at 72k. If that didn’t work i’d try doubling the rate at a second iteration

1 Like

I’m wondering if adding a delay of half a symbol to the in-phase component will turn the OQPSK IQ stream into a QPSK one…

1 Like

That could do the trick. But maybe a delay of one symbol period is needed in the in-phase component, provided that you run the flowgraph at the reported symbol rate. And then you throw away one-in-two symbols and you have the corresponding qpsk symbol.

One of the tricks here is going to be figuring out what flow-graph to run for METEOR M2 and M2-2, since they are both listed as LRPT.

I note that the TLE for the observation is available in the spawn_observer function (where we add in the line for LRPT), so I guess we can select the appropriate flow-graph based on the satellite ID.

I’ve managed to get this going with various sample recordings. The flow-graph needs a bit more work to clean up the constellation, but it’s a start. Here’s the GRC file


Thanks for that!

It seems the medet decoder also needs work to support Meteor MN2-2.

1 Like

Here’s a partial image I just decoded from @vk5qi’s recording.


And now it has switched to 80ksps mode! You can see the signal is wider in this observation: https://network.satnogs.org/observations/858187/
IQ for this recording is here: http://satnogs-iq.s3-ap-southeast-2.amazonaws.com/858187.raw

Is it just the sample rate that’s changed? Or more?

1 Like

From what I’ve seen this is also OQPSK modulated, so while we may be able to demodulate it, it still is not supported by medet.

It looks like the medet Meteor decoder has been updated for Meteor MN2-2: https://github.com/artlav/meteor_decoder

I’ve not been able to test it yet.

1 Like

Still needs a oqpsk demodulator in front of it but otherwise it works: https://network.satnogs.org/observations/956906/

I save the IQ data and demod it after the observation with https://github.com/dbdexter-dev/meteor_demod, which still needs some tweaking of the parameters to get a consistent lock.

1 Like