Acquired channels are discontinuous and not time-aligned

Applications, development tools, FPGA, C, WEB
Post Reply
mikepage
Posts: 23
Joined: Fri Oct 09, 2015 12:56 pm

Acquired channels are discontinuous and not time-aligned

Post by mikepage » Mon Feb 22, 2016 3:40 pm

Hi,

If I acquire channels with triggering, they both align to the trigger OK, but if I acquire with RP_TRIG_SRC_DISABLED, then the two channels are not even aligned to each other. Is this the expected behaviour? If so, it seems a bit odd to me. I expected the data not to be aligned to the waveform, but I was expecting sample N of Ch1 to be at the same time as sample N of Ch2.

I captured a short block of data that shows the issue (see https://dl.dropboxusercontent.com/u/11266852/RP.jpg). This has an external signal generator connected to both channels, so they see the same signal.

This picture also shows another problem. There is a clearly discontinuous section at the start of the buffer. What is the cause of this? As you can see, it is not a fixed number of samples. Again I would have expected that whatever I ask for, it would not be possible for the Red Pitaya to return me a block of discontinuous data without warning. If I enable triggering, the first sample is discontinuous, but everything else seems OK. In that case, because it's always 1 sample, I can just discard that one, but for the non-triggered case, I don't know how much data to discard.

Thanks for any useful input.
Mike.

Nils Roos
Posts: 1441
Joined: Sat Jun 07, 2014 12:49 pm
Location: Königswinter

Re: Acquired channels are discontinuous and not time-aligned

Post by Nils Roos » Sat Feb 27, 2016 4:21 pm

I assume you are doing your experiments with the librp-api, setting the RP_TRIG_SRC_DISABLED and then calling rp_AcqStart().

In that situation, both channels are continuously and synchronously filling their respective BRAM buffers. In particular, the buffers will continue being updated while you use one of the read functions. So it is quite possible - and, depending on the ratio of averaging rate to speed of reading, even rather likely - that you read buffer regions while they are currently receiving new data. In these instances, you will see discontinuities in the waveform as the reading crosses the new data / old data boundary (or vice-versa if you are recording faster than you can read).

Whether or not the samples from both channels will appear in sync in your setup depends on what function you use for reading. The absolute read functions (those with a pos parameter) should give you synced samples, unless you are recording fast enough for the buffer of the second channel to overrun before you get to reading it.
The rp_AcqGetOldest... and rp_AcqGetLatest... functions read samples relative to the write pointer, which will progress while you read one channel and hence give you another section of the waveform for the second channel.

mikepage
Posts: 23
Joined: Fri Oct 09, 2015 12:56 pm

Re: Acquired channels are discontinuous and not time-aligned

Post by mikepage » Wed Mar 02, 2016 1:09 pm

Hi Nils,

Thanks for your reply. I am using the API and setting the RP_TRIG_SRC_DISABLED then calling rp_AcqStart(). But before I call rp_AcqGetLatestDataV, I call rp_AcqStop() so I was not expecting the buffers to be in a dynamic state when I read them.

Below is the code I am using. It saves the data from the two channels into a CSV file so you can view it in a spreadsheet (just a double click if using Windows, Eclipse and Excel). Thanks for any further suggestions you can make.
Mike.

#define FCLK 125000000 //!< sample clock on RP board = 125MHz
#define US_PER_SEC 1000000
#define NUM_RATES 6 //!< number of decimation rates supported by RP board
#define BLK_SIZE 16384 //!< size of I/O buffers on RP board (number of samples)
#define TRIG_DELAY (BLK_SIZE / 2)

int Decimations[NUM_RATES] = {1, 8, 64, 1024, 8192, 65536};

int Example3(void)
{
int i;
int Timeout;
int Decimation;
int BuffTime;
uint32_t Size;
float *Buffer1;
float *Buffer2;
rp_acq_trig_state_t State = RP_TRIG_STATE_TRIGGERED;
FILE *Csv;
char Name[32];


// Initialisation of API resources
if (rp_Init () != RP_OK)
{
fprintf (stderr, "Red Pitaya API init failed!\n");
return EXIT_FAILURE;
}
rp_Reset();

// set acquisition parameters
rp_AcqReset();
rp_AcqSetSamplingRate(RP_SMP_1_953M);
rp_AcqSetAveraging(FALSE);
rp_AcqSetGain(RP_CH_1, RP_LOW);
rp_AcqSetGain(RP_CH_2, RP_LOW);
rp_AcqSetTriggerLevel(0.0f);
rp_AcqSetTriggerHyst(0.0f);
rp_AcqSetTriggerDelay(TRIG_DELAY);
rp_AcqSetTriggerSrc(RP_TRIG_SRC_DISABLED);

// calculate useful values
Decimation = Decimations[RP_SMP_1_953M];
BuffTime = (BLK_SIZE * Decimation) / (FCLK / US_PER_SEC);

// start acquisition (should be asynchronous to waveform) and wait long enough for buffer to fill
rp_AcqStart();
usleep(BuffTime);

// wait for trigger or for timeout after 100ms
Timeout = 100;
while(State != RP_TRIG_STATE_TRIGGERED && Timeout > 0)
{
rp_AcqGetTriggerState(&State);
usleep(1000);
Timeout--;
}

// wait after trigger to ensure post-trigger buffer is filled, then stop acquisition
usleep(BuffTime);
rp_AcqStop();

// check for timeout
if (Timeout > 0)
{
// read data and write out to CSV file
rp_AcqGetBufSize(&Size);
printf("Got data - %d samples\n", Size);
Buffer1 = (float*)malloc(Size * sizeof(float));
Buffer2 = (float*)malloc(Size * sizeof(float));
rp_AcqGetLatestDataV(RP_CH_1, &Size, Buffer1);
rp_AcqGetLatestDataV(RP_CH_2, &Size, Buffer2);

sprintf(Name, "acq.csv");
Csv = fopen(Name, "w");
for (i=0; i<Size; i++)
{
fprintf(Csv, "%f,%f,%f\n", ((float)(i * Decimation) / (float)(FCLK)), Buffer1, Buffer2);
}
fclose (Csv);
}
else
{
printf ("Timed Out\n");
}

/* Releasing resources */
free(Buffer1);
free(Buffer2);
rp_Release();

return 0;
}

Nils Roos
Posts: 1441
Joined: Sat Jun 07, 2014 12:49 pm
Location: Königswinter

Re: Acquired channels are discontinuous and not time-aligned

Post by Nils Roos » Wed Mar 02, 2016 5:10 pm

Yeah, well, here's the thing:

rp_AcqStop() doesn't actually do anything useful (as I've just learned by looking at the code).

