Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Error -200992: events are generated too quickly

I'm trying to read 2 analog input channels at 1000 hz continuously using an NI-6255 PCI board.  I'm using the NI-DAQmx C library.  I create a task, add 2 AI voltage channels to it, set the sample clock timing to 1000 hz, register callbacks for the sample-complete and done events, and start the task.  After a few seconds the done-event callback is called with status -200992, "...events are generated too quickly for the driver to keep up..."  I'm using library function calls very much like the ANSI C example ContAcq-IntClk.c.  My callback function is trivial; it just calls DAQmxReadAnalogF64, does a little arithmetic, and copies the results to locations in shared memory.  My process is running with priority 31.  I'm using a 1.26 Ghz Pentium III, with Windows XP, service pack 2.

What could I be doing wrong?  Am I asking too much of the NI-DAQmx library?  I'm certainly not asking too much of the machine.

John Gourlay
Bauer Controls

0 Kudos
Message 1 of 12
(3,669 Views)
Hi John,

Thanks for posting on the forums!  Since you have looked at the ContAcq-IntClk.c example, is it safe to assume you are using the DAQmxRegisterEveryNSamplesEvent callback function?  You mentioned you are acquiring at 1000 Hz.  A couple things to check:
 
  • Number of samples between callback functions (This is set to 1000 in the example.  For your application I would set this to no less than 100).
  • Number of samples to read set in DAQmxReadAnalogF64 (This should match the number of samples between callback functions).
Rod T.
0 Kudos
Message 2 of 12
(3,653 Views)
Roderick,

I've attached excerpts of the C code that I'm working on.  You'll see that I'm not using
DAQmxRegisterEveryNSamplesEvent .  I'm using DAQmxRegisterSignalEvent to register a callback for DAQmx_Val_SampleCompleteEvent.  I want the callback to run each time the channels are read, at 1000 Hz.

When the callback runs, in DAQmxReadAnalogF64 I ask for only one sample, because that's all that I expect to be ready.

John

0 Kudos
Message 3 of 12
(3,626 Views)
Hi John,
From your code, it looks like you are attempting to make 1,000 callbacks a second.  This is too fast for the DAQmx driver.  I would recommend buffering your samples and making no more than 10 callbacks a second.  You could use the DAQmxRegisterEveryNSamplesEvent callback function and fire this callback every 100 samples.  Make sure to match the number of samples to read set in DAQmxReadAnalogF64 to be the same.    
Rod T.
0 Kudos
Message 4 of 12
(3,617 Views)
Roderick,

