07-12-2011 05:07 AM
Hello everyone,
I'm writing an application in CVI that uses cDAQ-9188 chassis with several NI 9239 modules to record and analyze about 20 signals during 10-30 minute sessions. The recording requirement means that each sample of each channel at 5-10Khz sample rate should be archived and that's why I use task with continuous acquisition and DAQmx logging feature to stream it in TDMS file. The processing requirement is not to use all of sampled data for FFT analysis but to sample 1-2 second intervals (depending on wanted FFT resolution) in discrete points in time and present results to a person operating the device and the application (refreshing results each 1-2 second is acceptable). The process is following:
1. I know how many samples I need for data processing (variable SAMPLESPERCHANNEL) and have set up DAQmxRegisterEveryNSamplesEvent to call a function each time after that many samples per channel have been acquired into buffer which should happen each 1 second of data acquisition. Direct TDMS raw data streaming is happening in the mean time in DAQmx_Val_LogAndRead mode.
2. when the event triggers in the registered function I read data acquired with DAQmxReadAnalogF64 and call functions for data processing and data presentation. They are not in separate threads, I was going to reshape them after they are tested this way. Processing and presentation last for less than 1 second.
3. rinse and repeat until the task is stopped.
this is where the problems arise:
problem no.1: although event triggers on SAMPLESPERCHANNEL samples acquired, there is more than that in the buffer when I get to read it. I just need last SAMPLESPERCHANNEL samples and could discard the previous samples but LogAndRead mode doesn't allow for setting DAQmx_Read_RelativeTo attribute to DAQmx_Val_MostRecentSamp (to read at the end of all available samples), so I have to read the data at the sample number it stopped at at the last time this event function read the data and for me it's old data, I just need latest SAMPLESPERCHANNEL samples of each channel. Is there a way to do so without reading everything that there is in the buffer currently because if I read it all to keep up with the signals I run at the
problem no.2: acquisition runs normally and when I put the GUI window in the background it breaks down in error because there is less than SAMPLESPERCHANNEL samples in the buffer. It seems like the acquisition slows down or stops when the window is not active. Putting the task in the separate thread doesn't solve the issue. How to secure that acquisition works even if application GUI channel is minimized?
thank you,
Ivan
07-13-2011 02:16 PM
Hey Ivan,
What is the event that you're triggering on? Is it something like a rising signal on a digital line? If so, have you looked at configuring DAQmx for a reference trigger, wherein you can just get the SAMPLESPERCHANNEL of interest back from DAQmxRead?
Please clarify if I have a misunderstanding of your application. For example, do you need access to the data before the trigger condition has been met?
07-14-2011 03:51 AM
the triggering event is defined through RegisterEveryNSamplesEvent, meaning it triggers on every SAMPLESPERCHANNEL samples per channel acquired in the buffer, all signals are analog voltage signals and channels are analog input channels. I didn't configure reference trigger, I never worked with those so I'm not acquainted with how it could help me.
to clarify my application further: There is one task with N analog input channels with continuos acquisition that is being logged in TDMS file with DAQmxConfigureLogging set to DAQmx_Val_LogAndRead. every signal sample on every channel must be stored in the file and this takes care of it. Furthermore, I periodically need chunks of SAMPLESPERCHANNEL samples for each channel to do so some calculations and presentation with it, these chunks are mostly 1 second of signal sampling for FFT (to get 1 Hz FFT resolution), that's why I use RegisterEveryNSamplesEvent to register a function to be executed each time enough samples are in the buffer. Within that function I read from the buffer, do the processing and presentation and my guess is since it needs to end one execution to be able to trigger another, it triggers before end of former execution and upon next entry there are more samples than I need (number of extra samples varies and can't be determined beforehand) and I need to be able to read just SAMPLESPERCHANNEL last ones. Using streaming to TDMS disables reading from a point in the buffer other than the beginning. OK, then I'll just read all of them and use the last ones for acquisition. The problem with that is that the surplus of data comes from the signals acquired in the mean time and they count toward the next numbers of samples that will trigger the next execution of this function and if the acquisition slows down for any reason (and it does when I minimize the window and do something else while running this application) next time there will be no enough data left to be read.
I solved this few minutes ago (or for now it seems like I did) by reading all, put it into safe thread queue, and putting processing into callback function that is triggered when there is enough samples in the queue. Buffer reading function is unloaded of unnecessary burden which makes it faster and TSQ have a mechanism to wait for enough samples to be put into them. So far it seems like it works.
thank you,
sorry for my confusing explanations, english is not my first language