It clears a bit whose only function is to start an internal state machine when set to one. Clearing the bit does not stop the writing / waiting for trigger.

User avatar
redpitaya
Site Admin
Posts: 912
Joined: Wed Mar 26, 2014 7:04 pm

Re: Acquired channels are discontinuous and not time-aligned

Post by redpitaya » Wed Mar 02, 2016 7:10 pm

edit Nils: I believe this wasn't meant to be posted here ... (see this post)

Hi,

Try to use this code

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "redpitaya/rp.h"

int main(int argc, char **argv){

        /* Print error, if rp_Init() function failed */
        if(rp_Init() != RP_OK){
                fprintf(stderr, "Rp api init failed!\n");
        }


        int selected_frequency=10000000;
        int min_periodes = 8;
        int signal_decimation;
        float wait;

        if      (selected_frequency >= 100000.0)            {  wait = 200;    }
        else if (selected_frequency >= 10000.0)             {  wait = 2000;   }
        else if (selected_frequency >= 1000.0)              {  wait = 20000;  }
        else if (selected_frequency >= 0)                   {  wait = 200000; }


        //Digital pin init.
        rp_DpinReset( );
        rp_DpinSetDirection(RP_DIO1_P, RP_OUT);
        rp_DpinSetState(RP_DIO1_P, RP_LOW );


        /*Generate LOOP BACK signal FOR TESTING*/
        rp_GenReset();
        rp_GenFreq(RP_CH_1, selected_frequency);
        rp_GenAmp(RP_CH_1, 1);
        rp_GenOffset(RP_CH_1, 0);
        rp_GenWaveform(RP_CH_1, RP_WAVEFORM_SINE);
        rp_GenOutEnable(RP_CH_1);
        usleep(100000);

        rp_AcqReset();

        if      (selected_frequency >= 100000.0)       	 {     rp_AcqSetDecimation(RP_DEC_1);     signal_decimation = 1;    }
        else if (selected_frequency >= 10000.0) 	 {     rp_AcqSetDecimation(RP_DEC_8);     signal_decimation = 8;    }
        else if (selected_frequency >= 1000.0) 	         {     rp_AcqSetDecimation(RP_DEC_64);    signal_decimation = 64;   }
        else if (selected_frequency >= 0)                {     rp_AcqSetDecimation(RP_DEC_1024);  signal_decimation = 1024; }

        uint32_t buff_size = ((min_periodes*125e6)/(selected_frequency*signal_decimation));
        float *buff_in1 = (float *)malloc(buff_size * sizeof(float));
        //float *buff_in2 = (float *)malloc(buff_size * sizeof(float));

        rp_AcqSetTriggerLevel(0);
        rp_AcqSetTriggerDelay(8192);
        rp_AcqStart();

        rp_AcqSetTriggerSrc(RP_TRIG_SRC_EXT_PE);
        rp_acq_trig_state_t state = RP_TRIG_STATE_TRIGGERED;


        while(1){
                rp_AcqGetTriggerState(&state);
                if(state == RP_TRIG_STATE_TRIGGERED){
                break;
                }
        rp_DpinSetState(RP_DIO1_P, RP_HIGH);
	usleep(1);
        rp_DpinSetState(RP_DIO1_P, RP_LOW);
        }

        usleep(wait);
        rp_AcqGetOldestDataV(RP_CH_1, &buff_size, buff_in1);
        //rp_AcqGetOldestDataV(RP_CH_2, &buff_size, buff_in2);

	int i;
        for(i = 0; i < buff_size; i++){
                printf("%f\n", buff_in1[i]);
        }

	//Releasing resources
        free(buff_in1);
        rp_Release();
        return 0;

}
Best

