05-14-2009 05:07 AM
Hi,
I'm using a Pentium 4 with an NI4351 PCI DAQ, Win XP Pro OS, LabWindows/CVI 7.1, and an updated NI435x driver. DAQ readings are scanned from 8 channels into a scan buffer every second in an asynchronous timer thread that calls the NI435X_Check_And_Read() function. The readings are interleaved. After a few days of continous operation, the channel readings are somehow shifted to different scan buffer array indices. No function errors are returned.
For example, given a scan buffer variable declared as
double buf[1000];
The first 8 array elements (starting at buf[0]) should then always contain readings for respective channels as follows:
{ch1, ch2, ch3, ch4, ch5, ch6, ch7, ch8, ch1, ch2, ch3, ...}
However, after a few days, the contents of the array (starting at buf[0]) appear as follows:
{ch6, ch7, ch8, ch1, ch2, ch3, ch4, ch5, ch6, ch7, ch8, ...}
How do I prevent this from happening?
Thanks in advance,
John.
Solved! Go to Solution.
05-14-2009 06:51 AM
Hi John,
Good afternoon and I hope your well today.
Thanks for the post.
So if I understand you correctly, the acquired data for several channels appear to be shifting.. as in data from channel 1 appears say in the channel 2 array?
I have seen this before when using a cRIO to acquire data from 4 channels. At random periods, sometimes never, the signal on one channel would shift to another. The reason for this is because a sample of data is being lost.
Changes I had to make to reduce this was to improve the effiecny of my code, using a producer/consumer design pattern and also only place elements into a queue/FIFO in block of 4 (I had 4 channels). This way, to prevent one sample going missing.
What are your thoughts?
05-14-2009 02:02 PM
Hi James,
Thanks for the reply and I think you understand me correctly. One array (1000 elements in size) is used for all channels, whereby data for each channel is stored in a successive array element, with the ninth element containing data for channel 1 again, etc. If I check the contents of the array in debug mode, less than 400 elements of the array appear to be filled. The 'shift' does indeed appear to be random and sometimes everything could run fine for a week. It also appears that the measured analog values are still correct, only that after a 'shift', they are of course located in the wrong array element for correct array index retrieval.
I am unfamiliar with your 'producer/consumer design pattern'. My array is a thread-safe variable, although I only ever access it within the same asynchronous thread (I presume the same thread is used for each asynchronous timer call?). Are you referring to Thread-Safe Queues?
Many thanks,
John.
05-18-2009 03:31 AM
Hi John,
Thanks for the reply and I hope your well.
I was referring to programming such an application in LabVIEW.
Yes, the equivalent would be ThreadSafeQueues. The only suggestion I have is to improve the way the code works. It was the only way I resolved a issue like this when using a cRIO.And I found improving the code generally help too - not just aspects directly related to the acquisition. How does your code work at the moment/design pattern?
One last thing, Are you running on a multi-core machine? I wonder if the problem is worse or improved if you ask your application only to run on one core? (if possible).
08-18-2009 06:20 AM
Hi James,
Originally, an asynchronous thread read and processed data from the DAQ card every second. I think the problem may have arisen because this asynchronous thread had to perform too many operations within the allotted one-second timeframe. Any delay in the DAQ card response, might have introduced a backlog of successive asynchronous thread calls with associated DAQ card reads, and this might have been the problem.
The implementation of Thread-Safe Queues (TSQs) in another thread has solved the problem. By moving the task of reading the DAQ card from the asynchronous thread to the TSQ thread, attempted reads only occur when the DAQ card is ready. The DAQ card is now polled from a continous loop running in the TSQ thread and the paramaters are stored to a TSQ as quickly as the DAQ card can respond. The data in this TSQ are then read from and processed by the asynchronous thread every second, and stored in Thread-Safe Variables (TSVs) as before. The TSVs are then read by other threads to perform a number of functions and to store test results.
The PC has a single-core processor (P4), so this wasn't an issue. The system has been running non-stop for the last 4 weeks without a hitch. Thanks for your help James.
Regards,
John.