discuss-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Discuss-gnuradio] How to get a specific output of a block if a cond


From: Michael Dickens
Subject: Re: [Discuss-gnuradio] How to get a specific output of a block if a condition is true?
Date: Sun, 15 Sep 2019 17:47:31 -0500

Hi Tobias - Did you make any progress with your issue? I'm wondering if you've thought about using the GR-provided preamble access blocks: prepend a preamble + embedded length on Tx, then correlate against the preamble & if found then decode the length & output a tagged stream with that many items. Maybe these would work & you wouldn't have to figure out how to do this yourself? Feel free to email me directly to discuss more. - MLD

On Sat, Aug 31, 2019 at 4:05 AM Tobias Tepper via Discuss-gnuradio <address@hidden> wrote:
Hello GNU Radio community,

I'm trying to program a demodulation block for a variable pulse position modulation with c++ and have a problem where nobody know how to solve it.

At the moment it is a offline simulation and don't use USRP yet but this is my final goal.
I already created a block (type interpolator) that gets a byte and creates a 4-vppm symbol (containing 2 bits which mean there are 4 slots) that contains out of 4000 samples. Depending of the byte value only 10 samples are 1 at the beginning of the respective slot (i.e. (1100 0000 0000 0000 if byte is 0x00 or 0000 0000 1100 0000 if byte is 0x02). For adding the preamble sequence before the vppm symbol I use the "Stream Mux" block.

Now the part of my problem:
On the receiver side I created a preamble detection block (type general) which runs a cross-correlation and adds a tag to the stream if the preamble was found.
First I used the block "Tagged Stream Align" but I found out that the block only aligns the stream one time. So if i want to start a second transmission the stream is not aligned again and I don't get the expected output.
So my idea was to create a block (type general?) that search in the incoming stream for the tag "preamble_match". If a tag is found than copy 4000 samples beginning of the tag offset. It's possible that ninput_items[0] is < 4000 so I have to get the remaining items with the next call of the work-function. If I have 4000 items I want to start the demodulation and the block should only output one value. All the other time there should be no output of the block. I conected the block with a file sink and observed that the block is putting out data all the time. So how can I make sure that the block only put out a specific amout of data if a condition is true and if the condition is false no data is put out?

Please find below a stripped down version of the c++ code (and attached as txt file) of my general work function:

    new_mode_vppm_demodulator_impl::general_work (int noutput_items,
                       gr_vector_int &ninput_items,
                       gr_vector_const_void_star &input_items,
                       gr_vector_void_star &output_items)
    {
        const float *in = (const float *) input_items[0];
        unsigned char *out = (unsigned char *) output_items[0];

        // get the lowest count of items of the input and output buffer
        int ninput_noutput_min = std::min(noutput_items, ninput_items[0]);

        // create a vector of type tag_t which can hold the tag information of found tags
        std::vector<tag_t> tags;

        // store the distance between the first sample in the input buffer and the tag
        int nitems_read_tag_delta = 0;
        int tag_offset = 0;

        int ninput_items_tag_offset_delta = 0;

        if (d_tag_found)
        {
            std::cout << "Tag found before - get the remaining data" << std::endl;
            // there was one tag already in the previous call of the work-function
            // copy the remaining data into the array
            int tmp = d_read_counter;
            for (int i = 0; i < ninput_items[0]; i++)
            {
                /* check if the iteration variable "i" is equal to the max count of samples per symbol
                 * or if the counter variable "d_read_counter" is equal the max count of samples per symbol
                 */
                if ((i == d_samples_per_symbol) || (d_read_counter == d_samples_per_symbol))
                {
                    // reset the d_read_counter
                    d_read_counter = 0;
                    d_ready_for_correlation = true;

                    std::cout << "********* !!!READY FOR CORRELATION!!! *********" << std::endl;
                    // leave the for-loop because the necessary amount of data is available for correlation
                    break;
                }
                else{
                    // store the samples in the vector for correlation
                    d_vppm_symbol_samples[i + tmp] = in[i];
                    d_read_counter++;
                }


            } // end for-loop
            std::cout << "d_tag_found=true d_read_counter: " << d_read_counter << std::endl;

        }
        else // no tag found yet
        {
            // get all tags that are stored in the sample stream
            get_tags_in_range(tags, 0, nitems_read(0), nitems_read(0) + ninput_items[0], d_lengthtag);

            // check if tags were found in the bunch of samples in input buffer
            if (tags.size() > 0)
            {
                d_tag_found = true;
                // There was a tag in the sample stream!
                std::cout << "Tag found - move on!!" << std::endl;
                std::cout << "count of tags: " << tags.size() << std::endl; // this line prints the count of tags that were found

                // store the offset between the first sample of the input stream and the tag
                tag_offset = tags[0].offset;

                // the delta between ID of tag.offset and first item of input_buffer
                nitems_read_tag_delta = tag_offset - nitems_read(0);

                // get the count of samples that can be copied from the tag until the end of the current input buffer samples
                ninput_items_tag_offset_delta = ninput_items[0] - (nitems_read_tag_delta);

                // copy all items after the tag
                for (int i = 0; i < ninput_items_tag_offset_delta; i++)
                {
                    if (i == d_samples_per_symbol) //((i == d_samples_per_symbol) || (d_read_counter == d_samples_per_symbol))
                    {
                        //reset variables and exit the loop
                        d_read_counter = 0;
                        std::cout << "********* !!! first attempt READY FOR CORRELATION!!! *********" << std::endl;

                        d_ready_for_correlation = true;

                        // leave the for-loop
                        // next step will be to calculate the correlation
                        break;
                    }
                    else
                    {
                        d_vppm_symbol_samples[i] = in[i + tag_offset];
                        d_read_counter++;
                    }

                    if (i == (ninput_items_tag_offset_delta - 1))
                    {
                        std::cout << "Not enough samples yet. Continue with the next call of the work function!" << std::endl;
                    }
                }
                std::cout << "d_tag_found=false d_read_counter: " << d_read_counter << std::endl;
            } // loop for processing the found tags
        }


// skip code.....

// end skip code....
    }
_______________________________________________
Discuss-gnuradio mailing list
address@hidden
https://lists.gnu.org/mailman/listinfo/discuss-gnuradio


--
Michael Dickens, Mac OS X Programmer

Ettus Research Technical Support

Email: address@hidden

Web: http://www.ettus.com

reply via email to

[Prev in Thread] Current Thread [Next in Thread]