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.

I think this tutorial
answers your question regarding why the constellation looks so messy after the modulator

What we are seeing in this image is actually the ISI that we mentioned before. We get rid of ISI by using another filter at the receiver. Basically, what we’ve done is purposefully used a filter on the transmitter, the RRC filter, that creates the ISI. But when we convolve two RRC filters together, we get a raised cosine filter, which is a form of a Nyquist filter. So, knowing this property of the RRC filter, we can use another RRC filter at the receiver. Filtering is just a convolution here, so the output of the receive-side RRC filter is a raised cosine pulse shaped signal with minimized ISI. The other benefit is that absent effects of the channel, what we are also doing is using a matched filter at the receiver.

Which basically says that the “wrong” points on the constellation are actually INTENTIONAL Inter-Symbol-Interference (ISI) introduced by the modulator itself. That ISI is later filtered back on the receiver side using a matched filter. So this intentional ISI is actually better for the proper retrieval of the signal at the receiver side.

Hope this helps

old topic, but in case someone reads it:
the constellation modulator expectes Bytes at the input. It converts bytes to bits/symbols internally.
So, in your first picture, the “Repack” should be deleted because the file source already delivers bytes which are expected by the modulator.