Sampling Interval issues in streaming mode (-8ns)

Post your C and C++ discussions here
Post Reply
bouttier
Newbie
Posts: 1
Joined: Thu Jun 23, 2016 1:19 pm

Sampling Interval issues in streaming mode (-8ns)

Post by bouttier »

Hi !

It's me again, this topic is a "continuation" of my previous one : topic25081.html

So I eventually found a solution to my pulse width qualifier issues : I made up a trigger fonction by myself in C langage, based on the example provided by pico Tech. Thanks to this, I am able to fire and rearm continuous triggers in streaming mode.

But I still encounter some issue with the sampling Interval : Regardless of the Sample Interval I choose in the sampling Interval table of my picoscope 4227 (cf attached file) , the sampling rate will ALWAYS be 8ns less than announced.
For example :
I choose 512 ns sample interval => I'll have 504ns
I choose 992 ns = > I'll have 984ns ,
I choose 10016ns => I'll have 10008ns
and ... I think you got it. I searched a loooooonnnnng time to find that out because at first, I just tought it was not working at all (when your program says you got a 10078us period when the Picoscope 6 software says it lasts 9999,9us or 10000,1us, you understand you have some problem here).

I verified what I'm saying by using a 100Hz rectangular signal, which I observed with Picoscope 6 Software to ensure it was accurate (and it was) and I got the same results on my program IF and only IF I removed 8ns to (whatever) selected sample interval.

Here is my code if you want to take a look :

Code: Select all

void CollectStreamingImmediate(UNIT_MODEL * unit)
{
    int32_t i = 0, k = 0, h = 0, hPrevious = 0, moyenne = 0, moyennePrevious = 0, dureePeriode = 0;
    double er, erPrevious = 0;
    enum BOOL synchroHaute = FALSE, synchroBasse = FALSE, comparaison = FALSE;
    uint32_t sampleCount = 250000; /*  Make sure buffer large enough */
    int16_t * buffers[PS4000_MAX_CHANNEL_BUFFERS];
    int16_t * appBuffers[PS4000_MAX_CHANNEL_BUFFERS];
    uint32_t sampleInterval = 512;
    int32_t totalSamples;
    int16_t	triggerVoltage = mv_to_adc(1500,	unit->channelSettings[PS4000_CHANNEL_A].range); // ChannelInfo stores ADC counts
    BUFFER_INFO bufferInfo;

    ps4000SetChannel(unit->handle, (PS4000_CHANNEL) PS4000_CHANNEL_A, unit->channelSettings[PS4000_CHANNEL_A].enabled,
                     unit->channelSettings[PS4000_CHANNEL_A].DCcoupled, (PS4000_RANGE) unit->channelSettings[PS4000_CHANNEL_A].range);

    printf("Collect streaming...\nPress a key to start\n");

    _getch();

    buffers[0] = (int16_t*) calloc(sampleCount, sizeof(int16_t));

    ps4000SetDataBuffer(	unit->handle,
                            (PS4000_CHANNEL)PS4000_CHANNEL_A,
                            buffers[0],
                            sampleCount);

    // Application buffers to copy data into
    appBuffers[0] = (int16_t*)malloc(sampleCount * sizeof(int16_t));

    bufferInfo.unit = unit;
    bufferInfo.driverBuffers = buffers;
    bufferInfo.appBuffers = appBuffers;


    printf("Waiting for trigger...Press a key to abort\n");

    ps4000RunStreaming(unit->handle,
                            &sampleInterval,
                            PS4000_NS,
                            0,
                            0,
                            FALSE,	//FALSE,
                            1,
                            sampleCount);

    sampleInterval -= 8;

    printf("Streaming data at %d ns per sample ...Press a key to abort\n", sampleInterval);

    totalSamples = 0;


    while (!_kbhit())  /* Poll until data is received. Until then, GetStreamingLatestValues wont call the callback */
    {
        g_ready = FALSE;
        ps4000GetStreamingLatestValues(unit->handle, CallBackStreaming, &bufferInfo);

        if (g_ready && g_sampleCount > 0) /* can be ready and have no data, if autoStop has fired */
        {
            totalSamples += g_sampleCount;

            for (i = g_startIndex; i < (int32_t)(g_startIndex + g_sampleCount); i++)
            {
                if(comparaison == TRUE)       //Si le flag de comparaison est à 0 on attend que V(ech) > V(trig)
                {
                    if(appBuffers[0][i] > triggerVoltage)
                    {
                        if(synchroHaute == FALSE)
                        {
                            comparaison = FALSE;
                            synchroHaute = TRUE;
                            k=1;
                            h=0;
                            printf("synchro haute ok %d %d\n", k, h);
                        }
                        else
                        {
                            moyenne = (h*sampleInterval)/k;
                            dureePeriode = (h - hPrevious) * sampleInterval;
                            er = sqrt((((k - 1) * erPrevious) + (dureePeriode - moyennePrevious) * (dureePeriode - moyenne)) / k);
                            printf("Trigger %d front montant à %05d ns : %6d  adc Durée de la période : %d ns      Moyenne : %6d ns          Ecart relatif %f : \n",
                                   k, h*sampleInterval, appBuffers[0][i], (h-hPrevious)*sampleInterval,moyenne ,er);    //on relève le numéro de l'échantillon
                            comparaison = FALSE;    //on change le flag de comparaison                                                
                            hPrevious = h;
                            moyennePrevious=moyenne;
                            erPrevious = er;
                            k++;
                        }
                    }
                }
                else                       //Si le flag de comparaison est à 1, on attend que V(ech) < V(trig)
                {
                    if(appBuffers[0][i] < triggerVoltage)
                    {
                        if(synchroBasse == FALSE)
                        {
                            comparaison = TRUE;
                            synchroBasse = TRUE;
                            k=1;
                            h=0;
                            printf("synchro basse ok %d %d\n", k, h);
                        }
                        else
                        {
                            comparaison = TRUE;
                            printf("Trigger front descendant à %d us : %6d adc\n" , h*sampleInterval, appBuffers[0][i]);     //on relève (numéro échantillon*durée échantillon)
                        }
                    }
                }
                h++;
            }
        }
    }

    ps4000Stop(unit->handle);
    free(buffers[0]);
    free(appBuffers[0]);

    printf("\ndata collection aborted\n");

}
Thanks for you help !
Martin
Attachments
Sampling Interval table for picoscope 4000 series (refer to 4227)
Sampling Interval table for picoscope 4000 series (refer to 4227)

Hitesh

Re: Sampling Interval issues in streaming mode (-8ns)

Post by Hitesh »

Hi Martin,

Have you got some sample data for your waveform that we can take a look at?

With a 512 ns sampling interval and a signal of 100 Hz, you should find that one cycle of your waveform is approximately 19,531 samples. How many samples define one cycle at this sampling interval?

Which version of the ps4000.dll are you using? This can be queried using the ps4000GetUnitInfo() function.

Regards,

Post Reply