Yes, I'm trying to get 1000 callbacks per second.  Buffering the input data is not an option for me, because I'm working within an existing system, and another process is expecting to read the values from shared memory up to 1000 times per second. (Actually, I'd really like 2000 callbacks per second to avoid any glitches in the values the other process sees.)

If the callback mechanism is not capable of doing this, what do you suggest?  We have been reading analog inputs at 1000 Hz for years with older National Instruments boards and with boards from other manufacturers.

Is the problem with the callback mechanism, or with the DAQmxReadAnalogF64 function?  For example, can I expect to get 1000 or more counter-output callbacks per second?  Could I get 1000 sample-complete callbacks per second if I don't call DAQmxReadAnalogF64?  If I can understand the problem better, maybe I can find a way to work around it.

John

0 Kudos
Message 5 of 12
(3,611 Views)

Hi John,

How are your two processes synched up?  I still don’t understand why it would be a problem to buffer your acquisition and have it read from your second process at 1 kHz.  It seems that this threshold you’re reaching is not as simple as a limitation of the DAQmx driver.  I tried an example program using the same callback function on my machine, and I did not receive the error when acquiring at 1 kHz.  However, when increasing the sample rate to 5 kHz, I received the error after a few seconds.  At some point, the CPU cannot process the callback function and DAQmx Read fast enough to keep up with the acquisition (thus data is being overwritten).  You could try decreasing your sample rate if you absolutely need to fire the callback function at every sample acquired.  However, this is an inefficient use of the DAQmx driver.  I would strongly suggest to take advantage of the built in hardware buffering included in the DAQmx driver. 

Rod T.
0 Kudos
Message 6 of 12
(3,599 Views)
Roderick,

The two processes are not synchronized.  The other process just reads selected data from shared memory at a selected rate and writes something we call a recording file.  The data this recording process reads is not only from my NI-6255 process, but also simultaneously from a large number of other unrelated processes.  The recording process is oblivious to the source of the values it reads, and it would not be simple to make it know that certain shared memory locations are nominally being updated by the NI-6255 process, but that the correct values should be obtained from some buffer elsewhere.  Actually, that change wouldn't be enough, because many other pieces of the system woud also have to change to disregard the NI-6255 analog input locations.

So, redesigning that part of our system isn't really an option.  One way or another, I have to update the selected shared memory locations at 1000 Hz.  I'm really just asking if I can get reliable 1000 Hz or 2000 Hz callbacks of any kind from the NI-DAQmx C library.  What if I programmed a counter timer to go off at 1000 Hz?  Is that too fast, too?  Is the fastest reliable callback rate from NI-DAQmx really only 10 Hz?

John

0 Kudos
Message 7 of 12
(3,587 Views)
Hi John,
 
As I mentioned in my previous post, it is not a limitation of the DAQmx C Library. I was able to successfully get 1000 and even up to 2000 Hz callbacks without errors on my system. It is a limitation of your computer's ability to process the callback function and DAQmx Read fast enough to keep up with the acquisition rate. Please refer to the following Knowledge Base article. Part 1 of this article explains exactly what is going on here.
 
Another option would be to use hardware timed single point.  This sample mode allows you to acquire samples continuously using hardware timing without a buffer.  The advantage to this sample mode is it reduces the latency of your application.  The disadvantage is that if the software operations cannot keep up with the hardware timing, you will lose samples.  You can use the DAQmx real-time Report Missed Samples attribute/property, which returns an error if new samples are available before the read operation finishes converting samples from the previous iteration.
 
You can configure your sample mode using:
 
 DAQmx_Val_HWTimedSinglePoint.
 
You can get/set/reset the Report Missed Samples property using:
 
  DAQmxGetRealTimeReportMissedSamp
  DAQmxSetRealTimeReportMissedSamp
  DAQmxResetRealTimeReportMissedSamp
 
For more information about these functions please refer to the NI-DAQmx C Reference Help under NI-DAQmx C Functions » Timing » DAQmxCfgImplicitTiming.


Message Edited by RT4CY on 05-29-2008 06:03 PM
Rod T.
0 Kudos
Message 8 of 12
(3,561 Views)
Rod,

Do you have a sample C program that uses hardware timed single point sample mode?  It doesn't look like one shipped with DAQmx, and it seems like all of the on-line tutorials on the subject are written in terms of Lab View.

I'm having trouble understanding how to read the data.  DAQmxReadAnalogF64 just seems to time out.

I'm doing something like this:

         ni_rc = DAQmxCfgSampClkTiming (
                     ai_task_background,           // task reference
                     "",                           // clock source terminal (internal clock)
                     DEFAULT_COLLECTION_RATE,      // sampling rate in hz
                     (long) DAQmx_Val_Rising,      // rising edge of clock signal is active
                     (long) DAQmx_Val_HWTimedSinglePoint,// continuous sampling; no buffer
                     1ULL);                        // samples per channel to acquire

         ni_rc = DAQmxRegisterSignalEvent (
                     ai_task_background,                    // task reference
                     (long) DAQmx_Val_SampleCompleteEvent,  // call when sample is complete
                     0UL,                                   // call in a DAQmx thread
                     get_background_sample,                 // callback function
                     NULL);                                 // callback context data

As before, I have two input channels in the task.  In the get_background_sample callback I do this:

   ni_rc = DAQmxReadAnalogF64 (
               taskHandle,                // reference to task
               1L,                        // number of samples to read
               0.0,                       // timeout
               (ulong) DAQmx_Val_GroupByScanNumber,   // interleave data in buffer
               data,                      // buffer into which to place values
               2,                         // array size in number of values
               &read,                     // number of samples actually read
               NULL);                     // reserved

John Gourlay

0 Kudos
Message 9 of 12
(3,507 Views)

Hi John,

I’ve modified the Cont Acq-Int Clk.c example to use hardware timed single point.  I was able to run this program at 40 kHz before receiving errors.  Take a look at the attached code. 

 

Rod T.
0 Kudos
Message 10 of 12
(3,471 Views)