LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Problems with reading ai data with a higt sample rate

Hallo all,

I've some problems with aquireing data with 10,000 Hz. I read the data from the buffer and save all data with fprintf to an file. Up to there everything is ok. I don't save all data, only these data I aquire in between two events. So the Aquasation is never stoped. After stopping saving the incomming data, I have to calculate with each sample. After aquireing 3 seconds I've 30,000 sample-packets and the calculating operations take to lang that the measurement aborts because "the data are not longer availeble".
Have you some suggestions to opt the right buffer size? Or maybe an Idea to solve the problem while using Threads. If I use Threads, I have to know how much CPU-Power the aquarisation-process needs, so that I can assure the thread a minimum CPU-space.

Greets frpm Germany,
chemph
0 Kudos
Message 1 of 7
(3,937 Views)
Can you please submit some code or pseudocode so that we can see the code operations you are describing?  This will help forum members to better diagnose a problem.  Thanks!
0 Kudos
Message 2 of 7
(3,931 Views)

Here are the code extracts:

The initialisation for the Measurement


int mess_init()
{
    DAQmxCreateTask("",&handle_mess_1);
    DAQmxCreateAIVoltageChan (handle_mess_1, "Dev1/ai0:1", "", DAQmx_Val_Cfg_Default, 0, 10, DAQmx_Val_Volts, NULL);
    DAQmxCfgSampClkTiming (handle_mess_1, "", 10000, DAQmx_Val_Rising, DAQmx_Val_ContSamps, 1);  

    CmtNewThreadPool (1, &POOL);
    CmtSetThreadPoolAttribute (POOL, ATTR_TP_THREAD_PRIORITY, THREAD_PRIORITY_NORMAL);
    return 0;
}

Start of aquireing


int messen_start()
{
    int32 numRead;
    float64 *data_konv=NULL;
    int i;
    int pos_set=0;
    char buff[200];


    if (file_selected == 0)
    {
        DAQmxStartTask(handle_mess_1);
       
        gRunning = 1;
       
        MESS_FILE = fopen ("C:\\aaa\\bbb\\ccc\\ddd\\eee.log", "w");
       
        if( (data=malloc(2*10000000*sizeof(float64)))==NULL )
        {
            MessagePopup("Error","Not enough memory");
        }
       
        while(gRunning)
        {

                DAQmxReadAnalogF64 (handle_mess_1, -1, 10.0, DAQmx_Val_GroupByScanNumber, data, 2*10000000, &numRead, NULL);

            if( numRead>0 )
            {

                for (i=0; i<numRead*2;i++)
                {
                                  
                    if (auswertung==1)
                    {
                        reltime=reltime + (0.0001);
                       
                        fprintf(MESS_FILE, "%f;%f;%f\n", reltime, data[i], data[i+1]);


                        if (WERT_2 > weg_maximum[0])
                            {
                                weg_maximum[0] = WERT_2;
                                weg_maximum[1] = WERT_1;
                                SetCtrlVal(handle_panel, PANEL_WM, weg_maximum[0]);
                            }         
                   
                        skip=0;
                    }

                    i++;
                }

                    PlotStripChart (handle_panel_graph, PANEL_PLOT_STRIPCHART, data, numRead*2, 0, 0, VAL_DOUBLE);
            }

            ProcessSystemEvents();
        }
    }
 
    return 0;
}

Calculation with aquired data
(The Polygon-Things are for calculation and Displaying an Integral of an channel over the time)



Message Edited by chemph on 03-21-2008 02:21 PM
0 Kudos
Message 3 of 7
(3,922 Views)

