An OQPSK detector is being tested in GNU Radio. The architecture was obtained from Michael Rice's Digital Communications - A discrete-time approach. The flowgraph is shown below. The modulator architecture is basically QPSK delayed by half the sample rate, as shown below. In the flowgraph, the block oqpskIQMap maps the I/Q symbols from QPSK to OQPSK. It does so by delaying the Q-channel by d_delay, which is equal to the number of samples per symbol divided by two.
oqpskIQMap_impl::oqpskIQMap_impl(int sps)
: gr::sync_block("oqpskIQMap",
gr::io_signature::make(1, 1, sizeof(gr_complex)),
gr::io_signature::make(1, 1, sizeof(gr_complex))),
d_delay(sps/2)
{
//set_history(d_delay);
}
/*
* Our virtual destructor.
*/
oqpskIQMap_impl::~oqpskIQMap_impl()
{
}
int
oqpskIQMap_impl::work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
const gr_complex *in = (const gr_complex *) input_items[0];
gr_complex *out = (gr_complex *) output_items[0];
for(int i = 0; i < noutput_items; i++)
out[i] = gr_complex(real(in[i]),imag(in[i - d_delay]));
// Do <+signal processing+>
// Tell runtime system how many output items we produced.
return noutput_items;
}
The receiver architecture from Rice's book is shown below. In this architecture, the match-filter produces 2 samples per symbol. The oqpskIQDemap block processes the output samples (X(KTs), X(KTs + Ts/2), Y(KTs) and Y(KTs + Ts/2) into a constellation point (X(KTs) ,Y(KTs + Ts/2)), effectively reducing the sample rate to 1 sample per symbol.
oqpskIQDemap_impl::oqpskIQDemap_impl(int delay)
: gr::sync_decimator("oqpskIQDemap",
gr::io_signature::make(1, 1, sizeof(gr_complex)),
gr::io_signature::make(1, 1, sizeof(gr_complex)), 2),
d_delay(delay)
{}
/*
* Our virtual destructor.
*/
oqpskIQDemap_impl::~oqpskIQDemap_impl()
{
}
int
oqpskIQDemap_impl::work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
const gr_complex *in = (const gr_complex *) input_items[0];
gr_complex *out = (gr_complex *) output_items[0];
for(int i = 0; i < noutput_items; i+=2)
out[i] = gr_complex(real(in[i]),imag(in[i + 1]));
// Tell runtime system how many output items we produced.
return noutput_items;
}
The transmitted constellation (top) looks pretty okay. The Rx constellation (bottom), on the other hand, seems to have some points crossing the boundaries unexpectedly, given that the SNR is 25 dBs. I suspect the problem is with the way I introduce the delay in the two IQ map/demap blocks.
Please do let me know what you think.
Regards,
for
-loop, fori=0
, you're getting the -1. input item – that's not legal! In your previous call to work you already returnednoutput_items
, so you told GNU Radio that you don't need any of the input items you've gotten again. So, the upstream block might have already overwritten "-1th" input item with new output data. $\endgroup$return noutput_items
, you returnnoutput_items - 1
, so that you produced one less, but also didn't consume the last input item. $\endgroup$