Nils Roos
Posts: 1441
Joined: Sat Jun 07, 2014 12:49 pm
Location: Königswinter

Re: Acquired channels are discontinuous and not time-aligned

Post by Nils Roos » Thu Mar 03, 2016 12:03 pm

I've been looking into it some more, and it seems that not even rp_AcqReset() will help you in your specific situation. The RP API in its current implementation does not offer a way to "un-arm" the trigger and hence stop the writing before a trigger arrives. Or, to put it more bluntly, the functions that are supposed to do this don't work correctly.

mikepage
Posts: 23
Joined: Fri Oct 09, 2015 12:56 pm

Re: Acquired channels are discontinuous and not time-aligned

Post by mikepage » Fri Mar 04, 2016 8:26 pm

Hi Nils,

I made this post already, but it seems to have disappeared from the thread, so I'll post it again.

Would it work if I called rp_AcqSetTriggerSrc(RP_TRIG_SRC_NOW) once I have started the acquisition? Would that cause a manual trigger event that frees up the state machine and stops the capture?

Mik.

Nils Roos
Posts: 1441
Joined: Sat Jun 07, 2014 12:49 pm
Location: Königswinter

Re: Acquired channels are discontinuous and not time-aligned

Post by Nils Roos » Sun Mar 06, 2016 3:30 am

Good call, if you triggered manually, recording would continue for the configured trigger-delay-time and then stop and reset the armed-status.

Post Reply
jadalnie klasyczne ekskluzywne meble wypoczynkowe do salonu ekskluzywne meble tapicerowane ekskluzywne meble do sypialni ekskluzywne meble włoskie

Who is online

Users browsing this forum: No registered users and 106 guests