static int CVICALLBACK Thread_Read_NI (void *ctrlID)
{
   
    int stop=0;
    double weg_maximum[2];

    float *daten=NULL;
    int iz=0;

    double graph_x[5000];
    double graph_y_f[5000];
    double graph_y_s[5000];

    int count;
    int count_2=0;

    int skip=0;
    int paare=0;
    double m;
    double b;
    float x_ar[10];
    float y_ar[10];
    //double graph_x[2];
    double graph_y[2];
    int u=0;

    weg_maximum[0]=0;
    weg_maximum[1]=0;
   
    MESS_FILE = fopen ("C:\\aaa\\bbb\\ccc\\ddd\\eee.log", "r");

    while (stop == 0)
    {
        count_2 = 0;
   
        for(count=0; count<5000; count++)
        {
            ende = fgets(puffer, 100, MESS_FILE);
           
            if (ende == NULL)
            {
                stop = 1;
            }

0 Kudos
Message 4 of 7
(3,919 Views)
            if (stop == 0)
            {
                pch = strtok (puffer, ";");
                WERT_1 = atof(pch);
                graph_x[count]=WERT_1;
               
           
                pch = strtok(NULL, ";");
                WERT_2 = atof(pch);
                graph_y_s[count]=WERT_2;
           
                pch = strtok(NULL, ";");
                WERT_3 = atof(pch);
                graph_y_f[count]=WERT_3;

                        if (WERT_2 < weg_maximum[0])
                            skip=1;
                   
                        if (paare == 0 && skip!=1)
                        {
                            weg_1 = WERT_2;
                            kraft_1 = WERT_3;
                            paare++;
                        }
                            
                        else if (paare == 1 && skip!=1)
                        {
                            weg_2 = WERT_2;
                            kraft_2 = WERT_3;
                            paare++;
                        }

                        if (paare == 2 && skip!=1)
                        {
                            if (weg_2 - weg_1 != 0)
                            {
                                m = (kraft_2 - kraft_1) / (weg_2 - weg_1);
                            }
               
                            else
                            {
                                m = 0;
                            }
               
                  
                            b = kraft_1 - m * weg_1;

0 Kudos
Message 5 of 7
(3,918 Views)

                            if (m!=0)
                            {
                                E = E + (((m/2) * pow(weg_2,2) + b * weg_2) - ((m/2) * pow(weg_1,2) + b * weg_1));
                            }
               
                            else
                            {
                                E = E + ((weg_2 - weg_1) * kraft_1);
                            }
                          
                            SetCtrlVal(handle_panel, PANEL_E, E);
                           
                            x_ar[0]=weg_1;
                            x_ar[1]=weg_2;
                            x_ar[2]=weg_2;
                            x_ar[3]=weg_1;
                            x_ar[4]=weg_1;
                           
                            y_ar[0]=0;
                            y_ar[1]=0;
                            y_ar[2]=kraft_2;
                            y_ar[3]=kraft_1;
                            y_ar[4]=0;
                           
                            graph_x[0]=weg_1;
                            graph_x[1]=weg_2;
                           
                            graph_y[0]=kraft_1;
                            graph_y[1]=kraft_2;

                            PlotPolygon (handle_panel_graph, PANEL_PLOT_GRAPH, x_ar, y_ar, 10, VAL_FLOAT, VAL_FLOAT, VAL_BLUE, VAL_BLUE);
                            printf("%d\n", u);
                            u++;
                           
                            weg_1 = WERT_2;
                            kraft_1 = WERT_3;
                            paare=1;
                           
                        }
               
                count_2++;
            }
        }

        if (reltime != 0)
        {
            SetAxisRange (handle_panel_graph, PANEL_PLOT_GRAPH_2, VAL_MANUAL, 0.0, reltime, VAL_NO_CHANGE, 0.0, 1.0);   

            SetCtrlAttribute (handle_panel_graph, PANEL_PLOT_GRAPH_2, ATTR_ACTIVE_YAXIS, VAL_RIGHT_YAXIS);
            PlotXY (handle_panel_graph, PANEL_PLOT_GRAPH_2, graph_x, graph_y_f, count_2, VAL_DOUBLE, VAL_DOUBLE, VAL_THIN_LINE,
                            VAL_SOLID_SQUARE, VAL_SOLID, 1, VAL_GREEN);

            SetCtrlAttribute (handle_panel_graph, PANEL_PLOT_GRAPH_2, ATTR_ACTIVE_YAXIS, VAL_LEFT_YAXIS);
            PlotXY (handle_panel_graph, PANEL_PLOT_GRAPH_2, graph_x, graph_y_s, count_2, VAL_DOUBLE, VAL_DOUBLE, VAL_FAT_LINE,
                    VAL_ASTERISK, VAL_SOLID, 1, VAL_RED);

        }
       
    }
   
    fclose(MESS_FILE);
    return 0;
}


The source code is not very ordinary - the program is in "beta-status" 😉


Maybe I describe one more time what the program should do:
Aquireing data with a very high rate (10,000 Hz) an displaying some Values on User Interface (of course not every value, maybe one per second)
A function sets a marker (saving=1)
Now, data are stored in a semicolon-splitted text file
Another marker sets the saving-marker to 0
The saving stops
The analysis of stored data starts (with reading from file)

Greets,
chemph

0 Kudos
Message 6 of 7
(3,917 Views)
Dear chemph

Which hardware are you using? With most NI DAQ devices 10kHz isn't really a high sample rate.

You should start from the shipping example "ContAcq-IntClk.cws" (notice how the buffer size is a lot smaller than yours!); now, add
the functionality of writing the data to a file. As file I/O is expensive you should actually perform it in a separate thread and
pass the data to that through a thread safe queue; a very nice example of how to do that is "Overflow.cws". Finally, I would
recommend to write larger chunks of data at a time which improves performance.

Best regards

Philipp R.
0 Kudos
Message 7 of 7
(3,877 Views)