GNURadio Constellation Modulator



not sure if this is the right place to ask it, but except for the empty gnuradio forum at ruby I found no site.

I just can’t understand the Constellation Modulator Object.
Consider the following project:

It’s very simple: Repack bits from a source in 2 bit pairs because we want to use QAM, see the constellation Rect. Object. The sample rate after the repack block is 1e6. We can directly repack them in a 2:8 ratio again and we get the same data.

Now, the constellation Modulator should take these 2 bit parts and Map them to the 4 symbols defined by the constellation Rect. Object., right? Except, it doesn’t, instead it’s sampled wrong (see the points between the symbol maps), because I can’t set sps to 1 and the sample rate afterwords is WAY to high, like >10e6.

Why is this? Am I missing something?
Also, I went after this tutorial, which I can’t test because I never finished the demodulator. But it does the same thing, how is this project not wrong? Why is it seamingly working there?

Please help, I’m so frustrated by now.


Do you need a throttle after your sample source?


Yes, a throttle after the Constellation Modulator object would fix the sampling rate to whatever I wish. However, the signal would still be over sampled in the constellation.

I don’t understand why the constellation looks that way. Is there another block that just maps the incoming bytes to the complex space? Or is this not practical and I should use the constellation modulator?


Ok, so I dissected the Constellation Modulator Block in Python and realized that it consists of the 5 blocks below it. Both paths result in the same Constellation, so I got that.

The constellation after the Polyphase Arbitrary Resampler still looks awful though, f.e. if I use random values:

I still don’t understand the Resampler, I understand the RRC Filter but not why it should have a resample value of 4. Does anyone have a suggestion of literature on that? Or should I just look into the code?
What’s also interesting, if I use a finite number of samples, like in the example below, i actually loose 4 bytes in the process, besides the data of course being wrong.
Screenshot from 2018-10-12 15-20-51
I will also work on this over the weekend. Any hint is welcome though!

EDIT: Of course, the ultimate goal is to send & receive the data with my LimeSDR as soon as it works without a device & channel.
EDIT2: If anyone is interested, here is the GRC & python file:


Well don’t ask me why but setting the initial phase of the Polyphase Clock Sync to 20 (nfilts/1.6) I noticed a pattern that is correct once I bitshift the result file with a custom block:
Screenshot from 2018-10-15 14-38-08
Also turns out that the Clock Sync is the one loosing bytes.