LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Mulithreading ComRd

Hello,

I am currently a student (undergrad) designing a datalogging system. The device used is the TI EZ430-RF2560. I am sending three axis accelerometer data via bluetooth to the usb(RS232) port. I am currently using a multithread technique (its my first time multithreading and I'm not sure I'm doing it correctly or at least efficiently). My main issue seems to be the CVI program is too slow. The baud is only 9600b/s so I'm fairly certain that CVI should be able to handle this transfer rate. The program is supposed to get the data from the comport, process it into a gravity value and then display it on the strip chart. Of the two threads I have now, one is dedicated to getting the data from the com port to the TSQ via the write pointer and the other thread reads the TSQ and processes the data accordingly. If anyone has any advice as to where I am going wrong or how I could improve the efficiency I would greatly appreciate it. For some reason NI forum won't let me upload any files, I apologize, If anyone is willing to post an email I would more than gladly send you my project files. Thanks in advance

 

~Mark

0 Kudos
Message 1 of 5
(3,470 Views)

Nevermind, it attached just fine to the original message, test.txt. Thanks

0 Kudos
Message 2 of 5
(3,468 Views)

Hello Mark,

I took a look at your program and have some question / advice for you.

 

First of all, I wonder why you choose to go the pointer way in using TSQs instead of simpler CmtWriteTSQData / CmtReadTSQData mechanism, which takes care by itself of flushing the queue. Using pointers you can have interlocking problems like in your AcquireTSQDataWithPtrsThreadFunction function:

static int CVICALLBACK AcquireTSQDataWithPtrsThreadFunction (void *unused)
{
    int numToWrite;
    int index;
    char *writePtr;

    while (running)
        {
        /* Use direct pointers to write data to the thread-safe queue. */
        if (CmtGetTSQWritePtr (tsqHandle, &writePtr, &numToWrite) >= 0)
            {
            /* Ensure we do not overflow the queue. */
            if (numToWrite > RAW_DATA_Q_SIZE)
                numToWrite = RAW_DATA_Q_SIZE;
            
                //FlushInQ(comport);
                //ProcessSystemEvents();
                ComRd (comport,  			//comport to be read
                       writePtr,  					//Result Buffer
                       RAW_DATA_Q_SIZE-1);	    //Number of bytes read
                CmtReleaseTSQWritePtr (tsqHandle, numToWrite);
            }
        }
    return 0;
}

In case numToWrite is equal to RAW_DATA_Q_SIZE, infact (the most possible case since the queue is created with that exact size and never grows), you are getting the pointer but you are not releasing it!

 

Secondly, you are setting no timeout in reading from the COM port, so you can have some (long) wait in case external device does not transmit data fast enough (default timeout time in RS232 library is 5 seconds). Use SetComTime to set a proper timeout for reading and add some error checking to ComRd to properly handle the timeout event.

 

Finally, while manipulating UIR objects (Set/GetCtrlVal and so on) the first parameter passed to the functions must be a panel handle (returned by LoadPanel in the main in your case). You get no errors now since you are basically in single-panel application, but this is only a case and you will get errors when adding panel to it. Either use 'panelHandle' static variable or use 'panel' callback variable, which holds the handle of the panel the control is on: in your case those variables reference to the same handle.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 3 of 5
(3,461 Views)

Roberto,

Thank you very much for your advice. There is definately some clean up needed in the program and I will absolutly change the panel parameter to more readily allow for a multi-panel program. I am confused by your comment concerning the AcquireTSQDataWithPtrsThreadFunction. You mention that I aquire the pointer but never release it. I was under the impression that my call to CmtReleaseTSQWritePtr() located after my call to ComRd() would release the ptr. Although I am going to change over to using the CmtWriteTSQData / CmtReadTSQData function I would still like to understand the pointer functions usage. Thanks in advance.

 

 

Mark

0 Kudos
Message 4 of 5
(3,438 Views)

You're right, I misinterpreted the parentheses (you see it in the wrong indentation in my code). The pointer is actually deallocated every time it's acquired.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 5 of 5
(3,429 Views)